A = b = c order of evaluation weird

It demonstrates, at least, that one subscript op is evaluated
left-to-right, thus we expect all of them to be so.

···

On Tue, 2007-10-02 at 23:25 +0900, 7stud -- wrote:

Since your example only has one subscript
expression, it doesn't shed any light on that issue.

Hi,

···

In message "Re: a = b = c order of evaluation weird" on Tue, 2 Oct 2007 23:25:20 +0900, 7stud -- <dolgun@excite.com> writes:

I guess it's safer to say that the order of evaluating arguments is
undefined, unless it is stated somewhere.

Is it defined for ruby?

Two different answers:

  * there's no official specification of the language, so that it is
    not defined at all.

  * but at least the author (me) strongly suggests left-to-right
    evaluation order, so it seems we can say it's "defined".

              matz.

Arlen Christian Mart Cuss wrote:

···

On Tue, 2007-10-02 at 23:25 +0900, 7stud -- wrote:

Since your example only has one subscript
expression, it doesn't shed any light on that issue.

It demonstrates, at least, that one subscript op is evaluated
left-to-right, thus we expect all of them to be so.

How do you know the subscript expression wasn't evaluated from right to
left?
--
Posted via http://www.ruby-forum.com/\.

Arlen Christian Mart Cuss wrote:
>> Since your example only has one subscript
>> expression, it doesn't shed any light on that issue.
>
> It demonstrates, at least, that one subscript op is evaluated
> left-to-right, thus we expect all of them to be so.

How do you know the subscript expression wasn't evaluated from right to
left?

We'll combine two pieces of information here:

But anyway, my take on this is that

  a[0..a.size/2] = a[a.size*2/3..-1] = nil

is equivalent to:

  a.=(0..a.size/2, a.=(a.size*2/3..-1, nil))

And:

irb(main):001:0> a = [1,2,3,4,5]
=> [1, 2, 3, 4, 5]
irb(main):002:0> b = 1
=> 1
irb(main):003:0> a[b] = (b = 10)
=> 10
irb(main):004:0> a
=> [1, 10, 3, 4, 5]

The first one shows us that our initial double-assignment statement is
decomposed into that there function call. Looking at the second one, we
can also see that it's like this:

a.=(b, b = 10)

The second example shows us that `b' in the first parameter must
therefore be evaluated first, before `b = 10' is. We can apply that to
the original example and reason that "0..a.size/2" is evaluated before
"a.=(a.size*2/3..-1, nil)".

So, you can conclude that the assignments must be evaluated
left-to-right, because of they way they decompose into functions.

Hope this helps your understanding.

Arlen

···

On Wed, 2007-10-03 at 01:23 +0900, 7stud -- wrote:

> On Tue, 2007-10-02 at 23:25 +0900, 7stud -- wrote:

You can play with set_trace_func :

20:16 fred@vodka:~/ruby> cat toto.rb
#! /usr/local/bin/ruby

a = Array(1..100)

set_trace_func proc { |e,f,l,i,b,c|
  printf "%8s %s:%-2d %10s %8s\n",e,f,l,i,c if e == 'c-call'
}

a[0..a.size/2] \
  = \
  a[a.size*2/3..-1] \
  = \
  nil

20:16 fred@vodka:~/ruby> ruby toto.rb
  c-call toto.rb:9 size Array
  c-call toto.rb:9 / Fixnum
  c-call toto.rb:11 size Array
  c-call toto.rb:11 * Fixnum
  c-call toto.rb:11 / Fixnum
  c-call toto.rb:12 = Array
  c-call toto.rb:10 = Array

(I didn't expect the real line numbers, by the way. Cooool !)
  
Fred

···

Le 02 octobre à 18:23, 7stud -- a écrit :

Arlen Christian Mart Cuss wrote:

On Tue, 2007-10-02 at 23:25 +0900, 7stud -- wrote:

Since your example only has one subscript
expression, it doesn't shed any light on that issue.

It demonstrates, at least, that one subscript op is evaluated
left-to-right, thus we expect all of them to be so.

How do you know the subscript expression wasn't evaluated from right to
left?

--
Now that I think about it, having a (dense) group of Marketeers and
Salesweasels play russian roulette with, say, an 88 Flak would be better
than handing one of them an M1911 and convincing them that their odds
are better than with a revolver. (Matt Olson in ATSR)