From: "Guy N. Hurst" Date: 2002-04-14T08:52:12+09:00 Subject: Re: not vs !, and vs && james@rubyxml.com wrote: > ... > So, 'and' and '&&' are *not* synonyms that differ only in precedence? > (Likewise for '!' and 'not' ) > They are synonyms, but one forms a statement, and the other forms an expression. The difference is that you cannot use a statement as an argument inside another statement or expression. And it is solved by adding a set of parentheses. This can be considered a precedence issue, I suppose, as far as parsing goes. "In Ruby's syntax, statement is just a special case of a expression which cannot appear as a argument (e.g. multiple assignment)." "Because method call without parentheses is considered as statement, which can not be part of expression unless grouped within parentheses." ... > In this example: > > #----------------------------------- > def nt > puts "Inside nt" > not true > end > > put nt # Prints 'Inside nt', then 'false' > #----------------------------------- > > Why does the last line of the method nt act as an expression? > In Ruby, 'everything has its value'. Both expressions and statements are executed and have a value. You might think expressions have a value and statements don't, but that is not necessarily how it works in Ruby: "If every expression must have value by definition, it's OK for me to call non-value-returning expressions as statements, but must it?" Some expressions, such as 'while', 'class', and 'def', don't return any 'value' (see ). Now, matz said they do have one, they just aren't accessible ;-) "In Ruby, everything has its value, even definitions (although they doesn't have meaningful values)." He makes them return 'void value expression' arbitrarily: "Some expressions (e.g. while, break, etc.) are marked as void expression by the parser. I can relax them very easily if they bother you rather than helping you." "... if we can find proper return value for `def', I'll change expressions `class', `module', and 'def' to return values. Otherwise remain as they are." By the way, you can still use them as part of an argument if in addition to adding parentheses you also specify an explicit value: m = (def meth(x); x.new; end; nil) o = meth( (class MyClass; end; MyClass) ) Guy N. Hurst