Ruby 内核#uu方法uuu不';在动态定义的方法中似乎无法正常工作
我一直在尝试在Ruby 1.9中动态定义一些实例方法。以下是我一直在尝试的代码:Ruby 内核#uu方法uuu不';在动态定义的方法中似乎无法正常工作,ruby,Ruby,我一直在尝试在Ruby 1.9中动态定义一些实例方法。以下是我一直在尝试的代码: class Testing [:one, :two].each do |name| define_method(name) do puts __method__ end end end 以下是输出: ruby-1.9.2-p180 :008 > t = Testing.new => #<Testing:0x00000100961878> ruby-1
class Testing
[:one, :two].each do |name|
define_method(name) do
puts __method__
end
end
end
以下是输出:
ruby-1.9.2-p180 :008 > t = Testing.new
=> #<Testing:0x00000100961878>
ruby-1.9.2-p180 :009 > t.one
two
=> nil
ruby-1.9.2-p180 :010 > t.two
two
=> nil
ruby-1.9.2-p180 :011 >
ruby-1.9.2-p180:008>t=Testing.new
=> #
ruby-1.9.2-p180:009>t.one
二
=>零
ruby-1.9.2-p180:010>t.two
二
=>零
ruby-1.9.2-p180:011>
我希望结果分别是1
和2
。如果我在迭代之外调用每个方法的define_方法
,它将按预期工作。我在这里不明白什么
这是我在网上看到的许多在迭代中调用define_方法的例子之一
少了什么
另外:使用
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu。也许这已经开始向我解释这个问题了,但我还是不明白。你可以用这样的方法来代替定义方法
:
class Testing
[:one, :two].each do |name|
eval <<-EOM
def #{name}
puts __method__
end
EOM
end
end
t = Testing.new
t.one #=> "one"
t.two #=> "two"
类测试
[:一,:二]。每个人都有自己的名字|
评估“二”
发生这种情况的原因是define\u方法定义方法的方式与def稍有不同。它与创建匿名进程和lambda有关。我建议只使用方法名,因为您已经有了它。这应该避免在堆栈跟踪中搜索方法名,因此它的性能应该更好:
class Testing
[:one, :two].each do |name|
define_method name do
"This method's name is #{name}."
end
end
end
Testing.new.one
=> This method's name is one.
Testing.new.two
=> This method's name is two.
为了澄清,请注意以下两条语句返回的内容:
class Testing
define_method :one do
__method__
end
end
=> #<Proc:0x000001009ebfc8@(irb):54 (lambda)>
class Testing
def one
__method__
end
end
=> nil
类测试
定义方法:一次完成
__方法__
结束
结束
=> #
类测试
def一号
__方法__
结束
结束
=>零
另外,使用这两种格式也有性能上的差异。您可以使用基准测试验证def比define_方法快。这是一个很好的发现。在我测试的所有红宝石中,只有MRI 1.9.2能证明这一点
Ryan Davis(引用了这个问题)。我尝试了你的代码,在这里它工作得非常完美,t.one
打印“一”。这可能是我版本ruby中的一个bug吗*编辑:记录在案,这在Ruby 1.8Behavior中确实起作用,这里确认(1.9.2),t.one打印“2”。闻起来像个bug。肯定有比这更干净的方法吗?你的答案是一个很好的“字里行间的阅读,找出真正的意图是什么”答案,但它看起来仍然像是Kernel\uuuuuu方法在MRI 1.9.2中有一个bug。是的,很可能是,但我可以认为这是合理的,因为实现方法的方式不同。匿名proc/lambda没有方法名,至少可以解释一些奇怪的行为。JRuby 1.7也展示了这种行为: