2013-12-20 142 views
0

我有了要完成類似的東西一門功課:如何在沒有課程的情況下調用類方法?

module Foo 
    def self.bar 
    yield 
    end 

    def helper (number) 
    p number 
    end 
end 

Foo.bar do 
    helper 5 
end 

這當然給了一個錯誤,因爲「幫手」是不是在對象定義。但是,在任務,它說簡單是富,必須使用這種方式:

Foo.bar do 
    helper 5 
end 

這並不是說其中「幫手」的定義,雖然。我如何能夠像這樣調用這個方法?

回答

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 5main隱式調用,頂級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 } 
相關問題