2016-06-17 3 views
0

私は、このクラスの階層構造があります:update_params_3`super`が期待通りの順序で解決されないのはなぜですか?

class Parent 
    attr_accessor :params 
    def initialize 
     @params = {"original" => "original"} 
    end 
end 

class Child < Parent 
    def params 
     super 
    end 

    def update_params_1 
     params = {"update" => "update"} 
     params 
    end 

    def update_params_2 
     temp_var = params 
     params = temp_var.merge({"update" => "update"}) 
     params 
    end 

    def update_params_3 
     params = params.merge({"update" => "update"}) 
     params 
    end 
end 

child = Child.new 
child.update_params_1 
# => {"update"=>"update"} 
child.update_params_2 
# => {"original"=>"original", "update"=>"update"} 
child.update_params_3 
# => undefined method `merge' for nil:NilClass (NoMethodError) 

paramsnilです。

割り当て演算子のRHSのメソッド呼び出しに関与すると、paramsは常にnilと考えられます。しかし、それは真実ではありません。私はこのメソッドを追加して、RubyがRHSのチェーンにメソッドを追加できることを確認しました。それは期待どおりに動作します。

def right_hand_side 
    temp_var = params.inspect 
    puts temp_var 
end 

はなぜRubyがmergeへの呼び出しを連鎖する前にupdate_params_3params呼び出しを解決しませんか? paramsに値を割り当てた場合にのみ、paramsnilとなるのはなぜですか?これはRubyの意図ですか、バグですか?

答えて

1

ローカル変数paramsが作成され、それまたはparams.merge({"update" => "update"})かが実行される前にparams = ...が解析された直後にnilとして初期化されているので、それはあります。

ローカル変数は、メソッドに優先を持っているので、params.merge({"update" => "update"})paramsは、新しく作成されたローカル変数params代わりの方法paramsとして解釈されます。

+0

あなたが私に答えを教えてくれたら、Hmは一見一種のように思えます...今は私は気が気になりません。 –

1

params = ...paramsというローカル変数に割り当てられます。あなたは実際に@paramsを変更することはありません。paramsというローカル変数を作成して返してください。

selfparams=アクセサーを使用する場合は、割り当てを行うたびにself.params = ...が必要です。

関連する問題