Ruby 2.0中的改进完全没用吗?

Ale*_*kin -2 ruby ruby-2.0 refinements

Ruby 2.0中引入了所谓的改进.我和他们一起玩,现在我完全被哄骗了:

- 主要宣称的优势refine是它们不是全球范围的.呸.

module MyModule
  class ::String
    def my_locally_needed_func
      # do smth 
    end
  end
end

# here I need it
require 'mymodule'
"".my_locally_needed_func
Run Code Online (Sandbox Code Playgroud)

孤立不是更糟.

- 优化不支持类方法.呸.当然他们是通过黑客攻击(记住,一切都是对象):

module VoidRefinements
  refine String do
    def self.singleton_method_for_string_class
      puts "inside singleton_method_for_string_class"
    end 
  end 
end

module VoidRefinementsOK
  refine Class do
    def singleton_method_for_string_class
      err_msg = "NoMethodError: undefined method ‘#{__method__}’ for ‘#{self}:#{self.class}’"
      raise NoMethodError.new(err_msg) unless String == self
      puts "inside proper singleton_method_for_string_class"
    end 
  end 
end

using VoidRefinements
String.singleton_method_for_string_class rescue puts $!

using VoidRefinementsOK
String.singleton_method_for_string_class rescue puts $!

# undefined method `singleton_method_for_string_class' for String:Class
# inside proper singleton_method_for_string_class
Run Code Online (Sandbox Code Playgroud)

后者甚至没有导致性能损失,因为没有人会Fixnum.substr故意打电话.

- 通过执行改进eval.refine不是关键字.呸.(好吧,"呸!"再次.)

所以,我的问题是:我是否缺少smth或者每个人都认为新推出的功能没有优势?

Jör*_*tag 21

你完全忽略了Refinements不是全局范围的事实,但这就是它们被引入的原因.当然,如果你只是忽略某些东西存在的原因,那么你显然不会看到它的任何价值.

但是,看看行动中的隔离.以下是修改为使用优化的示例:

module MyModule
  refine String do
    def my_locally_needed_func
      # do smth 
    end
  end
end

module MyOtherModule
  # The monkeypatch is invisible:
  "".my_locally_needed_func
  # NoMethodError: undefined method `my_locally_needed_func' for "":String

  # I first have to use the Refinement:
  using MyModule
  "".my_locally_needed_func
end

# The monkeypatch is scoped. Even though we were able to use 
# it in MyOtherModule, we still cannot use it at the top-level:
"".my_locally_needed_func
# NoMethodError: undefined method `my_locally_needed_func' for "":String

# We have to call `using` again, for the top-level:
using MyModule
"".my_locally_needed_func
Run Code Online (Sandbox Code Playgroud)

以下是您进行比较的示例:

module MyModule
  class ::String
    def my_locally_needed_func
      # do smth 
    end
  end
end

# here I need it
"".my_locally_needed_func
Run Code Online (Sandbox Code Playgroud)

注意:我删除了using没有意义的调用,因为你还没有使用Refinements.

在您的情况下,monkeypatch是全局可用的,因为您只是修改了String类.这个功能被称为"开放类",正是Refinements所要避免的.

  • @mudasobwa不,它没有做同样的事情.假设您的项目中有两个文件,'foo.rb'和'bar.rb'.如果'foo.rb'需要MyModule,'bar.rb'将看到My​​Module安装的更改,即使它不需要MyModule本身.如果'foo.rb'使用MyRefinement,'bar.rb'*将不会*看到这些更改,除非它也使用MyRefinement. (3认同)