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

ruby-changes:49294

From: nobu <ko1@a...>
Date: Fri, 22 Dec 2017 17:08:36 +0900 (JST)
Subject: [ruby-changes:49294] nobu:r61411 (trunk): erb.rb: shadow by keys

nobu	2017-12-22 17:08:31 +0900 (Fri, 22 Dec 2017)

  New Revision: 61411

  https://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=revision&revision=61411

  Log:
    erb.rb: shadow by keys
    
    * lib/erb.rb (ERB#new_toplevel): shadow already defined local
      variables by block local variabes, not to overwrite them.
      [ruby-core:84390] [Bug #14215]

  Modified files:
    trunk/lib/erb.rb
    trunk/test/erb/test_erb.rb
Index: test/erb/test_erb.rb
===================================================================
--- test/erb/test_erb.rb	(revision 61410)
+++ test/erb/test_erb.rb	(revision 61411)
@@ -611,6 +611,10 @@ EOS https://github.com/ruby/ruby/blob/trunk/test/erb/test_erb.rb#L611
     erb = @erb.new("<%= foo %>")
     erb.result_with_hash(foo: "1")
     assert_equal(false, TOPLEVEL_BINDING.local_variable_defined?(:foo))
+    TOPLEVEL_BINDING.eval 'template2 = "two"'
+    erb = @erb.new("<%= template2 %>")
+    erb.result_with_hash(template2: "TWO")
+    assert_equal "two", TOPLEVEL_BINDING.local_variable_get("template2")
   end
 
   # This depends on the behavior that #local_variable_set raises TypeError by invalid key.
Index: lib/erb.rb
===================================================================
--- lib/erb.rb	(revision 61410)
+++ lib/erb.rb	(revision 61411)
@@ -889,7 +889,7 @@ class ERB https://github.com/ruby/ruby/blob/trunk/lib/erb.rb#L889
   # Render a template on a new toplevel binding with local variables specified
   # by a Hash object.
   def result_with_hash(hash)
-    b = new_toplevel
+    b = new_toplevel(hash.keys)
     hash.each_pair do |key, value|
       b.local_variable_set(key, value)
     end
@@ -900,8 +900,15 @@ class ERB https://github.com/ruby/ruby/blob/trunk/lib/erb.rb#L900
   # Returns a new binding each time *near* TOPLEVEL_BINDING for runs that do
   # not specify a binding.
 
-  def new_toplevel
-    TOPLEVEL_BINDING.dup
+  def new_toplevel(vars = nil)
+    b = TOPLEVEL_BINDING
+    if vars
+      vars = vars.select {|v| b.local_variable_defined?(v)}
+      unless vars.empty?
+        return b.eval("tap {|;#{vars.join(',')}| break binding}")
+      end
+    end
+    b.dup
   end
   private :new_toplevel
 

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

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