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/