Issue #12821 has been updated by George Koehler.


It's not what I expected, but Ruby is splitting `test2` into two hashes, with all keywords into the second hash. There are no keywords in `{0 => [0, 1]}`, so Ruby passes `{0 => [0, 1]}` as `foo` and `{}` as keywords.

~~~ ruby
def argtest2 foo = nil, bar: nil
  printf "foo = %p (%p), bar: %p\n", foo, foo.class, bar
end

argtest2(0 => [0, 1], bar: 2) # => foo = {0=>[0, 1]} (Hash), bar: 2
argtest2(bar: 2, 0 => [0, 1]) # => foo = {0=>[0, 1]} (Hash), bar: 2
argtest2(0 => [0, 1])         # => foo = {0=>[0, 1]} (Hash), bar: nil
~~~

So `argtest2(test2)` acts like `argtest2(0 => [0, 1])`. I don't know why Ruby does this split, or why Ruby 2.1 was different.

----------------------------------------
Bug #12821: Object converted to Hash unexpectedly uder certain method call
https://bugs.ruby-lang.org/issues/12821#change-60884

* Author: Hiroyuki Tanaka
* Status: Open
* Priority: Normal
* Assignee: 
* ruby -v: 2.2.5p319, 2.3.1p112, 2.4.0-preview2
* Backport: 2.1: UNKNOWN, 2.2: UNKNOWN, 2.3: UNKNOWN
----------------------------------------
Hi,

I saw a bit strange behavior (at least for me) with the code below; an object given as an argument to a method with a default value and a keyword argument becomes Hash class if the object has 'to_hash' method with ruby >= 2.2, but it is not converted to Hash with ruby 2.1.
I expected the behavior of ruby 2.1.
Is this a bug or expected behavior of ruby >= 2.2?

I tested both on Linux x86_64 (CentOS 6) and Mac OS X 10.11.6.

~~~ ruby
class Test1
end

class Test2
  def to_hash
    {0 => [0, 1]}
  end
end

def argtest1 foo, bar: nil
  p foo.class
end

def argtest2 foo = nil, bar: nil
  p foo.class
end

test1 = Test1.new
test2 = Test2.new

argtest1(test1) # => Test1
argtest1(test2) # => Test2

argtest2(test1) # => Test1
argtest2(test2) # => Hash (2.2.5p319, 2.3.1p112, 2.4.0-preview2), Test2 (2.1.10p492)

~~~

Regards,
Hiroyuki Tanaka



-- 
https://bugs.ruby-lang.org/

Unsubscribe: <mailto:ruby-core-request / ruby-lang.org?subject=unsubscribe>
<http://lists.ruby-lang.org/cgi-bin/mailman/options/ruby-core>