2017-02-04 57 views
0

所以说我有这个类:是否有将`def self.method_name`和`def method_name`缩短为一个方法?

class This 
    def a(that) 
    puts that 
    end 

    def self.b(that) 
    puts that 
    end 
end 

This.b("Hello!") # => passes 
This.a("Hello!") # => fails 

the_class = This.new() 
the_class.b("Hello!") # => fails 
the_class.a("Hello!") # => passes 

有没有一种方法,以缩短两者的这些方法成能够一个初始化的对象上调用,并能对已经初始化调用一个方法一个,还是我总是必须写这样的方法两次?

+0

你是什么意思未初始化的对象? –

+0

我的意思是我没有做'the_class = This.new()'。我不知道这个适当的名词,对不起! –

回答

6

您可以提取功能集成到一个模块,既extendinclude它。

module A 
    def a(that) 
    puts that 
    end 
end 

class This 
    include A # defines instance methods 
    extend A # defines class methods 
end 

This.a("foo") # => "foo" 
This.new.a("foo") # => "foo" 

虽然我认为这是比较常见的要么includeextend而不是两个。原因在于实例方法通常取决于实例状态,而类方法不取决于实例状态。如果你有一个实例This.new,想调用类的方法,你可以使用.classThis.new.class.a

+1

OP已经有效地询问单个方法是否可以将接收方作为类或类的实例。你还没有回答。在我看来,你的主要观点是可以通过创建两个具有相同名称的方法来模拟,一个是类方法,另一个是实例方法。在模块中使用'include'和'extend'只是一个方便的方法。 –

+0

谢谢!我非常感谢帮助! –

1

下面的代码位使用一些招数元编程自动拷贝过来的任何类方法来该类的实例。

module AutoAddMethods 

    def singleton_method_added(symbol) 
    define_method(symbol, method(symbol).to_proc) 
    end 

end 

class Foo 
    extend AutoAddMethods 
    @bar = 39 

    def initialize 
    @bar = 42 
    end 

    def test_one # Only added as an instance method. 
    puts "One #{@bar.inspect}" 
    end 

    def self.test_two # Added as both an instance and class method. 
    puts "Two #{@bar.inspect}" 
    end 

end 

i = Foo.new 
i.test_one 
i.test_two 

Foo.test_two 

这里是我的试运行输出:

One 42 
Two 39 
Two 39 

的test_two方法是从类及其实例都调用。它像在课堂上一样运行。

+0

这是一些方便的代码,我一定会在我的一些项目中使用它! –