Skip to content

Commit 39114ba

Browse files
committed
[GR-19220] Fix Method/Proc #parameters method when there are multiple _ parameters
PullRequest: truffleruby/3745
2 parents 1883f8a + c33a4a2 commit 39114ba

File tree

4 files changed

+48
-0
lines changed

4 files changed

+48
-0
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,7 @@ Bug fixes:
5252
* Fix `MatchData#[]` to support negative `length` argument (#2929, @andrykonchin).
5353
* Fix `IO` line reading calls when using a multi-byte delimiter (`IO#{each,gets,readline,readlines,etc.}) (#2961, @vinistock, @nirvdrum).
5454
* Fix the exception type raised when type coercion raises a `NoMethodError` (#2903, @paracycle, @nirvdrum).
55+
* Fix `Method` and `Proc` `#parameters` method to return `_` parameter name without synthetic suffix when there are multiple `_` parameters (@paracycle).
5556

5657
Compatibility:
5758

spec/ruby/core/method/parameters_spec.rb

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ def one_splat_one_block(*args, &block)
2020
local_is_not_parameter = {}
2121
end
2222

23+
def underscore_parameters(_, _, _ = 1, *_, _:, _: 2, **_, &_); end
24+
2325
define_method(:one_optional_defined_method) {|x = 1|}
2426
end
2527

@@ -251,6 +253,20 @@ def one_splat_one_block(*args, &block)
251253
m.method(:writer=).parameters.should == [[:req]]
252254
end
253255

256+
it "returns all parameters defined with the name _ as _" do
257+
m = MethodSpecs::Methods.instance_method(:underscore_parameters)
258+
m.parameters.should == [
259+
[:req, :_],
260+
[:req, :_],
261+
[:opt, :_],
262+
[:rest, :_],
263+
[:keyreq, :_],
264+
[:key, :_],
265+
[:keyrest, :_],
266+
[:block, :_]
267+
]
268+
end
269+
254270
it "returns [[:rest]] for core methods with variable-length argument lists" do
255271
# delete! takes rest args
256272
"foo".method(:delete!).parameters.should == [[:rest]]

spec/ruby/core/proc/parameters_spec.rb

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,4 +115,30 @@
115115
local_is_not_parameter = {}
116116
end.parameters.should == [[:rest, :args], [:block, :blk]]
117117
end
118+
119+
it "returns all parameters defined with the name _ as _" do
120+
proc = proc {|_, _, _ = 1, *_, _:, _: 2, **_, &_| }
121+
proc.parameters.should == [
122+
[:opt, :_],
123+
[:opt, :_],
124+
[:opt, :_],
125+
[:rest, :_],
126+
[:keyreq, :_],
127+
[:key, :_],
128+
[:keyrest, :_],
129+
[:block, :_]
130+
]
131+
132+
lambda = ->(_, _, _ = 1, *_, _:, _: 2, **_, &_) {}
133+
lambda.parameters.should == [
134+
[:req, :_],
135+
[:req, :_],
136+
[:opt, :_],
137+
[:rest, :_],
138+
[:keyreq, :_],
139+
[:key, :_],
140+
[:keyrest, :_],
141+
[:block, :_]
142+
]
143+
end
118144
end

src/main/java/org/truffleruby/language/arguments/ArgumentDescriptorUtils.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,11 @@ private static RubyArray toArray(RubyLanguage language, RubyContext context, Arg
4747
if (argType.anonymous || name == null) {
4848
store = new Object[]{ language.getSymbol(argType.symbolicName) };
4949
} else {
50+
// make sure to normalize parameter names to "_" if they start with "_$"
51+
if (name.startsWith("_$")) {
52+
name = "_";
53+
}
54+
5055
store = new Object[]{ language.getSymbol(argType.symbolicName), language.getSymbol(name) };
5156
}
5257

0 commit comments

Comments
 (0)