From d9f7f6d281658732de35b00de51a51c95784b334 Mon Sep 17 00:00:00 2001 From: Herwin Date: Fri, 22 Nov 2024 11:46:44 +0100 Subject: [PATCH 1/2] Refresh block specs --- spec/language/block_spec.rb | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/spec/language/block_spec.rb b/spec/language/block_spec.rb index 6248a89338..ca5fe1395e 100644 --- a/spec/language/block_spec.rb +++ b/spec/language/block_spec.rb @@ -981,24 +981,27 @@ def obj.to_ary; raise "Exception raised in #to_ary" end # NATFIXME: circular argument reference - a describe "with a circular argument reference" do - xit "raises a SyntaxError if using an existing local with the same name as the argument" do - #a = 1 - #-> { - #@proc = eval "proc { |a=a| a }" - #}.should raise_error(SyntaxError) + ruby_version_is ""..."3.4" do + xit "raises a SyntaxError if using the argument in its default value" do + #a = 1 + #-> { + #eval "proc { |a=a| a }" + #}.should raise_error(SyntaxError) + end end - xit "raises a SyntaxError if there is an existing method with the same name as the argument" do - #def a; 1; end - #-> { - #@proc = eval "proc { |a=a| a }" - #}.should raise_error(SyntaxError) + ruby_version_is "3.4" do + xit "is nil if using the argument in its default value" do + #-> { + #eval "proc { |a=a| a }.call" + #}.call.should == nil + end end + end - it "calls an existing method with the same name as the argument if explicitly using ()" do - def a; 1; end - proc { |a=a()| a }.call.should == 1 - end + it "calls an existing method with the same name as the argument if explicitly using ()" do + def a; 1; end + proc { |a=a()| a }.call.should == 1 end end From 48d2a17c30e1190f04ed524d0f0c9431d19d6179 Mon Sep 17 00:00:00 2001 From: Herwin Date: Fri, 22 Nov 2024 11:42:29 +0100 Subject: [PATCH 2/2] Fix behaviour for circular arguments Implement the Ruby 3.4 behaviour instead of 3.3, this is easier and more future proof. The spec has a small extra check to restore the NATFIXME blocks once we've fully switched to Ruby 3.4 compatibility. --- lib/natalie/compiler/args.rb | 2 +- spec/language/block_spec.rb | 29 +++++++++++++++++++---------- test/natalie/method_test.rb | 4 ++-- 3 files changed, 22 insertions(+), 13 deletions(-) diff --git a/lib/natalie/compiler/args.rb b/lib/natalie/compiler/args.rb index aee4fe002e..108b1252a9 100644 --- a/lib/natalie/compiler/args.rb +++ b/lib/natalie/compiler/args.rb @@ -168,7 +168,7 @@ def transform_optional_arg(arg) default_value = arg.value if default_value&.type == :local_variable_read_node && default_value.name == name - raise SyntaxError, "circular argument reference - #{name}" + default_value = Prism.nil_node(location: default_value.location) end @instructions << ArrayIsEmptyInstruction.new diff --git a/spec/language/block_spec.rb b/spec/language/block_spec.rb index ca5fe1395e..9585acb945 100644 --- a/spec/language/block_spec.rb +++ b/spec/language/block_spec.rb @@ -979,22 +979,31 @@ def obj.to_ary; raise "Exception raised in #to_ary" end end.call(2, 3).should == [2, 6, [], 3] end - # NATFIXME: circular argument reference - a describe "with a circular argument reference" do ruby_version_is ""..."3.4" do - xit "raises a SyntaxError if using the argument in its default value" do - #a = 1 - #-> { - #eval "proc { |a=a| a }" - #}.should raise_error(SyntaxError) + it "raises a SyntaxError if using the argument in its default value" do + NATFIXME 'We implement the Ruby 3.4 behaviour' do + a = 1 + -> { + eval "proc { |a=a| a }" + }.should raise_error(SyntaxError) + end + + NATFIXME "Restore this part of the spec once we've moved to Ruby 3.4 compatibility" do + RUBY_VERSION.should.start_with?('3.4.') + end + + -> { + eval "proc { |a=a| a }.call" + }.call.should == nil end end ruby_version_is "3.4" do - xit "is nil if using the argument in its default value" do - #-> { - #eval "proc { |a=a| a }.call" - #}.call.should == nil + it "is nil if using the argument in its default value" do + -> { + eval "proc { |a=a| a }.call" + }.call.should == nil end end end diff --git a/test/natalie/method_test.rb b/test/natalie/method_test.rb index d90b78e8c7..a18a3717ad 100644 --- a/test/natalie/method_test.rb +++ b/test/natalie/method_test.rb @@ -201,8 +201,8 @@ def yield_to_block(&b) default_nils.should == [nil, nil] default_nils(1).should == [1, nil] default_nils(1, 2).should == [1, 2] - out = `bin/natalie -e "def circular_argument_reference(a = a); a; end" 2>&1` - out.should =~ /parameter default value references itself|circular argument reference - a/ + out = `bin/natalie -e "def circular_argument_reference(a = a); p a; end; circular_argument_reference" 2>&1` + out.should =~ /^nil$/ end def default_first1(x = 1)