2011-12-08 4 views
1

インスタンスの属性を実行時に追加されたメソッドから変更し、フローメソッドで次に同じものを引き続き使用しようとしています。実行時に追加されたメソッドからインスタンスの属性を変更します。

class Test 

     def start 
     @s = 5 
     puts "start #{@s}" 
     end 

     def test_1 
     @s = 4 
     puts "test_1 #{@s}" 
     end 

     def flow 
     start 
     test_2 
     puts "flow #{@s}" 
     end 
    end 

Test.class_eval("def test_2\n puts 'test_2 1 #{@s}'\n @s = 7\n test_1\n puts 'test_2 2 #{@s}'\n end\n") 
    t = Test.new 
    t.flow 

その結果は次のとおりです。 開始5 TEST_2 1 TEST_1 4 TEST_2 2 流れ4

だから私はTEST_2の印刷をスキップする理由が何であるか分からないcoudl 1の印刷と、なぜclass属性の値が新しい評価メソッドから更新されないのかを示します。

答えて

2

class_evalの行が二重引用符で囲まれているため、Rubyは@s(この段階ではこの変数はnil)の代用を用意しています。ので、あなたのコードを変更します。

Test.class_eval('def test_2; puts "test_2 1 #{@s}"; @s = 7; test_1; puts "test_2 2 #{@s}"; end') 
# => 
    start 5 
    test_2 1 5 
    test_1 4 
    test_2 2 4 
    flow 4 

または使用ブロック一緒class_eval

Test.class_eval do 
    def test_2 
    puts "test_2 1 #{@s}" 
    test_1 
    puts "test_2 2 #{@s}" 
    end 
end 

そして、もう一つのノートを(それははるかに良いですが、私は信じています)。 test_1メソッドでは、もう1つの割り当て@s = 4がすぐに準備されるため、@s = 7割り当てが冗長です。

+0

お返事ありがとうございます。これはUIから定義され、DBに保存されているメソッドに基づくDSLの単純化された例です。私の問題は、評価され、クラス属性を取得する新しく定義されたメソッドは、メソッドから終了した後にこれらの属性が更新されないということです。クラス属性として定義された配列の配列があるとします。評価されたメソッドでは、文字列の1つを配列から変更し、終了後にこのクラスから次のメソッドでこの文字列が変更されたことを確認しません。これはちょっとタイプミスか、私はいくつかのリビー原則がないかもしれないと仮定します – user1087894