2017-09-26 45 views
0

我有一個爲子類化構建的類。如何創建一個在Ruby中執行以前給定的塊的方法?

class A 
    def initialize(name) 
    end 

    def some 
    # to define in subclass 
    end 
end 

# usage 
p A.new('foo').some 
#=> nil 

在我的用例中,我不想創建一個子類,因爲我只需要一個實例。因此,我會更改initialize方法以支持以下用法。

p A.new('foo') { 'YEAH' }.some 
#=> YEAH 

我怎麼能支持上面的用法?


BTW:我發現了一個Ruby 1.8.7以下項目的解決方案,但它們看起來彆扭給我。

class A 
    def singleton_class 
    class << self; self; end 
    end 

    def initialize(name, &block) 
    @name = name 
    self.singleton_class.send(:define_method, :some) { block.call } if block_given? 
    end 

    def some 
    # to define in subclass 
    end 
end 

回答

3

你可以存儲在一個實例變量的block argumentcall它以後:

class A 
    def initialize(name, &block) 
    @name = name 
    @block = block 
    end 

    def some 
    @block.call 
    end 
end 

A.new('foo') { 'YEAH' }.some 
#=> "YEAH" 

您也可以傳遞參數成塊:

class A 
    # ... 
    def some 
    @block.call(@name) 
    end 
end 

A.new('foo') { |s| s.upcase }.some 
#=> "FOO" 

或者instance_exec的塊接收方的背景:

class A 
    # ... 

    def some 
    instance_exec(&@block) 
    end 
end 

它允許您繞過封裝:

A.new('foo') { @name.upcase }.some 
#=> "FOO" 
相關問題