2010-08-05 177 views
1
class Foo 
    def self.bar 
    puts "foobar" 
    end 

    def bar 
    self.class.bar 
    end 
end 

我想避免需要定義實例方法bar。有沒有辦法自動使類方法作爲實例方法可訪問?也許有一些method_missing?魔法?訪問類實例方法如實例方法

回答

1

試着這麼做:

class Foo 

    def self.bar 
    puts "foobar" 
    end 

    def respond_to? name 
    super or self.class.respond_to? name 
    end 

    def method_missing name, *args, &block 
    if self.class.respond_to? name 
     self.class.send name, *args, &block 
    else 
     super 
    end 
    end 

end 

你也可以做到這一點(簡版):

module ChainsToClass 
    def respond_to? name 
    super or self.class.respond_to? name 
    end 
    def method_missing name, *args, &block 
    if self.class.respond_to? name 
     self.class.send name, *args, &block 
    else 
     super 
    end 
    end 
end 

class Foo 
    def self.bar 
    puts "foobar" 
    end 
end 

Foo.send :include, ChainsToClass 
+0

謝謝!儘管Ruby不會讓你調用'class',但你必須使用'self.class'。 – Karl 2010-08-05 22:41:38

+0

編輯,謝謝。 – yfeldblum 2010-08-05 23:18:59

1

最簡單的方法是定義在一個子模塊的方法和延伸,它包括進入等級:

class Foo 

    module FooMethods 
    def bar 
     puts "foobar" 
    end 
    end 

    # Add methods from module FooMethods as class methods to class Foo 
    extend FooMethods 

    # Add methods from module FooMethods as instance methods to class Foo 
    include FooMethods 
end 
+0

好主意!我有一些代碼需要類作爲環境,但我有這種感覺,在我的情況下,使用這種方法不能正確處理事情。 – Karl 2010-08-05 22:42:50

+1

在該方法中,'self'可以包含類或實例對象,具體取決於您稱爲類方法還是實例方法。如果你需要找出這個類,你可以添加'def klass; self.is_a?(Class)? self:self.class;結束「到模塊並以'klass'而不是'self.class'的方式訪問類。 – Zargony 2010-08-06 00:03:17