On Tue, Jan 25, 2011 at 7:09 PM, Jon Leighton <j / jonathanleighton.com> wrote: > Robert Klemme wrote in post #977336: >> On Mon, Jan 24, 2011 at 7:18 PM, Jon Leighton <j / jonathanleighton.com> >> wrote: >>> Thanks for the explanation. FWIW I think it is a shame that postfix >>> conditionals are semantically different to normal ones, but it's good to >>> know why the difference occurs. >> >> See Gary's reply. > > Yes, I agree that it's surprising this is done at parse time. But > regardless of the cause and effect it is still surprising (to me) that > the two conditional syntaxes have different semantics :) Why do you find that surprising? Parse time is exactly the time when things are done like - determining which code sequence is a method call - determining which code sequence is a class definition ... - and also what code sequence denotes a variable name - and the kind of variable (instance, local, class) Ruby is dynamic but this does not mean that source code has arbitrary semantic. I guess the reason that a following assignment to a local variable has no effect on prior usage of the identifier is compiler efficiency. If the assignment can be anywhere in local scope you need more complex lookups or a second pass whereas with the current rule you simply collect local variables you have seen so far and check each identifier occurrence against the current set of known local variables. You might want to argue that one could make an exception for postfix statements but that exception would only be efficient for the simple case we discussed and be much harder for more complex expressions before the postfix "if" (these expressions can even span multiple lines). Also, the rule would be more complicated which is always bad because that would hinder learning the language (and maybe also bug hunting). >>> I started to wonder about this when I was using the following code: >>> >>> bla(foo) if foo = self.foo >>> >>> In other words, I was trying to put the value of the method foo into the >>> local variable foo in order to avoid calling the method twice. To me the >>> above is quite an elegant way of doing that, so it's a shame that it >>> does not actually have the intended effect ;) [it all came crashing down >>> when I renamed the foo variable] >> >> Frankly, I don't find this elegant at all. > > It's a matter of taste. I agree with you that in almost all situations > that assignment during a conditional test is not nice. I'd say it's not only taste: you should be aware of the implications. The warning in the assignment is there for a good reason, namely because it's a typical typing error to type "=" instead of "==". This will also make the code harder to read IMHO and might left the reader wondering whether it was intentional or caused by named typing error. > However, I liked this solution precisely because the local var was named > exactly the same as the method. So the way I read it in my head was > "call bla with foo, and oh btw, don't call the foo method twice". So in > this situation the 'if foo = self.foo' was purely a performance tweak > and nothing else. A side note, if you will - it didn't change the > semantics of the statement. > > But as I say, it's a matter of taste. And it doesn't work anyway ;) Well, at least you can do foo = foo() and bla(foo) Kind regards robert -- remember.guy do |as, often| as.you_can - without end http://blog.rubybestpractices.com/