4

私はそのようなコードのブロックを持っています (これは動作中のバージョンです)

@full_user_schedule[0].attributes.each do |event_name, attending|
   if attending
     sessions_hash.each do |id, name|
       event_name = event_name.sub(name, id.to_s) if event_name.include? name 
     end
     @user_schedule.merge!(event_name => attending)
   end
end

event_idステートメント内で変数を設定しようとしたときsessions_hash.each、そのループの外で割り当てることができませんでした (不明な変数の警告が表示されました)。どうしてそうなるのか、また回避する方法を教えていただきたいです。

以下は、何が失敗したかの例です (変数が正しく設定されていることがログに示されていましたが、イベントが発生しました)。変数が作成されたループの外では、変数にアクセスできませんでした。

@full_user_schedule[0].attributes.each do |event_name, attending|
   if attending
     sessions_hash.each do |id, name|
       event_id = event_name.sub(name, id.to_s) if event_name.include? name 
     end
     @user_schedule.merge!(event_id => attending)
   end
end

を明示的に返そうとしましevent_idたが、ループを終了しました。私は何を理解していませんか?

4

2 に答える 2

4

ブロックは実際には一種の匿名関数であるため、独自のスコープを持ちますが、周囲のスコープ内の変数にアクセスできます。

event_idブロックが開始する前に初期化し、親メソッドの要素にします。

event_id = nil
@full_user_schedule[0].attributes.each do |event_name, attending|
   ...
于 2012-12-19T17:15:16.193 に答える
0

2 番目のコード例では、event_id が作成され、渡されたブロック内に割り当てられますsessions_hash.each。そのブロック内にのみ存在し、ブロック外のコードからアクセスすることはできません。これをスコープと呼びます。

最初の例では、渡されたブロックで定義されている event_name に割り当てて@full_user_schedule[0].attributes.eachおり、残りのコードもこのブロックに含まれているため、常にスコープ内にあります。

あなたがここで達成しようとしていることを完全には理解していませんが、これはうまくいくようです:

@full_user_schedule[0].attributes.each do |event_name, attending|
  if attending
     sessions_hash.each do |id, name|
       event_id = event_name.sub(name, id.to_s) if event_name.include? name 
     end
     @user_schedule.merge!(event_id => attending)
   end
end

行を移動した@user_schedule...ので、同じ範囲になりますevent_id

于 2012-12-19T17:18:55.403 に答える