Skip to content

Commit

Permalink
Add lambda keyword argument to Proc#parameters
Browse files Browse the repository at this point in the history
Co-authored-by: Jose Narvaez <jose.narvaez@shopify.com>
  • Loading branch information
thomasmarshall and goyox86 committed Feb 2, 2024
1 parent 90bfaa0 commit d9469bf
Show file tree
Hide file tree
Showing 5 changed files with 21 additions and 9 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ Compatibility:
* Do not autosplat a proc that accepts a single positional argument and keywords (#3039, @andrykonchin).
* Support passing anonymous * and ** parameters as method call arguments (#3039, @andrykonchin).
* Handle either positional or keywords arguments by default in `Struct.new` (#3039, @rwstauner).
* Support `lambda` argument in `Proc#parameters` (#3039, @thomasmarshall, @goyox86).

Performance:

Expand Down
10 changes: 10 additions & 0 deletions spec/ruby/core/proc/parameters_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,16 @@
it "regards named parameters in lambda as optional if lambda: false keyword used" do
-> x { }.parameters(lambda: false).first.first.should == :opt
end

it "regards named parameters in procs and lambdas as required if lambda keyword is truthy" do
proc {|x| }.parameters(lambda: 123).first.first.should == :req
-> x { }.parameters(lambda: 123).first.first.should == :req
end

it "ignores the lambda keyword if it is nil" do
proc {|x|}.parameters(lambda: nil).first.first.should == :opt
-> x { }.parameters(lambda: nil).first.first.should == :req
end
end

it "regards optional keyword parameters in procs as optional" do
Expand Down
3 changes: 0 additions & 3 deletions spec/tags/core/proc/parameters_tags.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,3 @@
fails:Proc#parameters sets the first element of each sub-Array to :req for required argument if lambda keyword used
fails:Proc#parameters regards named parameters in procs as required if lambda keyword used
fails:Proc#parameters regards named parameters in lambda as optional if lambda: false keyword used
fails:Proc#parameters adds rest arg with name * for "star" argument
fails:Proc#parameters adds keyrest arg with ** as a name for "double star" argument
fails:Proc#parameters adds block arg with name & for anonymous block argument
12 changes: 6 additions & 6 deletions src/main/java/org/truffleruby/core/proc/ProcNodes.java
Original file line number Diff line number Diff line change
Expand Up @@ -203,18 +203,18 @@ boolean lambda(RubyProc proc) {

}

@CoreMethod(names = "parameters")
public abstract static class ParametersNode extends CoreMethodArrayArgumentsNode {
@Primitive(name = "proc_parameters")
public abstract static class ParametersNode extends PrimitiveArrayArgumentsNode {

@TruffleBoundary
@Specialization
RubyArray parameters(RubyProc proc) {
RubyArray parameters(RubyProc proc, Object lambdaObject) {
final ArgumentDescriptor[] argsDesc = proc.getArgumentDescriptors();
final boolean isLambda = proc.type == ProcType.LAMBDA;
final boolean isLambda = (lambdaObject == nil)
? proc.type == ProcType.LAMBDA
: !lambdaObject.equals(Boolean.FALSE);
return ArgumentDescriptorUtils
.argumentDescriptorsToParameters(getLanguage(), getContext(), argsDesc, isLambda);
}

}

@CoreMethod(names = "source_location")
Expand Down
4 changes: 4 additions & 0 deletions src/main/ruby/truffleruby/core/proc.rb
Original file line number Diff line number Diff line change
Expand Up @@ -128,4 +128,8 @@ def <<(other)
end
end
end

def parameters(lambda: nil)
Primitive.proc_parameters(self, lambda)
end
end

0 comments on commit d9469bf

Please sign in to comment.