Project

General

Profile

Actions

Feature #6733

open

New inspect framework

Added by akr (Akira Tanaka) about 10 years ago. Updated 10 months ago.

Status:
Open
Priority:
Normal
Assignee:
-
Target version:
-
[ruby-core:46442]

Description

After we discussed http://bugs.ruby-lang.org/issues/6291 at a developer meeting,
we re-realized new inspect framework may be useful.

Problem:

  • inspect method may generate too long string but sometimes whole string is not required.
    For example, first 70 characters are enough for error messages (backtrace).
  • inspect can't know a encoding to be expected.
  • inspect generates may short strings and discard them immediately.

If we have a new method, inspect_to(buffer), and
it (or overridden method in subclass) adds the inspected result to buffer,
we can solve above problems.
buffer has a method, <<.
It may be a string, IO or other object.

For too long string, buffer itself can throw (or raise) when buffered output is reached to a specified limit.

For encoding, buffer can record an encoding.
(p method creates a buffer object using $stdout's encoding.)

For small strings, in C level, we can create a rb_buffer_add(VALUE buffer, const char *p, long len) and
it don't need to allocate a String object.

This is big change but we can preserve compatibility by following default inspect_to method:

class Object
def inspect_to(buffer)
buffer << self.inspect
end
end

If legacy class which has inspect but not inspect_to,
Object#inspect_to calls inspect and use the result.


Related issues 2 (2 open0 closed)

Related to Ruby master - Feature #6783: Infinite loop in inspect, not overriding inspect, to_s, and no known circular references. Stepping into inspect in debugger locks it up with 100% CPU.OpenActions
Related to Ruby master - Feature #18285: NoMethodError#message uses a lot of CPU/is really expensive to callOpenActions

Updated by Anonymous almost 10 years ago

Thank you so much for this. Whenever I use #inspect and #to_s methods, such as when writing

puts "blah blah #{object} blah"

I cannot help but be afraid that object's #to_s method will return 20MB string, that will overrun something somewhere and take control over my computer :-)

Updated by Anonymous almost 10 years ago

Call me a paranoid, if you want :-)

Actions #3

Updated by shyouhei (Shyouhei Urabe) almost 6 years ago

  • Related to Feature #6783: Infinite loop in inspect, not overriding inspect, to_s, and no known circular references. Stepping into inspect in debugger locks it up with 100% CPU. added
Actions #4

Updated by naruse (Yui NARUSE) almost 2 years ago

  • Target version deleted (3.0)
Actions #5

Updated by mame (Yusuke Endoh) 10 months ago

  • Related to Feature #18285: NoMethodError#message uses a lot of CPU/is really expensive to call added

Updated by mame (Yusuke Endoh) 10 months ago

I like this proposal.

Updated by kou (Kouhei Sutou) 10 months ago

This may be out-of-scope but I hope that this mechanism also supports multimedia like Julia: https://docs.julialang.org/en/v1/base/io-network/#Multimedia-I/O

My use case is showing images on irb automatically.

For example with Red Datasets and Charty:

irb(main):001:0> require "datasets"
=> true
irb(main):002:0> require "charty"
=> true
irb(main):003:0> penguins = Datasets::Penguins.new
=> 
#<Datasets::Penguins:0x00007f308dd34d10                                                         
...                                                                                             
irb(main):004:0> Charty.scatter_plot(data: penguins, x: :body_mass_g, y: :flipper_length_mm, color: :species)
=> #<Charty::Plotters::ScatterPlotter:0x0000000000000424> # Show Sixel images here if the terminal supports Sixel

ref: Sixel

Updated by Eregon (Benoit Daloze) 10 months ago

Should the (remaining) limit (of nb of characters) be passed to inspect_to?
Otherwise if the logic is like creating a long string, and then appending to the buffer, we have the problem that it still takes a long time and might waste a lot of needless computation.

Updated by Dan0042 (Daniel DeLorme) 10 months ago

This sounds like a very powerful and flexible approach, but perhaps a little over-engineered?
Maybe a more KISS approach would be sufficient; just define Object#simple_inspect to be used when we need a short string, like in NoMethodError#message.
By default it can return #<MyClass:0x00007fe40a128ae0> (without ivars).

Updated by mame (Yusuke Endoh) 10 months ago

Eregon (Benoit Daloze) wrote in #note-8:

Should the (remaining) limit (of nb of characters) be passed to inspect_to?
Otherwise if the logic is like creating a long string, and then appending to the buffer, we have the problem that it still takes a long time and might waste a lot of needless computation.

I don't think that your concern will be addressed even if limit is passed. The logic can still create a long string and then truncate it to fit with the limit. inspect_to should append small strings to the buffer, which should be noted as a best practice.

Dan0042 (Daniel DeLorme) wrote in #note-9:

This sounds like a very powerful and flexible approach, but perhaps a little over-engineered?
Maybe a more KISS approach would be sufficient; just define Object#simple_inspect to be used when we need a short string, like in NoMethodError#message.

Indeed this proposal was unearthed in the context of NoMethodError#message (#18285), but the use case is not limited to that.

Actions

Also available in: Atom PDF