evolution
evolution

Reputation: 4722

pry inspect method not working

I have the following code from understanding computation book. The intention is to change the inspect behavior.

class Number < Struct.new(:value)
  def inspect
    "<<#{self}>>"
  end
  def to_s
    value.to_s
  end
end

It works as expected when I use irb:

irb(main):014:0> Number.new(1)
=> <<1>>

but it does not when I use pry:

[8] pry(main)> n = Number.new(1)
=> #<struct Number value=1>

The Pry is version 0.10.3 on Ruby 2.0.0. Why does it not work?

Upvotes: 3

Views: 764

Answers (3)

johansenja
johansenja

Reputation: 678

Sawa is right in that Pry uses its own printer, but if you look closer at the source you can see that it actually uses Ruby's PP behind the scenes, and PP defines its own behaviour for pretty printing Structs:

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

It's worth checking out the documentation (though it is only brief) if you are interested in learning more about this.

So in your struct you could also define your own pretty_print and pretty_print_cycle methods, which would mean Pry could print these how you want, without having to override their DEFAULT_PRINT proc.

Upvotes: 1

sashaegorov
sashaegorov

Reputation: 1862

I use Pry version 0.10.4.

I've just added the following lines in my .pryrc file (I think, that is a good place for such code):

if defined?(BigDecimal)
  BigDecimal.class_eval do
    def inspect
      "<#{to_s('+3F')}>"
    end
  end
end

And result:

 balance: <+100.0>,
 commission_amount: <+0.15>

Upvotes: 0

sawa
sawa

Reputation: 168101

Pry doesn't just use inspect to display the return value. It calls a proc called print object that is defined in configuration. In lib/pry.rb, you can find that it is set to:

class Pry
  # The default print
  DEFAULT_PRINT = proc do |output, value, _pry_|
    _pry_.pager.open do |pager|
      pager.print _pry_.config.output_prefix
      Pry::ColorPrinter.pp(value, pager, Pry::Terminal.width! - 1)
    end
  end
end

In order to use inspect as in irb, set it like this as instructed here:

Pry.config.print = proc {|output, value| output.puts "=> #{value.inspect}"}

Then you will get:

pry(main)> n = Number.new(1)
=> <<1>>

Upvotes: 2

Related Questions