我有一个必须完成类似事情的作业:
module Foo
def self.bar
yield
end
def helper (number)
p number
end
end
Foo.bar do
helper 5
end
当然会出错,因为'帮助'没有在Object中定义。但在任务中,它直截了当地说Foo必须以这种方式使用:
Foo.bar do
helper 5
end
它没有说明在哪里帮助'虽然是定义的。我怎样才能像上面这样调用这个方法?
答案 0 :(得分:3)
编写如下代码:
module Foo
def self.bar
yield
end
end
def helper (number)
p number
end
Foo.bar do
helper 5
end
将方法helper
放在顶层。然后helper
将成为类Object
的私有实例方法。您正在将一个块传递给调用Foo.bar
,并阻止成为一个闭包,可以访问其周围环境。因此,helper 5
将隐式调用main
,顶级Object
类实例。现在代码可以工作了。
另一种方法是在顶级使用Module#include
方法将Foo
模块包含到类Object
中。
module Foo
def self.bar
yield
end
def helper (number)
p number
end
end
# this will make available `helper` method as an instance method to the Object class.
include Foo
Foo.bar do
helper 5
end
答案 1 :(得分:3)
您可以使用instance_eval
来评估对象上下文中的块。像这样:
class Foo
def bar(&block)
instance_eval(&block)
end
def helper(number)
p number
end
end
Foo.new.bar do
helper 5
end
你也可以让bar
成为一个类方法并调用:
class Foo
def self.bar(&block)
new.instance_eval(&block)
end
# ...
end
Foo.bar { helper 5 }
或者返回实例:
class Foo
def self.bar(&block)
new.tap { |foo| foo.instance_eval(&block) }
end
# ...
end
foo = Foo.bar { helper 5 }