Ruby 安全地扩展标准库类的功能

Ruby 安全地扩展标准库类的功能,ruby,Ruby,有没有一种简单的方法可以在模块内部扩展标准库类(如String)的功能,而不影响模块外部的任何内容?示例(不起作用): 我想要的结果是: Foo::Bar.new.greet 'Tom' #=> hello Tom! 'Tom'.hello #=> NoMethodError 我知道一些解决方案,如使用所需的功能创建MyString

有没有一种简单的方法可以在模块内部扩展标准库类(如
String
)的功能,而不影响模块外部的任何内容?示例(不起作用):

我想要的结果是:

Foo::Bar.new.greet 'Tom' #=> hello Tom!
'Tom'.hello #=> NoMethodError
我知道一些解决方案,如使用所需的功能创建
MyString
,但我不希望每次在模块中使用字符串时都调用
MyString.new('foo')


我意识到这可能不是一个好的做法,我只是想扩大我对这门语言的理解。

你想要的是:

改进的目的是减少猴子修补对环境的影响 monkey patched类的其他用户优化提供了一种 在本地扩展类

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!
有关作用域、方法查找和内容查找文档的完整信息,请参见我提供的链接:)


注意,Rubinius开发人员在哲学上反对细化,因此永远不会实现细化(c)Jörg W Mittag。

编写一个同名类,然后使用
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

是的,我很确定他想要改进,这不是一个误解。也许,提供一个小代码片段,说明如何在这里使用改进?是的,当然是一个打字错误。对
String
类进行细化的代码片段将是最受欢迎的。值得一提的是,Rubinius开发人员在哲学上反对细化,因此永远不会实现它们。JRuby-OTOH拥有它们。@PiotrKruczek:精炼仍处于不断变化的状态。它们曾经非常广泛,在首次试用时,然后在发布时受到了很大限制(仅允许在脚本范围内使用,
using
仅被定义为
main
上的单例方法),现在它们再次被扩展,也可以在模块范围内使用(
module#using
)。
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