From: Rick DeNatale Date: 2009-11-22T08:35:17+09:00 Subject: Re: Order of evaluation and precedence On Sat, Nov 21, 2009 at 5:30 PM, Seebs wrote: > In _The Ruby Programming Language_, it is asserted that order of evaluation > is controlled by precedence. > > However, this is often asserted in books about C, where it's definitely > not true.  Is it actually true in Ruby? > > In other words: > >        def a >          puts "a" >          1 >        end >        def b >          puts "b" >          1 >        end >        def c >          puts "c" >          1 >        end >        x = a + (b + c) > > Is it actually guaranteed that the output will have "a" after "b" and "c"? > In C, it wouldn't be.  (Compilers are free to evaluate the operands in any > order whatsoever, then feed them into operators, all that precedence and > grouping controls is which operands go to which operators.) I think you are confusing precedence ordering with evaluation strategy. Precedence determines the order in which the operators/functions/methods are performed. so in a + b * c the * is performed before the + But the timing of when the argument expressions is evaiuated is a different issue. Ruby like most other languages uses what is called applicative ordering, which means that the arguments to a function are evaluated before the function is called (or applied). They don't need to be evaluated JUST before the function is applied, just BEFORE it is. Consider this Ruby program and its output: class NoisyNum def initialize(name) @name = name puts "#{name} created" end def to_s @name.to_s end def +(other) NoisyNum.new("#{self}+#{other}") end def *(other) NoisyNum.new("#{self}*#{other}") end end def N(name) NoisyNum.new(name) end x = N(:a) + N(:b) * N(:c) a created b created c created b*c created a+b*c created A few languages use what is called Normal order (strange since it's not the normal strategy used) in which the evaluation of the arguments is delayed until they are needed by a function. Some languages like Lisp/Scheme normally use applicative order, but have what are called special forms which use normal order. This allows special forms to be used to define control flow like if/then/else to be implemented with a function with the condition, and the two alternatives. In Ruby you could think of the expression a || b as a special form in that the b expression is not evaluated unless a is not truthy. HTH -- Rick DeNatale Blog: http://talklikeaduck.denhaven2.com/ Twitter: http://twitter.com/RickDeNatale WWR: http://www.workingwithrails.com/person/9021-rick-denatale LinkedIn: http://www.linkedin.com/in/rickdenatale