2012-03-24 13 views
1

多分私は構造体について十分に分かっておらず、盲目的に使っていますが、以下の結果は私には不合理なようです。なぜこの変数は構造体で消えますか?

class VarTest < Struct.new(:email) 
    def perform 
    puts "Start: #{email}" 
    if email == "nothing" 
     email = "bad email" 
    end 
    puts "End: #{email}" 
    end 
end 
VarTest.new("[email protected]").perform 

予期しない出力:

Start: [email protected] 
End: 

私は、コードを変更する場合:

01:

class VarTest < Struct.new(:email) 
    def perform 
    e = email 
    puts "Start: #{e}" 
    if e == "nothing" 
     e = "bad email" 
    end 
    puts "End: #{e}" 
    end 
end 

VarTest.new("[email protected]").perform 

私たちは、予想される出力を得ます

誰かがこれで起こっていることを説明できますか?

ありがとうございました。

+0

実際の目標は何ですか?言い換えれば、なぜあなたは 'VarTest = Struct.new(:email)'と 'VarTest.new( '[email protected]')の代わりに継承を使っていますか? –

+0

エンキューの一部として遅延ジョブによって使用されています。それにもかかわらず、なぜこのように使用するとこの動作が起こりますか? – chrishomer

答えて

4

email = "bad email"self.email = "bad email"に置き換えると、正常に動作します。これはセッターを使用するときに常に当てはまります。

理由は簡単です:Rubyがbarewordに遭遇すると、ローカル変数として解決しようとします。何もない場合、その名前でメソッドを呼び出そうとします。クラス本体の中で、自己は暗黙的な受信機なので、読者だけが働きます。今作家にとっては問題があります。 foo = "bar"のようなものを書くと、Rubyは新しいローカル変数を作成するので、受信者を明示的にする必要があります。

このケースは少しトリッキーです:if email == "nothing"はゲッターを使用しています。しかし、email = "bad email"はパーサーによって引き続き表示され、ローカル変数emailnilに設定されます。これはパーサが割り当てのLHSとしてベアワードを見るときに常に起こります。このローカルnilの値は、emailの値が消えるように見えるようにするものです(最後のputsputs "End: #{self.email}"に変更するだけで確認できます)。

+0

素晴らしい。これはStructsに固有のものではありません。構造変数がどのように働いたかはわかりませんでした。後向きには完璧な意味合いを持つ。さて、学習は続けられ、それがこの楽しいものを作るのです!ありがとう! – chrishomer

関連する問題