Ruby send vs __send__
我理解
1 2 3 4 5 6 7 8 9 | class Foo def bar? true end end foo = Foo.new foo.send(:bar?) foo.__send__(:bar?) |
有人对此有任何想法吗?
某些类(例如,标准库的套接字类)定义了自己的
现在剩下的问题是,为什么会有
如果您真的需要
看:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | class Foo def bar? true end def send(*args) false end end foo = Foo.new foo.send(:bar?) # => false foo.__send__(:bar?) # => true |
如果覆盖
warning: redefining `__send__' may
cause serious problems
在某些情况下,覆盖
至于为什么
除了其他人已经告诉您的内容,以及可以归结为
1 2 3 4 | A, B, C = Module.new, Module.new, Module.new B.include A #=> error -- private method B.send :include, A #=> bypasses the method's privacy C.public_send :include, A #=> does not bypass privacy |
更新:由于Ruby 2.1,
send,
warning: redefining
__send__ may cause serious problems
这是因为要避免冲突,尤其是在gem或库中,当要使用该上下文的上下文未知时,请始终使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | class Foo def __send__(*args, &block) "__send__" end def send(*args) "send" end def bar "bar" end private def private_bar "private_bar" end end Foo.new.bar #=>"bar" Foo.new.private_bar #=> NoMethodError(private method 'private_bar' called for #Foo) Foo.new.send(:bar) #=>"send" Foo.new.__send__(:bar) #=>"__send__" Foo.new.public_send(:bar) #=>"bar" Foo.new.send(:private_bar) #=>"send" Foo.new.__send__(:private_bar) #=>"__send__" Foo.new.public_send(:private_bar) #=> NoMethodError(private method 'private_bar' called for #Foo) |
最后,尝试使用public_send避免直接调用私有方法,而不要使用__send__或send。