Davide wrote such intriguing questions to be a real newbie :) > Which is the rationale of the fact that block variables are > non-binding if some variable with the same name already > exists ? Isn't it confusing? I think I'm reading your question wrongly, but it seems you have a mistake here. I guess a block variable binds if there exists a variable of same name in outer scope. And it *is* confusing sometimes. For me the only bothersome case was when there wasn't a variable, and I tried to access a variable local to a block. Like: def foo loop { a = "initialize" break } puts a end foo But even that was easy afterall. I'm sure I'll hit really hard runtime weirdness in the future, but so far so good. > What is supposed to do the following fragment of code? > > a = 1 ; x = 1 ; f = proc {|a| a += 1} > f.call(x) I have to say your following example makes me dizzy, but for this I can give my explanation, even though it might be completely wrong. When we call the method call of the proc object referenced by f, we pass the object referenced by x as an argument. That object is number 1. In the block the first thing is to assign arguments to the parameter list, so 'a' starts to refer to object 1. Then we send a message '+' to object passed object 1 with and argument 1, and get a reference to a object 2, which is assigned to variable a again. Then we fade out from a proc, and return from the call, continuing from the next line after your example. In my understanding your example shouldn't touch the "top-level" variable 'a' at all, as the proc has a variable 'a' already in scope before "a+=1" - namely the 'a' in the proc's parameter list. So I'm really puzzled why this example of yours actually changes the value of the top-level variable 'a' based on if it's passed to the block or not. Maybe the clever guys will enlight us. > a = 1 ; x = 1 ; f = proc {|a| a += 1} > f.call(x) > f.call(a) > a # results in 2 > > a = 1 ; x = 1 ; f = proc {|a| a += 1} > f.call(a) > f.call(x) > a # results in 3 And what it comes to your last question > Are the following statement equivalent? > > p() if (b1 and b2) > p() if (b1 && b2) > > If so, why are operators `and', `or' needed? I have to say there are differences, and I'd like to have both, while maybe both are not actually needed. Their precedence is different, and 'and' is lower, thus: ruby -v -e "def foo; true; end; p foo and false; p foo && false;" ruby 1.6.2 (2000-10-11) [i386-cygwin] true false The first p is actually p(foo) and false; # evaluating to (nil and false) which is nil The second p( foo && false ); # evaluating to nil Usually you don't have to think about the difference so much. It's quite much the same as you think when to put extra parentheses to calculations. Nevertheless, use extra parentheses when in doubt. My personal opinion is that 'and' is much more nicer looking, and should be used most of the time. - Aleksi