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

ruby-changes:48844

From: akr <ko1@a...>
Date: Fri, 1 Dec 2017 19:48:34 +0900 (JST)
Subject: [ruby-changes:48844] akr:r60961 (trunk): Replace Kernel#pp after PP class is defined.

akr	2017-12-01 19:48:29 +0900 (Fri, 01 Dec 2017)

  New Revision: 60961

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

  Log:
    Replace Kernel#pp after PP class is defined.
    
    Avoid a race condition which a context switch
    occur after replacing Kernel#pp but before
    defining PP class.
    
    Following patch, inserting sleep, makes
    this problem reproducible.
    
    ```
    Index: lib/pp.rb
    ===================================================================
    --- lib/pp.rb	(revision 60960)
    +++ lib/pp.rb	(working copy)
    @@ -26,6 +26,7 @@ module Kernel
       end
       undef __pp_backup__ if method_defined?(:__pp_backup__)
       module_function :pp
    +  sleep 1 # thread context switch
     end
     
     ##
    ```
    
    With the above patch, "uninitialized constant Kernel::PP" can
    happen as as follows.
    
    ```
    % ./ruby -w -Ilib -e '
    t1 = Thread.new {
      Thread.current.report_on_exception = true
      pp :foo1
    }
    t2 = Thread.new {
      Thread.current.report_on_exception = true
      sleep 0.5
      pp :foo2
    }
    t1.join rescue nil
    t2.join rescue nil
    '
    #<Thread:0x000055dbf926eaa0@-e:6 run> terminated with exception:
    Traceback (most recent call last):
    3: from -e:9:in `block in <main>'
    2: from /home/ruby/tst2/ruby/lib/pp.rb:22:in `pp'
    1: from /home/ruby/tst2/ruby/lib/pp.rb:22:in `each'
    /home/ruby/tst2/ruby/lib/pp.rb:23:in `block in pp': uninitialized constant Kernel::PP (NameError)
    :foo1
    ```

  Modified files:
    trunk/lib/pp.rb
Index: lib/pp.rb
===================================================================
--- lib/pp.rb	(revision 60960)
+++ lib/pp.rb	(revision 60961)
@@ -2,32 +2,6 @@ https://github.com/ruby/ruby/blob/trunk/lib/pp.rb#L2
 
 require 'prettyprint'
 
-module Kernel
-  # Returns a pretty printed object as a string.
-  #
-  # In order to use this method you must first require the PP module:
-  #
-  #   require 'pp'
-  #
-  # See the PP module for more information.
-  def pretty_inspect
-    PP.pp(self, ''.dup)
-  end
-
-  # prints arguments in pretty form.
-  #
-  # pp returns argument(s).
-  alias __pp_backup__ pp if method_defined?(:pp)
-  def pp(*objs)
-    objs.each {|obj|
-      PP.pp(obj)
-    }
-    objs.size <= 1 ? objs.first : objs
-  end
-  undef __pp_backup__ if method_defined?(:__pp_backup__)
-  module_function :pp
-end
-
 ##
 # A pretty-printer for Ruby objects.
 #
@@ -562,3 +536,30 @@ end https://github.com/ruby/ruby/blob/trunk/lib/pp.rb#L536
     end
   }
 }
+
+module Kernel
+  # Returns a pretty printed object as a string.
+  #
+  # In order to use this method you must first require the PP module:
+  #
+  #   require 'pp'
+  #
+  # See the PP module for more information.
+  def pretty_inspect
+    PP.pp(self, ''.dup)
+  end
+
+  # prints arguments in pretty form.
+  #
+  # pp returns argument(s).
+  alias __pp_backup__ pp if method_defined?(:pp)
+  def pp(*objs)
+    objs.each {|obj|
+      PP.pp(obj)
+    }
+    objs.size <= 1 ? objs.first : objs
+  end
+  undef __pp_backup__ if method_defined?(:__pp_backup__)
+  module_function :pp
+end
+

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

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