是否有一种简单的方法可以在模块中扩展标准库类(如String
)的功能而不会影响其外部的任何内容?示例(不起作用):
module Foo
class String
def hello
"hello #{self}!"
end
end
class Bar
def greet name
name.hello
end
end
end
结果我正在寻找:
Foo::Bar.new.greet 'Tom' #=> hello Tom!
'Tom'.hello #=> NoMethodError
我知道创建具有所需功能的MyString < String
等解决方案,但每次我想在模块中使用字符串时,我宁愿不调用MyString.new('foo')
。
我意识到这可能不是一种好习惯,我只是想扩大对语言的理解。
答案 0 :(得分:3)
您要找的是Refinement:
改进旨在减少猴子修补的影响 猴子修补课程的其他用户。 优化提供了一种方法 在本地扩展一个类 。
module Foo
refine String do
def hello
"hello #{self}!"
end
end
end
puts 'Tom'.hello
#=> undefined method `hello' for "Tom":String
using Foo
puts 'Tom'.hello
#=> hello Tom!
在Bar
类中使用细化:
# Without refinement
class Bar
def greet(name)
name.hello
end
end
puts Bar.new.greet('Tom')
#=> undefined method `hello' for "Tom":String
# With refinement
class Bar
using Foo
def greet(name)
name.hello
end
end
puts Bar.new.greet('Tom')
#=> hello Tom!
有关范围界定,方法查找和内容的完整信息,请查看我提供的文档链接:)
P.S。请注意,Rubinius开发人员在哲学上反对精炼,因此永远不会实施它们(c)JörgWMittag。
答案 1 :(得分:0)
写一个同名的类,然后使用require_relative
(或类似方法)将其包括在内。
class Date
def itis
puts "It is " + self.to_s
end
示例:
[1] pry(main)> require_relative 'date.rb'
=> true
[2] pry(main)> require 'date'
=> true
[3] pry(main)> Date.new(2018, 10, 9).itis
It is 2018-10-09
=> nil