尽管尝试了很多次,但我无法使用define_method()创建方法并提供方法。
如果我理解可在此处找到的Module类的文档http://www.ruby-doc.org/core-1.9.3/Module.html,我应该可以执行以下任一操作:
define_method(symbol,method)→new_method
define_method(symbol){block}→proc
我可以使用define_method(symbol){block}然而我收到的似乎是一个方法(不是我链接到的文档中概述的proc):
class M
define_method(:hello) { puts "Hello World!"}
end
M.new.hello
我的两个问题是: 1.做到这一点我似乎没有收到过程,尽管医生明确说明我会得到的。 2.我不知道如何为“define_method(symbol,method)→new_method”提供方法,我试着谷歌搜索无效,不知道如何使用这种形式的define_method。
如果有人能够对此有所了解,我将不胜感激! :)非常感谢!
答案 0 :(得分:0)
define_method
确实会返回Proc
或Method
,具体取决于使用情况。
在第一种情况下,返回Proc
:
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
的方法在这种情况下并没有用,我也不能想到它会出现的情况。
答案 1 :(得分: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
不是TestClass
的子类,因此获得了以下String
:
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代码封装和隐私(否则您可以通过从另一个类传递方法来访问私有方法和变量)。