循环内循环并在深循环中分配变量

时间:2012-12-19 16:58:47

标签: ruby variables loops closures

我有一块像这样的代码(这是工作版本)

@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,但是退出了循环。我不理解的是什么?

2 个答案:

答案 0 :(得分:4)

一个块实际上是一种匿名函数,因此它有自己的作用域,但它可以访问周围作用域中的变量。

在块开始之前初始化event_id,使其成为父方法的元素。

event_id = nil
@full_user_schedule[0].attributes.each do |event_name, attending|
   ...

答案 1 :(得分:0)

在第二个代码示例中,在sessions_hash.each传递的块中创建并分配了event_id。它只存在于该块中,不能从块外的代码访问。这称为范围。

在第一个示例中,您将分配给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

的范围相同