From: Rob Biedenharn Date: 2008-07-08T00:55:03+09:00 Subject: Re: Another logical precedence question On Jul 7, 2008, at 11:28 AM, -j b- wrote: > I am used to using the following shortcut: > > value = ARGV.shift or usage > > where usage is a method. > However, I recently ran into a situation where the following did not > work (as expected, anyway): > > $user_type = ARGV.shift or usage > $user_map = ARGV.shift or DEFAULT_MAP > > DEFAULT_MAP is just a string constant. When I tried to access > $user_map > later I was surprised to find that it was nil when no argument was > provided. If I changed things to: > > $user_type = ARGV.shift or usage > $user_map = (ARGV.shift or DEFAULT_MAP) > > I got behavior I expected ($user_map was assigned DEFAULT_MAP). > > Why the two types of behavior based (as far as I can tell) on the type > of the second parameter to 'or'? If you choose to use 'or' rather than '||', you are not just getting different precedence ('or' is lower than '||'), but there are a bunch of operators that fall in the middle. In particular, the assignment operators are higher precedence than 'or' and lower precedence than '||'. So you really have: (value = ARGV.shift) or (usage) ($user_type = ARGV.shift) or (usage) ($user_map = ARGV.shift) or (DEFAULT_MAP) When you change the operator to '||', the precedence becomes the equivalent of: value = (ARGV.shift || usage) $user_type = (ARGV.shift || usage) $user_map = (ARGV.shift || DEFAULT_MAP) Generally, the use of the ultra-low precedence 'and', 'or', 'not' operators is best reserved for places where the precedence does what you expect. For me, this typically means thinking of these as combining "statements" (which are often either assignment or flow control) rather than expressions (for which I tend to always use '&&', '||', '!' although my background with C and Perl make this sub- conscious in most cases). -Rob Rob Biedenharn http://agileconsultingllc.com Rob@AgileConsultingLLC.com