From add309c49627b88cb20865dacee8dc17cd0d9525 Mon Sep 17 00:00:00 2001 From: akr Date: Fri, 1 Dec 2017 10:48:29 +0000 Subject: [PATCH] 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 ' # terminated with exception: Traceback (most recent call last): 3: from -e:9:in `block in
' 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 ``` git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@60961 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- lib/pp.rb | 53 +++++++++++++++++++++++++++-------------------------- 1 file changed, 27 insertions(+), 26 deletions(-) diff --git a/lib/pp.rb b/lib/pp.rb index 9acb02f61e..4d5bee5f5d 100644 --- a/lib/pp.rb +++ b/lib/pp.rb @@ -2,32 +2,6 @@ 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 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 +