2

尽管进行了多次尝试,但我无法使用 define_method() 创建方法并提供方法。

如果我了解可以在此处找到的 Module 类的文档http://www.ruby-doc.org/core-1.9.3/Module.html我应该能够执行以下任一操作:

定义方法(符号,方法)→ 新方法

定义方法(符号){块}→过程

我可以使用 define_method(symbol) { block } 但是我收到的似乎是一种方法(不是我链接到的文档中概述的过程):

class M
  define_method(:hello) { puts "Hello World!"}
end

M.new.hello

我在这里担心的两个问题是: 1. 执行上述操作我似乎没有收到 proc,尽管文档清楚地说明这是我会得到的。2.我不知道如何为“define_method(symbol, method) → new_method”提供方法,我尝试谷歌搜索无济于事,不知道如何使用这种形式的define_method。

如果有人可以请对此有所了解,将不胜感激!:) 非常感谢!

4

2 回答 2

0

define_method确实返回 aProc或 aMethod取决于使用情况。

在第一种情况下,Proc返回 a:

class Test
  x = define_method :test_method { nil }
  puts x.inspect
end


Test.new.test_method

在控制台输出上运行上述内容:

#<Proc:0x007fe12104e228@test.rb:3 (lambda)>

第二种情况返回一个UnboundMethod,它是 的类型Method

class Test2 < Test
  y = define_method :test_method2, Test.instance_method(:test_method)
  puts y.inspect
end

Test2.new.test_method2

以上输出

#<UnboundMethod: Test#test_method>

这是一个非常人为的例子,在这种情况下定义一个传递给的方法define_method并不是很有用,我也想不出它会是什么情况。

于 2012-11-19T20:35:32.483 回答
0

您可以通过在类中定义一个方法来做到这一点,如下所示:

class TestClass
  def a_method
  end
  # Store the method in a class variable; define_method is a Module 
  # method and needs to be called from within this context
  @@x = define_method(:another_method, TestClass.new.method(:a_method))
  def x
    @@x
  end

  # And to get a block...
  @@y = define_method(:yet_another_method) {}
  def y
    @@y
  end
end

调用该x方法你会得到这样的东西:

TestClass.new.x
#<Method: TestClass#a_method>

而调用该y方法你会得到这样的东西:

TestClass.new.y
#<Proc:0x00000000aebc30@(irb):75 (lambda)>

这里棘手的部分是你需要一个来自你正在执行的同一个类(或超类)的对象的方法define_method,否则它不起作用。例如,如果您替换该@@x行:

...
@@x = define_method(:another_method, String.new.method(:gsub))
...

由于不是 的子类,TypeError因此获得以下内容:TestClassString

TypeError: bind argument must be a subclass of String

请注意,这起作用:

...
@@x = define_method(:another_method, Object.new.method(:object_id))
...

输出与此类似:

TestClass.new.x
#<Method: Object(Kernel)#object_id>

我假设需要来自同一类层次结构的方法的原因是强制执行 OO 代码封装和隐私(否则您可以通过传递另一个类的方法来访问私有方法和变量)。

于 2013-02-22T12:57:43.853 回答