2017-06-05 38 views
-2

可以使用模塊將方法添加到類中。例如,用於功能的Ruby模塊

class Test 
    include Singleton 
end 

是否可以使用相同的方法?例如,

class Test 
    include Singleton 

    def test 
    include Instructions_to_add_to_the_method 
    puts 'done' 
    end 
end 

其中:

module Instructions_to_add_to_the_method 
    puts 'hi !' 
end 

當調用Test.instance.test,我想:

hi ! 
done 

我不想調用另一個方法,因爲它會給我帶的範圍問題我的變數。

+0

不,這不是紅寶石的工作原理。模塊不是宏。如果這就是你想要實現的目標,你可以使用'Module#prepend'或'Module#include'與'super'結合使用? –

回答

1

有可能增加方法到使用模塊的類。例如,

class Test 
    include Singleton 
end 

號這並不 「添加方法一類」。 include只是使Singleton的超類Test。而已。沒有什麼是「添加到課堂」的。這只是繼承。

是否可以使用相同的方法?例如,

class Test 
    include Singleton 

    def test 
    include Instructions_to_add_to_the_method 
    puts 'done' 
    end 
end 

沒有方法Test#include,因此這將只是一個raiseNoMethodError

當調用Test.instance.test,我想:

hi ! 
done 

這就是繼承是:

class Test 
    include Singleton 

    def test 
    super 
    puts 'done' 
    end 
end 

module Instructions_to_add_to_the_method 
    def test 
    puts 'hi' 
    end 
end 

class Test 
    include Instructions_to_add_to_the_method 
end 

Test.instance.test 
# hi 
# done 

注意在Ruby中使用繼承的方式是有點落後。如果你真的需要這樣的東西,你應該使用Beta這樣的語言,這是繼承如何自然發揮作用。

更好的解決方案會是這樣的Template Method Software Design Pattern它在紅寶石可以像yield簡單荷蘭國際集團以一個塊的內容:

class Test 
    include Singleton 

    def test 
    yield 
    puts 'done' 
    end 
end 

Test.instance.test { puts 'hi' } 
# hi 
# done 

或採取Proc作爲參數:

class Test 
    include Singleton 

    def test(prc) 
    prc.() 
    puts 'done' 
    end 
end 

Test.instance.test(-> { puts 'hi' }) 
# hi 
# done 

或通過調用掛鉤方法:

class Test 
    include Singleton 

    def test 
    extension_hook 
    puts 'done' 
    end 

    def extension_hook; end 
end 

class HookedTest < Test 
    def extension_hook 
    puts 'hi' 
    end 
end 

HookedTest.instance.test 
# hi 
# done 

我不想調用另一種方法,因爲它會給我變量的範圍帶來問題。

代碼中沒有變量,所以不可能有任何「問題」與他們。

+0

非常感謝答案,看來我對Ruby類繼承的理解有點偏離 –

1

這可能是一個可怕的想法。在運行時弄亂你的類會使問題難以調試(我在那裏調用哪種版本的方法?),而且你的代碼很難遵循(哦,對,我還不能調用該方法,因爲它尚未定義,我需要首先調用這個方法)。

鑑於你在變量範圍界定問題的結尾所說的話,我幾乎可以肯定,這不會解決你實際存在的問題,而且我建議實際發佈你的實際問題。

這就是說,你問的問題可以通過使用includedextended鉤來回答這,勿庸置疑,火當一個模塊被包括和擴展:


module FooModule 
    def self.included(base) 
    puts 'FooModule included' 
    end 

    def self.extended(base) 
    puts 'FooModule extended' 
    end 
  
    def new_method 
    puts 'new method called' 
    end 
end 

class Extender 
    def test_extend 
    self.extend FooModule 
    puts 'done' 
    end 
end 

class Includer 
    def test_include 
    self.class.include FooModule 
    puts 'done' 
    end 
end 

t1 = Extender.new 
t2 = Extender.new 
t1.test_extend # Prints out "FooModule extended" followed by "done" 
t1.new_method # Prints out "new method called" 
t2.new_method rescue puts 'error' # Prints out "error" - extend only modifies the instance that calls it 

t1 = Includer.new 
t2 = Includer.new 
t1.test_include # Prints out "FooModule included" followed by "done" 
t1.new_method # Prints out "new method called" 
t2.new_method # Prints out "new method called" - all past and future instances of Includer have been modified