Project

General

Profile

Actions

Bug #5730

closed

Optinal block parameters assigns wrong

Added by matz (Yukihiro Matsumoto) almost 13 years ago. Updated almost 13 years ago.

Status:
Closed
Assignee:
-
Target version:
-
ruby -v:
-
Backport:
[ruby-core:41557]

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

noname (500 Bytes) noname Anonymous, 12/09/2011 09:29 AM

Related issues 1 (0 open1 closed)

Related to Ruby master - Bug #7621: ブロック引数にデフォルト値を指定したときに配列を渡した際の挙動が1.9.3と変わっているClosed12/25/2012Actions

Updated by Anonymous almost 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/5730

Author: 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) almost 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 :

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) almost 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) almost 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ächter 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) almost 13 years ago

2011/12/9 Yukihiro Matsumoto :

|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) almost 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 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) almost 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

Actions #8

Updated by nobu (Nobuyoshi Nakada) almost 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]
Actions

Also available in: Atom PDF

Like0
Like0Like0Like0Like0Like0Like0Like0Like0