Bug #4440

odd evaluation order in a multiple assignment

Added by Yusuke Endoh about 3 years ago. Updated almost 2 years ago.

[ruby-core:35367]
Status:Closed
Priority:Normal
Assignee:Yukihiro Matsumoto
Category:-
Target version:-
ruby -v:- Backport:

Description

=begin
遠藤です。

Ruby は左から右に評価が進むと信じていたのですが、多重代入で裏切られました。

def foo
p :foo
[]
end
def bar
p :bar
end

x, foo[0] = bar, 0

bar より foo が左にあるので、:foo 、:bar の順に出力されることを期待するのですが、なんと :bar 、:foo になります。

具体的に何が困るかというと、例えば

obj, obj.foo = obj.foo, obj

には swap を期待するわけですが、そうなりません。こういうコードは実際に、木の回転などを実装するときにしばしば書きたくなります。この挙動に気がついたのも splay tree を実装していたときでした。こんなの:

t.left, t.left.right, t = t.left.right, t, t.left

1.9 系列で修正すべきとまでは思いませんが、2.0 で直る可能性はあるでしょうか。

IRC で話したら「それで普通」みたいな反応もありましたが、

foo[0] = bar

はちゃんと :foo 、:bar の順に出ます。

Yusuke Endoh mame@tsg.ne.jp
=end


Related issues

Duplicated by ruby-trunk - Bug #4442: odd evaluation order in a multiple assignment Rejected 02/24/2011
Duplicated by ruby-trunk - Bug #4443: odd evaluation order in a multiple assignment Open 02/24/2011

History

#1 Updated by Yukihiro Matsumoto about 3 years ago

  • ruby -v changed from ruby 1.9.2p0 (2010-08-18 revision 29036) [i686-linux] to -

=begin
まつもと ゆきひろです

In message "Re: [Ruby 1.9 - Bug #4440] [Open] odd evaluation order in a multiple assignment"
on Thu, 24 Feb 2011 23:02:38 +0900, Yusuke Endoh mame@tsg.ne.jp writes:

|Ruby は左から右に評価が進むと信じていたのですが、多重代入で裏切られました。

|bar より foo が左にあるので、:foo 、:bar の順に出力されることを期待するのですが、なんと :bar 、:foo になります。

|1.9 系列で修正すべきとまでは思いませんが、2.0 で直る可能性はあるでしょうか。

優先順位は高くありませんが、直すべきだと思います。

とはいうものの、1.8のころからこうだったのですし、直すのが難しいのも確
かなのですが。
=end

#2 Updated by Yukihiro Matsumoto about 3 years ago

=begin
Hi,

Oops, I sent Japanese message to the core. Sorry.

                        matz.

In message "Re: Re: [Ruby 1.9 - Bug #4440] [Open] odd evaluation order in a multiple assignment"
on Thu, 24 Feb 2011 23:26:13 +0900, Yukihiro Matsumoto matz@ruby-lang.org writes:
|
|まつもと ゆきひろです
|
|In message "Re: [Ruby 1.9 - Bug #4440] [Open] odd evaluation order in a multiple assignment"
| on Thu, 24 Feb 2011 23:02:38 +0900, Yusuke Endoh mame@tsg.ne.jp writes:
|
||Ruby は左から右に評価が進むと信じていたのですが、多重代入で裏切られました。
|
||bar より foo が左にあるので、:foo 、:bar の順に出力されることを期待するのですが、なんと :bar 、:foo になります。
|
||1.9 系列で修正すべきとまでは思いませんが、2.0 で直る可能性はあるでしょうか。
|
|優先順位は高くありませんが、直すべきだと思います。
|
|とはいうものの、1.8のころからこうだったのですし、直すのが難しいのも確
|かなのですが。
=end

#3 Updated by Yusuke Endoh about 3 years ago

=begin
Sorry, I've sent a Japanese mail to ruby-core by mistake.
Translation :-)

Hi,

I have believed that Ruby evaluates everything from left to
right, but was betrayed by a multiple assignment:

def foo
p :foo
[]
end
def bar
p :bar
end

x, foo[0] = bar, 0

Because "foo" precedes "bar", I expect that this prints :foo
and :bar in this order, but actually :bar and :foo.

I think that this is a matter in practice. For example,

x, y = y, x

is used to swap the two, but

obj, obj.foo = obj.foo, obj

does not so. This kind of code is often written to rotate
a tree. In fact I realized this behavior when I was writing
a splay tree, like this:

t.left, t.left.right, t = t.left.right, t, t.left

I don't think that this should be fixed in 1.9 series, but
can we fix this in 2.0?

Some people (in Japanese IRC) said me that the behavior is
expected, but note that

foo[0] = bar

does print :foo and :bar in the order.

--
Yusuke Endoh mame@tsg.ne.jp
=end

#4 Updated by Shyouhei Urabe about 3 years ago

  • Status changed from Open to Assigned

#5 Updated by Yui NARUSE over 2 years ago

  • Project changed from ruby-trunk to CommonRuby
  • Target version deleted (Next Major)

#6 Updated by Yui NARUSE over 2 years ago

  • Project changed from CommonRuby to ruby-trunk

#7 Updated by Koichi Sasada almost 2 years ago

  • Description updated (diff)
  • Status changed from Assigned to Closed

Also available in: Atom PDF