-
-
Notifications
You must be signed in to change notification settings - Fork 100
Description
Starting Ruby 3.0, there is a difference between passing a hash or list of keywords as a method arguments. But Ruby 3.0 parser returns the same result for RubyParser::V30.new.parse:
code = "variable.method(a: 1)"
RubyParser::V30.new.parse(code)
#=> s(:call, s(:call, nil, :variable), :method, s(:hash, s(:lit, :a), s(:lit, 1)))
code = "variable.method({a: 1})"
RubyParser::V30.new.parse(code)
#=> s(:call, s(:call, nil, :variable), :method, s(:hash, s(:lit, :a), s(:lit, 1)))
Note that the result is the same, but it will lead to errors trying to execute it back via Ruby2Ruby if method
has def method(hash, kw: 1)
signature.
I've tried to make up with easier example. Noticed this error when looking at how is "kwargs = { b_keyword: false }; @article.method_with_kwargs('positional', a_keyword: true, **kwargs)"
parsed:
s(:block,
s(:lasgn, :kwargs, s(:hash, s(:lit, :b_keyword), s(:false))),
s(:call, s(:ivar, :@article), :method_with_kwargs, s(:str, "positional"), s(:hash, s(:lit, :a_keyword), s(:true), s(:kwsplat, s(:lvar, :kwargs)))))
Note that a_keyword
becomes part of hash
, even though it's obviously an explicit keyword. Moreover, **kwargs
then become part of the same hash, which is just wrong. It sometimes work, just because { :a_keyword => true, **kwargs }
is being naively extracted in https://github.com/seattlerb/ruby2ruby/blob/master/lib/ruby2ruby.rb#L262-L265.
Could you please tell me if it's expected or it's a bug?