Ruby 内核#uu方法uuu不';在动态定义的方法中似乎无法正常工作

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

我一直在尝试在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.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也展示了这种行为: