Bug #5730
closedOptinal block parameters assigns wrong
Description
The following program do not expand the given array, but it should expand the value.
def foo(&block)
block.call([1,2])
end
h = foo{|k=6,v=8|
p [k,v] # gives [[1,2],8] but should be [1,2]
}
Files
Updated by Anonymous about 13 years ago
On Fri, Dec 09, 2011 at 08:59:26AM +0900, Yukihiro Matsumoto wrote:
Issue #5730 has been reported by Yukihiro Matsumoto.
Bug #5730: Optinal block parameters assigns wrong
http://redmine.ruby-lang.org/issues/5730Author: Yukihiro Matsumoto
Status: Open
Priority: Normal
Assignee:
Category:
Target version:
ruby -v: ruby 2.0.0dev (2011-12-09 trunk 33990) [i486-linux]ruby 2.0.0dev (2011-12-09 trunk 33990) [i486-linux]The following program do not expand the given array, but it should expand the value.
def foo(&block)
block.call([1,2])
end
h = foo{|k=6,v=8|
p [k,v] # gives [[1,2],8] but should be [1,2]
}
Would this have the same behavior?
irb(main):001:0> def bar(k=6,v=8); p [k,v]; end
=> nil
irb(main):002:0> def foo(&block); block.call([1,2]); end
=> nil
irb(main):003:0> foo(&method(:bar).to_proc)
[[1, 2], 8]
=> [[1, 2], 8]
irb(main):004:0> RUBY_VERSION
=> "2.0.0"
irb(main):005:0>
--
Aaron Patterson
http://tenderlovemaking.com/
Updated by akr (Akira Tanaka) about 13 years ago
- ruby -v changed from ruby 2.0.0dev (2011-12-09 trunk 33990) [i486-linux]ruby 2.0.0dev (2011-12-09 trunk 33990) [i486-linux] to -
2011/12/9 Yukihiro Matsumoto matz@ruby-lang.org:
The following program do not expand the given array, but it should expand the value.
It is not clear.
If we break consistency between method invocation and block invocation,
I think concrete usefulness should be shown.
My explanation of current behavior if in [ruby-dev:38795] (in Japanese).
Although the optional arguments for block parameter is not exist at the time,
I think the consistency explains current behavior.
Tanaka Akira
Updated by matz (Yukihiro Matsumoto) about 13 years ago
Hi,
In message "Re: [ruby-core:41559] Re: [ruby-trunk - Bug #5730][Open] Optinal block parameters assigns wrong"
on Fri, 9 Dec 2011 09:36:00 +0900, Tanaka Akira writes:
|If we break consistency between method invocation and block invocation,
|I think concrete usefulness should be shown.
OK, the point is when
- block is not a lambda
- yielded value is an array
we expand the value for the sake of compatibility, i.e.
def foo(&block)
block.call([1,2])
end
foo{|k,v|
p [k,v] # gives [1,2]
}
and even when some parameters are optional:
foo{|k,v=6|
p [k,v] # gives [1,2] too
}
but Ruby do NOT expand the value when all parameters are optional:
foo{|k=5,v=6|
p [k,v] # gives [[1,2],6]
}
|I think the consistency explains current behavior.
From above examples, I consider the current behavior is NOT consistent
at all, under some condition.
The example from Aaron in [ruby-core:41558] uses a proc from method
object, which is not the target of this issue. I expect the following
behavior
foo(&->(k=6,v=8){p [k,v]}) # => [[1,2],6]
I don't think fixing this issue does not break any consistency.
matz.
Updated by mwaechter (Matthias Wächter) about 13 years ago
Matz,
On 09.12.2011 09:44, Yukihiro Matsumoto wrote:
Hi,
In message "Re: [ruby-core:41561] Re: [ruby-trunk - Bug #5730][Open] Optinal block parameters assigns wrong"
on Fri, 9 Dec 2011 17:31:31 +0900, Matthias Wächtermatthias@waechter.wiz.at writes:
|
|Hi Matz,
|
|Please excuse my ignorance, but why do we want this auto-splat behavior
|in Ruby at all? For me this goes very much against the POLS. Has this
|been discussed or documented somewhere for reference?Yes, we have been discussed very deeply in the past, mostly in
ruby-dev (Japanese developers list). In tha past history of Ruby,
assignment to block parameters had behaved more like multiple
assignment. But we have gradually moved toward method argument
passing behavior. So if I were about to start new language, I
wouldn't add this auto-splat at all, but since we have history, the
community and the code base, I couldn't fix this corner-case.
Thanks for your explanation. So I’m not the only one wondering …
Maybe we can remove this in Ruby 3.0.
+1
matz.
– Matthias
Updated by akr (Akira Tanaka) about 13 years ago
2011/12/9 Yukihiro Matsumoto matz@ruby-lang.org:
|I think the consistency explains current behavior.
From above examples, I consider the current behavior is NOT consistent
at all, under some condition.
The behavior is consistent with method invocation.
def foo(&block)
block.call([1,2])
end
foo{|k=5,v=6|
p [k,v] # gives [[1,2],6]
}
def bar(k=5,v=6)
p [k,v] # gives [[1,2],6]
end
bar([1,2])
So, it is consistent, under some condition.
However, I re-read [ruby-dev:38795] and I feel the case should be
treated as multiple arguments case.
I.e. You are right. Now I think it is a bug.¶
Tanaka Akira
Updated by matz (Yukihiro Matsumoto) about 13 years ago
Hi,
In message "Re: [ruby-core:41568] Re: [ruby-trunk - Bug #5730][Open] Optinal block parameters assigns wrong"
on Fri, 9 Dec 2011 18:03:15 +0900, Tanaka Akira akr@fsij.org writes:
|I.e. You are right. Now I think it is a bug.
I am happy to see we agree. Nobu, could you fix this issue?
matz.
Updated by nobu (Nobuyoshi Nakada) about 13 years ago
Hi,
(11/12/10 1:19), Yukihiro Matsumoto wrote:
I am happy to see we agree. Nobu, could you fix this issue?
Roger.
But I'm afraid no time at this weekend.¶
--
Nobu Nakada
Updated by nobu (Nobuyoshi Nakada) about 13 years ago
- Status changed from Open to Closed
- % Done changed from 0 to 100
This issue was solved with changeset r34020.
Yukihiro, thank you for reporting this issue.
Your contribution to Ruby is greatly appreciated.
May Ruby be with you.
- vm_insnhelper.c (vm_yield_setup_block_args): splat single
argument if optinal arguments are defined not only mandatory or
post arguments. [ruby-core:41557] [Bug #5730]