From: Mark Hubbart Date: 2005-01-21T02:08:33+09:00 Subject: Re: Confused about variable "declarations" On Thu, 20 Jan 2005 21:01:01 +0900, Graham Nicholls wrote: > No worries, and thanks, but I think that the problem was that offset is > being set inside an iterator (they still confuse me - any pointers to a > good explanation would be nice!), which means that it is out of scope > outside the iterator. A short explanation: Blocks have a sort of "leaky scope", where variables from outside the scope can leak in and out, but those that are from the inside don't leak out. for example: def increment_23(num) 23.times { num += 1 } return num end increment_23(9) #=>42 This is because num was defined in the block's outer scope, so it leaked in. In this example, though: def one 1.time { num = 1 } return num end one() #=> error! This gives an error because num was created *inside* the block, and didn't leak out. So "return num" references a variable that doesn't exist in that scope. You could fix it like this: def one num = nil # assign something to num, initializing it. 1.time{ num = 1 } return num end one() #=>1 Setting the variable before entering the block lets it leak in (and out). Though it doesn't actually matter what you assigning to the variable, from what I've seen, the most common idiom for this is to assign nil, like in the above. That way, if you see where someone has assigned nil to a variable above a block, you can be fairly sure that they will also be assigning to that variable inside the block, and want it to leak back out of the block so they can use it later. So, to recap: When you assign to a variable *inside* a block, ruby looks first to see if there is a variable of the same name *outside* the block; if there is, it will use the same variable; if there isn't, it will create a variable local only to that block. HTH, Mark