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

时间:2013-03-05 09:45:24

标签: ruby ruby-2.0 refinements

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

- 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

孤立并不差。

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

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

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

- 通过eval执行优化。 refine不是关键字。呸。 (好吧,“呸!”再次。)

所以,我的问题是:我错过了什么,或者每个人都认为新推出的功能没有优势?

1 个答案:

答案 0 :(得分: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

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

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

# here I need it
"".my_locally_needed_func

注意:我删除了对using的调用,因为您还没有使用优化,所以没有任何意义。

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