-
-
Notifications
You must be signed in to change notification settings - Fork 922
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
Splat with method_missing inconsistent #2410
Comments
Confirmed in both interpreter and JIT. High priority. Seems like it's not coercing to array, so perhaps it's checking if to_ary is defined before making the call when it should just go for it? |
Yeah it seems to be an IR problem. If I log the method name in method_missing, I see it called twice for MRI and zero times for JRuby 9k. So splatting is not making the call it should in this place. @subbuss You did work on splatting recently...perhaps take a look into this? |
looking.. |
Seems like a bug in Helpers.arrayValue(..) else part of line 1862 .. it is unconditionally returning a new array instead of calling method_missing .. but since these helpers have been around for ever, I don't want to just fix it. But, fixing it there would fix it .. or maybe IRRuntimeHelpers:irSplat is not calling the right helper in Helpers.java. Is this good enough for you or @enebo to take this over? |
Please review my fix and close if it looks good. Will require new tests since this hasn't been covered by any suite so far? |
fwiw, I tested with the above snippet and also by making method_missing return a Fixnum and both MRI and 9k now raise an error. |
I just saw the ``to_a' did not return Array` error you're raising and had a look what MRI does in that case. class A
attr_reader :obj
def initialize(*args)
@obj = args
end
def method_missing(method, *args, &block)
if obj.respond_to?(method)
obj.__send__(method, *args, &block)
else
super
end
end
end
class B < Array
def to_a
nil
end
end
b = B.new
b.push 3
b.push 4
b.push 5
a = A.new(*A.new([1,2,3]), *A.new(b))
puts b.to_a.inspect
puts b.class.name
puts a.inspect MRI output:
I didn't expect this to work. May be this is actually undefined behavior? Or am I missing something here? |
Actually have a one more. Given class A
attr_reader :obj
def initialize(*args)
@obj = args
end
def method_missing(method, *args, &block)
puts "called"
if obj.respond_to?(method)
obj.__send__(method, *args, &block)
else
super
end
end
end
class B
def to_a
nil
end
end
b = B.new
puts b.to_a.inspect
puts b.class.name
a = A.new(*A.new([1,2,3]), *A.new(b))
puts a.inspect MRI output:
I added in a |
jruby current master returns identical output as MRI in both cases.
and
When to_a returns nil, the default behavior is to return an empty array. See the jruby commit that fixes this bug to see the code. |
It sounds like this one is fixed. @tobiassvn If you are seeing the original reported behavior failing, please reopen and demonstrate. If you are seeing related but different behaviors failing, file a new issue. |
The behavior when using the splat operator together with
method_missing
appears to be different from MRI.Example:
On MRI:
On JRuby 9.0.0 SNAPSHOT:
The text was updated successfully, but these errors were encountered: