2015-10-05 28 views
0

我有一类Foo:动态添加语句的方法

class Foo 

    def a 
     "something" if true 
    end 

end 

我想要一个add_statement方法,将新语句添加到方法,保持旧的实现。可能吗?

我想要做这样的事情:

foo = Foo.new 
foo.extend_method(:a, &block) 

所以现在我a方法的来源应该是这样的:

def a 
     "something" if true 
     &block 
    end 

其中&block是我作为参数传入的代码extend_method

+0

'define_method(:add_statement,instance_method(:a))' –

+1

看来你想创建一个新方法,它包含'a'中的语句以及其他语句。你是这个意思吗?请编辑并添加示例。 (标题中的“动态”拼写错误。) –

+0

我编辑它,检查它 – Alan

回答

1

您想使用alias_method_chainModule#prepend

网上有很多关于它们的教程/文档,例如“AVOIDING ALIAS_METHOD_CHAIN IN RUBY”或“Module.prepend: a super story”。

对于您的具体示例(当您想在课堂外扩展功能时),您必须使用alias_method_chain,将其添加到新模块中,并使用Foo.send包含在原始类中。

您可以在“When to use alias_method_chain”中找到更多详细信息和示例。

+0

'Module#prepend'是我用于类似情况的一个很好的解决方案,我需要改变'require'和'require_relative'的行为。此外,不要“这个或这个”,提供可用的锚文本,让人们能够快速,轻松地看到链接将采取他们的位置,而不必实际点击它看。 –

0

下面是一个面向方面的例子:

require 'aspector' 

class Foo 
    def a 
    puts "in Foo.a" 
    end 
end 

aspect = Aspector do 
    before :a do 
    puts 'this should print first' 
    end 

    after :a do |result_of_a| 
    puts 'this should print last' 
    end 
end 

puts "\n\nplain instance" 
foo = Foo.new 
foo.a 

puts "\n\napply to an instance" 
aspect.apply(foo) 
foo.a 

puts "\n\napply to all instances of Foo" 
aspect.apply(Foo) 
Foo.new.a 

你需要 '宝石安装aspector'。