[前][次][番号順一覧][スレッド一覧]

ruby-changes:59614

From: Jeremy <ko1@a...>
Date: Sat, 4 Jan 2020 13:13:40 +0900 (JST)
Subject: [ruby-changes:59614] 0eeed5bcc5 (master): Make eval(code, binding) use (eval) as __FILE__ and 1 as __LINE__

https://git.ruby-lang.org/ruby.git/commit/?id=0eeed5bcc5

From 0eeed5bcc5530edb0af2af2ccff09d067c59e8f9 Mon Sep 17 00:00:00 2001
From: Jeremy Evans <code@j...>
Date: Tue, 30 Jul 2019 16:15:19 -0700
Subject: Make eval(code, binding) use (eval) as __FILE__ and 1 as __LINE__

This removes the warning that was added in
3802fb92ff8c83eed3e867db20f72c53932f542d, and switches the behavior
so that the eval does not use the binding's __FILE__ and __LINE__
implicitly.

Fixes [Bug #4352]

diff --git a/parse.y b/parse.y
index 5f7884b..75cd097 100644
--- a/parse.y
+++ b/parse.y
@@ -315,7 +315,6 @@ struct parser_params { https://github.com/ruby/ruby/blob/trunk/parse.y#L315
     unsigned int do_loop: 1;
     unsigned int do_chomp: 1;
     unsigned int do_split: 1;
-    unsigned int warn_location: 1;
 
     NODE *eval_tree_begin;
     NODE *eval_tree;
@@ -9917,19 +9916,6 @@ past_dvar_p(struct parser_params *p, ID id) https://github.com/ruby/ruby/blob/trunk/parse.y#L9916
 }
 # endif
 
-/* As Ripper#warn does not have arguments for the location, so the
- * following messages cannot be separated */
-#define WARN_LOCATION(type) do { \
-    if (p->warn_location) { \
-	int line; \
-	VALUE file = rb_source_location(&line); \
-	rb_warn3(type" in eval may not return location in binding;" \
-		 " use Binding#source_location instead\n" \
-		 "%"PRIsWARN":%d: warning: in `%"PRIsWARN"'", \
-		 file, WARN_I(line), rb_id2str(rb_frame_this_func())); \
-    } \
-} while (0)
-
 static int
 numparam_nested_p(struct parser_params *p)
 {
@@ -9963,7 +9949,6 @@ gettable(struct parser_params *p, ID id, const YYLTYPE *loc) https://github.com/ruby/ruby/blob/trunk/parse.y#L9949
       case keyword_false:
 	return NEW_FALSE(loc);
       case keyword__FILE__:
-	WARN_LOCATION("__FILE__");
 	{
 	    VALUE file = p->ruby_sourcefile_string;
 	    if (NIL_P(file))
@@ -9975,7 +9960,6 @@ gettable(struct parser_params *p, ID id, const YYLTYPE *loc) https://github.com/ruby/ruby/blob/trunk/parse.y#L9960
 	}
 	return node;
       case keyword__LINE__:
-	WARN_LOCATION("__LINE__");
 	return NEW_LIT(INT2FIX(p->tokline), loc);
       case keyword__ENCODING__:
         node = NEW_LIT(rb_enc_from_encoding(p->enc), loc);
@@ -12248,14 +12232,6 @@ rb_parser_set_options(VALUE vparser, int print, int loop, int chomp, int split) https://github.com/ruby/ruby/blob/trunk/parse.y#L12232
     p->do_split = split;
 }
 
-void
-rb_parser_warn_location(VALUE vparser, int warn)
-{
-    struct parser_params *p;
-    TypedData_Get_Struct(vparser, struct parser_params, &parser_data_type, p);
-    p->warn_location = warn;
-}
-
 static NODE *
 parser_append_options(struct parser_params *p, NODE *node)
 {
diff --git a/spec/ruby/core/binding/eval_spec.rb b/spec/ruby/core/binding/eval_spec.rb
index fff8c9c..84096f8 100644
--- a/spec/ruby/core/binding/eval_spec.rb
+++ b/spec/ruby/core/binding/eval_spec.rb
@@ -23,29 +23,58 @@ describe "Binding#eval" do https://github.com/ruby/ruby/blob/trunk/spec/ruby/core/binding/eval_spec.rb#L23
     bind2.local_variables.should == []
   end
 
-  it "inherits __LINE__ from the enclosing scope" do
-    obj = BindingSpecs::Demo.new(1)
-    bind = obj.get_binding
-    suppress_warning {bind.eval("__LINE__")}.should == obj.get_line_of_binding
-  end
+  ruby_version_is ""..."2.8" do
+    it "inherits __LINE__ from the enclosing scope" do
+      obj = BindingSpecs::Demo.new(1)
+      bind = obj.get_binding
+      suppress_warning {bind.eval("__LINE__")}.should == obj.get_line_of_binding
+    end
 
-  it "preserves __LINE__ across multiple calls to eval" do
-    obj = BindingSpecs::Demo.new(1)
-    bind = obj.get_binding
-    suppress_warning {bind.eval("__LINE__")}.should == obj.get_line_of_binding
-    suppress_warning {bind.eval("__LINE__")}.should == obj.get_line_of_binding
-  end
+    it "preserves __LINE__ across multiple calls to eval" do
+      obj = BindingSpecs::Demo.new(1)
+      bind = obj.get_binding
+      suppress_warning {bind.eval("__LINE__")}.should == obj.get_line_of_binding
+      suppress_warning {bind.eval("__LINE__")}.should == obj.get_line_of_binding
+    end
 
-  it "increments __LINE__ on each line of a multiline eval" do
-    obj = BindingSpecs::Demo.new(1)
-    bind = obj.get_binding
-    suppress_warning {bind.eval("#foo\n__LINE__")}.should == obj.get_line_of_binding + 1
+    it "increments __LINE__ on each line of a multiline eval" do
+      obj = BindingSpecs::Demo.new(1)
+      bind = obj.get_binding
+      suppress_warning {bind.eval("#foo\n__LINE__")}.should == obj.get_line_of_binding + 1
+    end
+
+    it "inherits __LINE__ from the enclosing scope even if the Binding is created with #send" do
+      obj = BindingSpecs::Demo.new(1)
+      bind, line = obj.get_binding_with_send_and_line
+      suppress_warning {bind.eval("__LINE__")}.should == line
+    end
   end
 
-  it "inherits __LINE__ from the enclosing scope even if the Binding is created with #send" do
-    obj = BindingSpecs::Demo.new(1)
-    bind, line = obj.get_binding_with_send_and_line
-    suppress_warning {bind.eval("__LINE__")}.should == line
+  ruby_version_is "2.8" do
+    it "starts with line 1 if single argument is given" do
+      obj = BindingSpecs::Demo.new(1)
+      bind = obj.get_binding
+      bind.eval("__LINE__").should == 1
+    end
+
+    it "preserves __LINE__ across multiple calls to eval" do
+      obj = BindingSpecs::Demo.new(1)
+      bind = obj.get_binding
+      bind.eval("__LINE__").should == 1
+      bind.eval("__LINE__").should == 1
+    end
+
+    it "increments __LINE__ on each line of a multiline eval" do
+      obj = BindingSpecs::Demo.new(1)
+      bind = obj.get_binding
+      bind.eval("#foo\n__LINE__").should == 2
+    end
+
+    it "starts with line 1 if the Binding is created with #send" do
+      obj = BindingSpecs::Demo.new(1)
+      bind, line = obj.get_binding_with_send_and_line
+      bind.eval("__LINE__").should == 1
+    end
   end
 
   it "starts with a __LINE__ of 1 if a filename is passed" do
@@ -60,10 +89,20 @@ describe "Binding#eval" do https://github.com/ruby/ruby/blob/trunk/spec/ruby/core/binding/eval_spec.rb#L89
     bind.eval("#foo\n__LINE__", "(test)", 88).should == 89
   end
 
-  it "inherits __FILE__ from the enclosing scope" do
-    obj = BindingSpecs::Demo.new(1)
-    bind = obj.get_binding
-    suppress_warning {bind.eval("__FILE__")}.should == obj.get_file_of_binding
+  ruby_version_is ""..."2.8" do
+    it "inherits __FILE__ from the enclosing scope" do
+      obj = BindingSpecs::Demo.new(1)
+      bind = obj.get_binding
+      suppress_warning {bind.eval("__FILE__")}.should == obj.get_file_of_binding
+    end
+  end
+
+  ruby_version_is "2.8" do
+    it "Uses (eval) as __FILE__ if single argument given" do
+      obj = BindingSpecs::Demo.new(1)
+      bind = obj.get_binding
+      bind.eval("__FILE__").should == '(eval)'
+    end
   end
 
   it "uses the __FILE__ that is passed in" do
diff --git a/spec/ruby/core/kernel/__dir___spec.rb b/spec/ruby/core/kernel/__dir___spec.rb
index 3c34277..e2bcc6e 100644
--- a/spec/ruby/core/kernel/__dir___spec.rb
+++ b/spec/ruby/core/kernel/__dir___spec.rb
@@ -12,9 +12,19 @@ describe "Kernel#__dir__" do https://github.com/ruby/ruby/blob/trunk/spec/ruby/core/kernel/__dir___spec.rb#L12
     end
   end
 
-  context "when used in eval with top level binding" do
-    it "returns the real name of the directory containing the currently-executing file" do
-      eval("__dir__", binding).should == File.realpath(File.dirname(__FILE__))
+  ruby_version_is ""..."2.7" do
+    context "when used in eval with top level binding" do
+      it "returns the real name of the directory containing the currently-executing file" do
+        eval("__dir__", binding).should == File.realpath(File.dirname(__FILE__))
+      end
+    end
+  end
+
+  ruby_version_is "2.7" do
+    context "when used in eval with top level binding" do
+      it "returns nil" do
+        eval("__dir__", binding).should == nil
+      end
     end
   end
 end
diff --git a/spec/ruby/core/kernel/eval_spec.rb b/spec/ruby/core/kernel/eval_spec.rb
index 340ba23..09ccb9d 100644
--- a/spec/ruby/core/kernel/eval_spec.rb
+++ b/spec/ruby/core/kernel/eval_spec.rb
@@ -159,13 +159,27 @@ describe "Kernel#eval" do https://github.com/ruby/ruby/blob/trunk/spec/ruby/core/kernel/eval_spec.rb#L159
     end
   end
 
-  it "uses the filename of the binding if none is provided" do
-    eval("__FILE__").should == "(eval)"
-    suppress_warning {eval("__FILE__", binding)}.should == __FILE__
-    eval("__FILE__", binding, "success").should == "success"
-    suppress_warning {eval("eval '__FILE__', binding")}.should == "(eval)"
-    suppress_warning {eval("eval '__FILE__', binding", binding)}.should == __FILE__
-    suppress_warning {eval("eval '__FILE__', binding", binding, 'success')}.should == 'success'
+  ruby_version_is ""..."2.8" do
+    it "uses the filename of the binding if none is provided" do
+      eval("__FILE__").should == "(eval)"
+      suppress_warning {eval("__FILE__", binding)}.should == __FILE__
+      eval("__FILE__", binding, "success").should == "success"
+      suppress_warning {eval("eval '__FILE__', binding")}.should == "(eval)"
+      suppress_warning {eval("eval '__FILE__', binding", binding)}.should == __FILE__
+      suppress_warning {eval("eval '__FILE__', binding", binding, 'success')}.should == 'success'
+    end
+  end
+
+  ruby_version_is "2.8" do
+    it "uses (eval) filename if none is provided" do
+      eval("__FILE__").should == "(eval)"
+      eval("__FILE__", binding).should == "(eval)"
+      eval("__FILE__", binding, "success").should == "success"
+      eval("eval '__FILE__', binding").should == "(eval)"
+      eval("eval '__FILE__', binding", binding).should == "(eval)"
+      eval("eval '__FILE__', binding", binding, 'success').should == '(eval)'
+      eval("eval '__FILE__', binding, 'success'", binding).should == 'success'
+    end
   end
 
   # Found via Rubinius bug github:#149
diff --git a/test/ruby/test_eval.rb b/test/ruby/test_eval.rb
index 3d6116 (... truncated)

--
ML: ruby-changes@q...
Info: http://www.atdot.net/~ko1/quickml/

[前][次][番号順一覧][スレッド一覧]