Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A block destructuring arguments bug #3544

Closed
janko opened this issue Dec 26, 2015 · 3 comments
Closed

A block destructuring arguments bug #3544

janko opened this issue Dec 26, 2015 · 3 comments

Comments

@janko
Copy link

janko commented Dec 26, 2015

I've found a weird bug with keyword arguments and parenthesized block parameters when using each_with_object or inject. The below code will return incorrect block variable values:

def function(hash: nil)
  hash.each_with_object(Object.new) do |(key, value), object|
    p key    #=> {}
    p value  #=> nil
    p object #=> [:foo, "bar"]
  end
end

function(hash: {foo: "bar"})

If I change (key, value) to be stored as just element, the code works. If I change the signature of this method to be an options hash, and in the next line use options[:hash], it works. Executing the code inside the method by itself works as well.

$ ruby -v
rubinius 2.5.8 (2.1.0 bef51ae3 2015-09-25 3.5.1 JI) [x86_64-darwin14.5.0]
$ uname -a
Darwin Jankos-MacBook-Pro.local 15.2.0 Darwin Kernel Version 15.2.0: Fri Nov 13 19:56:56 PST 2015; root:xnu-3248.20.55~2/RELEASE_X86_64 x86_64
@janko
Copy link
Author

janko commented Dec 26, 2015

Since Rubinius 2.9 didn't come to ruby-build I couldn't test with the latest locally, but on Travis I set 2.9 and this bug is still there.

janko added a commit to shrinerb/shrine that referenced this issue Dec 28, 2015
Rubinius breaks in rack-test_app when using multipart, so we'll
temporary skip those tests until the issue is resolved.

rubinius/rubinius#3544

Fixes #29
@sshao
Copy link
Contributor

sshao commented Dec 29, 2015

I looked a little into this and haven't found a solution yet, but this might be independent of kwargs. I have a kwargs-less repro that I think is victim to the same bug:

outer = { foo: 'bar' }

outer.each do |(key, value)|
  inner = { baz: 'qux' }
  inner.each do |(inner_key, inner_value)|
    puts "inner loop"
    p inner_key #=> should print baz, prints 'foo' instead
    p inner_value #=> should print qux, prints 'bar' instead
  end

  puts "\nouter loop"
  p key
  p value
end
$ ruby -v test2.rb
rubinius 2.10.c1 (2.1.0 f0b5ce66 2015-12-27 3.5.1 JID) [x86_64-darwin14.5.0]
inner loop
:foo
"bar"

outer loop
:foo
"bar"

$ ruby -v test2.rb
ruby 2.2.3p173 (2015-08-18 revision 51636) [x86_64-darwin14]
inner loop
:baz
"qux"

outer loop
:foo
"bar"

@brixen
Copy link
Member

brixen commented Dec 30, 2015

This looks like it could be a bug in multi-assignment destructuring. Basically, in block arguments, nested parenthesized arguments are destructured like multiple assignment, eg a, b = [x, y]; a == x; b == y.

I don't see where @janko-m's code is actually passing a Hash or keyword arguments, so I think @sshao's alternate (or additional?) repro points at destructuring being the real bug.

Would have expected that we already had specs for this sort of case, but that would be a good place to start.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants