【问题标题】:pry inspect method not working撬检查方法不起作用
【发布时间】:2016-04-16 11:49:00
【问题描述】:

我从理解计算一书中获得了以下代码。目的是改变inspect 的行为。

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

当我使用irb 时,它按预期工作:

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

但是当我使用pry时它不会:

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

Pry 是 Ruby 2.0.0 上的 0.10.3 版本。为什么它不起作用?

【问题讨论】:

    标签: ruby pry


    【解决方案1】:

    Pry 不仅仅使用inspect 来显示返回值。它调用一个在配置中定义的名为 print object 的过程。在lib/pry.rb中可以发现设置为:

    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
    

    为了像irb一样使用inspect,请按照here的说明这样设置:

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

    然后你会得到:

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

    【讨论】:

    • 修改所有对象的打印行为(并失去 Pry 的所有漂亮打印)只是为了获得你想要的一个类的行为似乎是一种耻辱。根据您链接到的文档,不会将类添加到Pry.config.prompt_safe_objects 来完成同样的事情而不会产生不幸的副作用吗?
    【解决方案2】:

    我使用Pry版本0.10.4

    我刚刚在我的.pryrc 文件中添加了以下几行(我认为,这是一个 此类代码的位置):

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

    结果:

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

    【讨论】:

      【解决方案3】:

      Sawa 是对的,Pry 使用自己的打印机,但如果您仔细观察 source,您会发现它实际上在幕后使用了 Ruby 的 PP,而 PP 将其 own behaviour 定义为漂亮打印结构:

      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
      

      如果您有兴趣了解更多相关信息,值得查看documentation(虽然它只是简短的)。

      因此,在您的结构中,您还可以定义自己的 pretty_printpretty_print_cycle 方法,这意味着 Pry 可以按照您的意愿打印这些,而无需覆盖它们的 DEFAULT_PRINT proc。

      【讨论】:

        猜你喜欢
        • 2015-09-12
        • 2018-12-16
        • 2016-09-12
        • 1970-01-01
        • 2020-04-01
        • 1970-01-01
        • 2013-02-24
        • 2014-09-23
        • 2016-12-11
        相关资源
        最近更新 更多