[ruby-core:119575] [Ruby master Bug#20808] Cannot override Data#inspect

Issue #20808 has been reported by maicolben (Maicol Bentancor). ---------------------------------------- Bug #20808: Cannot override Data#inspect https://bugs.ruby-lang.org/issues/20808 * Author: maicolben (Maicol Bentancor) * Status: Open * ruby -v: 3.3.5 * Backport: 3.1: UNKNOWN, 3.2: UNKNOWN, 3.3: UNKNOWN ---------------------------------------- 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 -- https://bugs.ruby-lang.org/

Issue #20808 has been updated by byroot (Jean Boussier). 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' ``` ---------------------------------------- Bug #20808: Cannot override Data#inspect https://bugs.ruby-lang.org/issues/20808#change-110195 * Author: maicolben (Maicol Bentancor) * Status: Open * ruby -v: 3.3.5 * Backport: 3.1: UNKNOWN, 3.2: UNKNOWN, 3.3: UNKNOWN ---------------------------------------- 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 -- https://bugs.ruby-lang.org/

Issue #20808 has been updated by byroot (Jean Boussier). The `pp` implementation for `Struct` and `Data` both assume all member readers are public: ```ruby 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 ``` ---------------------------------------- Bug #20808: Cannot override Data#inspect https://bugs.ruby-lang.org/issues/20808#change-110196 * Author: maicolben (Maicol Bentancor) * Status: Open * ruby -v: 3.3.5 * Backport: 3.1: UNKNOWN, 3.2: UNKNOWN, 3.3: UNKNOWN ---------------------------------------- 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 -- https://bugs.ruby-lang.org/

Issue #20808 has been updated by byroot (Jean Boussier).
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. ---------------------------------------- Bug #20808: Cannot override Data#inspect https://bugs.ruby-lang.org/issues/20808#change-110197 * Author: maicolben (Maicol Bentancor) * Status: Open * ruby -v: 3.3.5 * Backport: 3.1: UNKNOWN, 3.2: UNKNOWN, 3.3: UNKNOWN ---------------------------------------- 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 -- https://bugs.ruby-lang.org/

Issue #20808 has been updated by byroot (Jean Boussier). cc @akr , as maintainer of PP perhaps you have an opinion on how this sort of issue should be handled? ---------------------------------------- Bug #20808: Cannot override Data#inspect https://bugs.ruby-lang.org/issues/20808#change-110198 * Author: maicolben (Maicol Bentancor) * Status: Open * ruby -v: 3.3.5 * Backport: 3.1: UNKNOWN, 3.2: UNKNOWN, 3.3: UNKNOWN ---------------------------------------- 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 -- https://bugs.ruby-lang.org/

Issue #20808 has been updated by mame (Yusuke Endoh). The code in question is written by @osyo and committed by @nobu. Just FYI. ---------------------------------------- Bug #20808: Cannot override Data#inspect https://bugs.ruby-lang.org/issues/20808#change-110201 * Author: maicolben (Maicol Bentancor) * Status: Open * ruby -v: 3.3.5 * Backport: 3.1: UNKNOWN, 3.2: UNKNOWN, 3.3: UNKNOWN ---------------------------------------- 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 -- https://bugs.ruby-lang.org/

Issue #20808 has been updated by mame (Yusuke Endoh). Discussed the dev meeting. @akr said using `__send__` instead of `public_send` would be good. ---------------------------------------- Bug #20808: Data#pretty_print doesn't handle private or remove attribute readers https://bugs.ruby-lang.org/issues/20808#change-110489 * Author: maicolben (Maicol Bentancor) * Status: Open * ruby -v: 3.3.5 * Backport: 3.1: UNKNOWN, 3.2: UNKNOWN, 3.3: UNKNOWN ---------------------------------------- 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 -- https://bugs.ruby-lang.org/

Issue #20808 has been updated by byroot (Jean Boussier). Proposed patch: https://github.com/ruby/pp/pull/29 ---------------------------------------- Bug #20808: Data#pretty_print doesn't handle private or remove attribute readers https://bugs.ruby-lang.org/issues/20808#change-110494 * Author: maicolben (Maicol Bentancor) * Status: Open * ruby -v: 3.3.5 * Backport: 3.1: UNKNOWN, 3.2: UNKNOWN, 3.3: UNKNOWN ---------------------------------------- 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 -- https://bugs.ruby-lang.org/
participants (3)
-
byroot (Jean Boussier)
-
maicolben (Maicol Bentancor)
-
mame (Yusuke Endoh)