Project

General

Profile

Actions

Bug #20808

open

Data#pretty_print doesn't handle private or remove attribute readers

Added by maicolben (Maicol Bentancor) 14 days ago. Updated 14 days ago.

Status:
Open
Assignee:
-
Target version:
-
[ruby-core:119575]

Description

Given the next code:

Dog = Data.define(:name) do
  def inspect
    "Hello!"
  end

  private
  attr_reader :name
end

Dog.new(name: "Fido")

It throws an error:

  • An error occurred when inspecting the object: #<NoMethodError: private method `name' called for an instance of Dog>

And isn't using my inspect function

Updated by byroot (Jean Boussier) 14 days ago

So the problem isn't with inspect, as it only reproduce in irb.

It's coming from pretty_inspect:

>> d.pretty_inspect
/opt/rubies/3.3.5/lib/ruby/3.3.0/pp.rb:432:in `public_send': private method `name' called for an instance of Dog (NoMethodError)

          q.pp public_send(member)
               ^^^^^^^^^^^
	from /opt/rubies/3.3.5/lib/ruby/3.3.0/pp.rb:432:in `block (3 levels) in pretty_print'
	from /opt/rubies/3.3.5/lib/ruby/3.3.0/prettyprint.rb:255:in `block (2 levels) in group'
	from /opt/rubies/3.3.5/lib/ruby/3.3.0/prettyprint.rb:282:in `nest'
	from /opt/rubies/3.3.5/lib/ruby/3.3.0/prettyprint.rb:254:in `block in group'
	from /opt/rubies/3.3.5/lib/ruby/3.3.0/prettyprint.rb:267:in `group_sub'
	from /opt/rubies/3.3.5/lib/ruby/3.3.0/prettyprint.rb:253:in `group'
	from /opt/rubies/3.3.5/lib/ruby/3.3.0/pp.rb:430:in `block (2 levels) in pretty_print'
	from /opt/rubies/3.3.5/lib/ruby/3.3.0/pp.rb:264:in `block in seplist'
	from /opt/rubies/3.3.5/lib/ruby/3.3.0/pp.rb:258:in `each'
	from /opt/rubies/3.3.5/lib/ruby/3.3.0/pp.rb:258:in `seplist'
	from /opt/rubies/3.3.5/lib/ruby/3.3.0/pp.rb:426:in `block in pretty_print'
	from /opt/rubies/3.3.5/lib/ruby/3.3.0/prettyprint.rb:255:in `block (2 levels) in group'
	from /opt/rubies/3.3.5/lib/ruby/3.3.0/prettyprint.rb:282:in `nest'
	from /opt/rubies/3.3.5/lib/ruby/3.3.0/prettyprint.rb:254:in `block in group'
	from /opt/rubies/3.3.5/lib/ruby/3.3.0/prettyprint.rb:267:in `group_sub'
	from /opt/rubies/3.3.5/lib/ruby/3.3.0/prettyprint.rb:253:in `group'

Updated by byroot (Jean Boussier) 14 days ago

The pp implementation for Struct and Data both assume all member readers are public:

class Struct # :nodoc:
  def pretty_print(q) # :nodoc:
    q.group(1, sprintf("#<struct %s", PP.mcall(self, Kernel, :class).name), '>') {
      q.seplist(PP.mcall(self, Struct, :members), lambda { q.text "," }) {|member|
        q.breakable
        q.text member.to_s
        q.text '='
        q.group(1) {
          q.breakable ''
          q.pp self[member]
        }
      }
    }
  end

  def pretty_print_cycle(q) # :nodoc:
    q.text sprintf("#<struct %s:...>", PP.mcall(self, Kernel, :class).name)
  end
end

class Data # :nodoc:
  def pretty_print(q) # :nodoc:
    q.group(1, sprintf("#<data %s", PP.mcall(self, Kernel, :class).name), '>') {
      q.seplist(PP.mcall(self, Data, :members), lambda { q.text "," }) {|member|
        q.breakable
        q.text member.to_s
        q.text '='
        q.group(1) {
          q.breakable ''
          q.pp public_send(member)
        }
      }
    }
  end

  def pretty_print_cycle(q) # :nodoc:
    q.text sprintf("#<data %s:...>", PP.mcall(self, Kernel, :class).name)
  end
end if "3.2" <= RUBY_VERSION

Updated by byroot (Jean Boussier) 14 days ago

Struct and Data both assume all member readers are public:

Actually I misread. The Struct one uses Struct#[] so it would work with Struct. Data however has no such method, so two solutions I can think of are:

  • Use send, but only work for private. If instead the method is renamed or removed, it will still fail.
  • Rescue NoMethodError, and skip displaying that field.

Updated by byroot (Jean Boussier) 14 days ago

cc @akr (Akira Tanaka) , as maintainer of PP perhaps you have an opinion on how this sort of issue should be handled?

Updated by mame (Yusuke Endoh) 14 days ago

The code in question is written by @osyo (manga osyo) and committed by @nobu (Nobuyoshi Nakada). Just FYI.

Actions #6

Updated by byroot (Jean Boussier) 14 days ago

  • Subject changed from Cannot override Data#inspect to Data#pretty_print doesn't handle private or remove attribute readers
Actions

Also available in: Atom PDF

Like0
Like1Like0Like1Like0Like0Like0