如何在没有类的情况下调用类方法?

时间:2013-12-20 12:44:11

标签: ruby

我有一个必须完成类似事情的作业:

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

它没有说明在哪里帮助'虽然是定义的。我怎样才能像上面这样调用这个方法?

2 个答案:

答案 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 }