2017-06-05 18 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 

Test.instance.testを呼び出すとき、私が欲しい

module Instructions_to_add_to_the_method 
    puts 'hi !' 
end 

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。 Rubyで継承を使用するこの方法は、少し後方にあることを

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 

注:継承は何のためにあるのかだ

hi ! 
done 

を:

Test.instance.testを呼び出すときに、私が欲しいです。このようなものが本当に必要な場合は、ベータのような言語を使用する必要があります。これは、継承が自然に機能する方法です。

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 

よりよい解決策は、ブロックにINGのyieldような単純なものにすることができRubyでTemplate Method Software Design Patternようなものになるだろうまたはフック方法を呼び出すことによって:

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 
関連する問題