Truncate #inspect output in irb (ruby)

2019-04-12 02:35发布

问题:

I want to truncate #inspect output in irb (a large output must be cropped to MAX_LEN).

Currently, I override :inspect, :to_s methods for all specific objects.

Is there are other solution?

  • change $stdout ?
  • other?

回答1:

For a clean solution, gem install hirb. hirb pages irb's returned values if they get too long.

If you want to monkeypatch irb:

module IRB
  class Irb
    def output_value
     @context.last_value.to_s.slice(0, MAX_LEN)
    end
  end
end

I don't recommend this because it's a hack and breaks any time gems like ap and hirb are required.

Instead of monkeypatching irb, I'd recommend trying ripl, an irb alternative that is meant to extended. The above as a ripl plugin would be:

require 'ripl'
module Ripl::SlicedInspect
  def format_result(result)
    result_prompt + result.inspect.slice(MAX_LEN)
  end
end
Ripl::Shell.send :include, Ripl::SlicedInspect

With this plugin, you could require it as needed or add to your ~/.riplrc if you want to always use it.



回答2:

Your solution is good.

It involves no dark magic, which might make the code less understandable and error-prone.



回答3:

If you're just in IRB - you could define a monkeypatch in irb itself and or load a file that monkeypatches inspect via 'load'. This way you keep it out of your core codebase but you still get the functionality you need w/o having to override inspect in every class you wish to inspect....



回答4:

If it's because you have a nested hash or something that's hard to decipher, try awesome_print. You can make it the default output formatter in irb by placing the following in your .irbrc:

require 'ap'

module IRB
  class Irb
    def output_value
      ap @context.last_value
    end
  end
end

This makes objects with lots of data easy to decipher in IRB.

Even if you don't use awesome_print, you can truncate output using this same technique so you don't have to override to_s in your code.



回答5:

For rails 3.1.1+, place the code below in helpers/irb_helper.rb

module IRB
  class Irb
    MAX_LEN = 10000

    def output_value
      if (@context.inspect_last_value.length > MAX_LEN)
        printf @context.return_format, "#{@context.inspect_last_value[0..MAX_LEN]} <- Truncated"
      else
        printf @context.return_format, @context.inspect_last_value
      end
    end
  end
end

If you'd like to customize your output more, check irb's source at https://github.com/Ruby/Ruby/blob/trunk/lib/irb.rb



回答6:

I sometimes modify the objects themselves (via a module called BoringInspect which I include into the relevant classes) so that exception messages are also manageable.