diff options
author | akr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2017-12-01 10:48:29 +0000 |
---|---|---|
committer | akr <akr@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> | 2017-12-01 10:48:29 +0000 |
commit | 1980347d02b2d1d43e7051641be3396bdf32d7b3 (patch) | |
tree | e437cae92230676b1524f6d279ca7be2a86267d1 /lib | |
parent | 278dfd2289e2445a7ab286cb8921f31c1841fcad (diff) | |
download | ruby-1980347d02b2d1d43e7051641be3396bdf32d7b3.tar.gz |
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
```
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@60961 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
Diffstat (limited to 'lib')
-rw-r--r-- | lib/pp.rb | 53 |
1 files changed, 27 insertions, 26 deletions
@@ -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 + |