Skip to content

Object#pp changes visibility upon requiring 'pp' #5599

@p-mongo

Description

@p-mongo

Environment

jruby 9.2.5.0 is affected
jruby 9.1.17.0 is not affected

Linux tk.bsdpower.com 4.13.0-1-amd64 #1 SMP Debian 4.13.4-2 (2017-10-15) x86_64 GNU/Linux

Debian testing

Expected Behavior

Object#pp should have the same visibility regardless of whether 'pp' is required.

Actual Behavior

tk% irb
irb(main):001:0> Object.new.pp 'hai'
"hai"
=> "hai"
irb(main):002:0> require 'pp'
=> false
irb(main):003:0> Object.new.pp 'hai'
Traceback (most recent call last):
        6: from /home/mpush/.rbenv/versions/jruby-9.2.5.0/bin/irb:13:in `'
        5: from org/jruby/RubyKernel.java:1181:in `catch'
        4: from org/jruby/RubyKernel.java:1181:in `catch'
        3: from org/jruby/RubyKernel.java:1415:in `loop'
        2: from org/jruby/RubyKernel.java:1046:in `eval'
        1: from (irb):3:in `evaluate'
NoMethodError (private method `pp' called for #)

This is creating an issue for our test suite because we test that forwarding methods works. When the tests are defined, 'pp' is not required and pp is included in Object (or Array in our case) public methods. Subsequently we have a test which is marked in RSpec via pending. This prints the expected/actual mismatch since we use an instafailing formatter, which in turn issues require 'pp'. Once 'pp' is required, Object#pp's visibility changes to private. Some time later the test which verifies forwarding of all methods, including used-to-be-public pp, runs, and is unable to forward pp because pp is now private.

This issue also affects MRI 2.5.1 though curiously neither 2.4 nor 2.6.

On jruby 9.1.17.0:

tk% rbenv shell jruby-9.1.17.0 
tk% irb
irb(main):001:0> Object.new.pp 'hai'
NoMethodError: undefined method `pp' for #
Did you mean?  p
	from (irb):1:in `'
	from org/jruby/RubyKernel.java:995:in `eval'
	from org/jruby/RubyKernel.java:1316:in `loop'
	from org/jruby/RubyKernel.java:1138:in `catch'
	from org/jruby/RubyKernel.java:1138:in `catch'
	from /home/mpush/.rbenv/versions/jruby-9.1.17.0/bin/irb:13:in `'
irb(main):002:0> require 'pp'
=> true
irb(main):003:0> Object.new.pp 'hai'
NoMethodError: private method `pp' called for #
Did you mean?  p
	from (irb):3:in `'
	from org/jruby/RubyKernel.java:995:in `eval'
	from org/jruby/RubyKernel.java:1316:in `loop'
	from org/jruby/RubyKernel.java:1138:in `catch'
	from org/jruby/RubyKernel.java:1138:in `catch'
	from /home/mpush/.rbenv/versions/jruby-9.1.17.0/bin/irb:13:in `'

pp was initially not defined, and is thus not included in the list of public methods. Upon require of 'pp' pp is defined but is private.

Looks like MRI 2.6 fixed this by having pp always be private:

tk% rbenv shell 2.6.0
tk% irb
irb(main):001:0> [].pp 'hai'
Traceback (most recent call last):
        4: from /home/mpush/.rbenv/versions/2.6.0/bin/irb:23:in `'
        3: from /home/mpush/.rbenv/versions/2.6.0/bin/irb:23:in `load'
        2: from /big/home/mpush/.rbenv/versions/2.6.0/lib/ruby/gems/2.6.0/gems/irb-1.0.0/exe/irb:11:in `'
        1: from (irb):1
NoMethodError (private method `pp' called for []:Array)
irb(main):002:0> require 'pp'
=> true
irb(main):003:0> [].pp 'hai'
Traceback (most recent call last):
        4: from /home/mpush/.rbenv/versions/2.6.0/bin/irb:23:in `'
        3: from /home/mpush/.rbenv/versions/2.6.0/bin/irb:23:in `load'
        2: from /big/home/mpush/.rbenv/versions/2.6.0/lib/ruby/gems/2.6.0/gems/irb-1.0.0/exe/irb:11:in `'
        1: from (irb):3
NoMethodError (private method `pp' called for []:Array)

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions