【发布时间】:2016-10-29 19:52:35
【问题描述】:
使用已定义为特殊类的外部 API,其中几乎所有标准方法都未定义用于构建 xml。其中#method_missing负责根据对象调用的缺失方法名生成元素。
基本上在类体内有一些效果:
undef_method :send
现在我想通过名称以编程方式调用方法。我想我可以使用eval "obj.#{something}",但我真的不喜欢eval。
我在想必须有一些黑暗的技术来恢复方法#send 的未定义,所以我可以将其别名为#__send__ 并再次取消定义。这样我就可以愉快地按名称调用方法而无需 eval。例如obj.__send__(:something, params)。
所以我的问题是如何使用猴子补丁来恢复#send 方法。我找不到任何有这种效果的东西。甚至找不到任何人询问它。
更新:我最初的问题是没有问题的,因为无论如何有一个方法#__send__,我只知道#send。问题的另一部分是如何恢复未定义的方法。在@philomory asnwer 的帮助下,这就是我所拥有的:
[46] pry(#<CucuShift::DefaultWorld>)> class A
[46] pry(#<CucuShift::DefaultWorld>)* def gah
[46] pry(#<CucuShift::DefaultWorld>)* puts "gah"
[46] pry(#<CucuShift::DefaultWorld>)* end
[46] pry(#<CucuShift::DefaultWorld>)* end
=> :gah
[49] pry(#<CucuShift::DefaultWorld>)> class C < A
[49] pry(#<CucuShift::DefaultWorld>)* undef_method :gah
[49] pry(#<CucuShift::DefaultWorld>)* end
=> C
[50] pry(#<CucuShift::DefaultWorld>)> C.new.gah
NoMethodError: undefined method `gah' for #<C:0x000000070d7918>
[57] pry(#<CucuShift::DefaultWorld>)> class C
[57] pry(#<CucuShift::DefaultWorld>)* define_method :fff , A.instance_method(:gah)
[57] pry(#<CucuShift::DefaultWorld>)* end
=> :fff
[58] pry(#<CucuShift::DefaultWorld>)> C.new.fff
gah
【问题讨论】:
-
我很困惑 - 你为什么不能打电话 send ?
-
愚蠢的格式 - 我的意思是
__send__ -
@FrederickCheung,因为我从来不知道有
#__send__方法。我只知道#send。我想这解释了负面问题评级.. ruby 文档真的很糟糕,无论如何,谢谢 -
Ruby 有很棒的文档,您只需要实际查看即可。
-
@13aal,我猜你从未看过其他语言的文档,例如 java。与我使用的其他语言相比,Ruby 是我在文档中定义最不明确的语言。幸运的是,它的广泛流行使得博客和论坛中的大多数主题都得到了很好的覆盖。顺便说一句,看看我在网站上提出的问题数量,看起来我实际上很聪明,只有几个问题......只要你的断言是正确的,而且我在提问之前没有做研究。
标签: ruby metaprogramming monkeypatching