防止ruby / rails打印赋值表达式的结果

时间:2019-03-12 18:25:25

标签: ruby-on-rails ruby irb

当我在rails中执行以下操作时:

irb(main):060:0> users = User.where(name: "Joe")

控制台将评估users并打印出来(也许使用inspectto_s,我不确定100%正确)。这样会产生数百行我不想要的输出。

我知道我可以做这样的事情来防止在某一行上输出:

irb(main):060:0> users = User.where(name: "Joe"); nil

因为nil将被评估并打印出来,而不是users

我还可以通过以下方式关闭所有评估:

irb(main):060:0> conf.echo = false

第一个解决方案很烦人,因为您必须记住在要抑制输出的每一行上都添加它。第二个令人讨厌,因为有时您确实想要输出。很多时候,您只想输入变量的名称以将其打印出来。

Python似乎没有这个问题。如果我输入a = {1: 2},则python shell不会评估a,它只会再次显示提示。但是,如果我输入{1: 2}或仅输入a,它就会打印出该值。

似乎python的控制台会检查要评估的语句的左侧,以决定是否打印结果。

问题:

可以在ruby的控制台中完成类似的事情吗?因此,不会评估诸如a = {1 => 2}之类的语句,而会评估诸如a{1 => 2}之类的语句?

更新:

我将此合并请求推送到irb回购,也许会被接受,然后 会是一种方法:https://github.com/ruby/irb/pull/12

1 个答案:

答案 0 :(得分:1)

this pull request(或类似的文件)被合并之前,您可以将以下内容放入~/.irbrc文件中:

require 'ripper'
module IRB
  class Irb
    ASSIGNMENT_NODE_TYPES = [:assign, :opassign, :massign]
    def is_assignment_expression?(line)
      s = Ripper.sexp(line)
      return false if !s.is_a?(Array)
      return false if !s[1].is_a?(Array)
      return false if !s[1][-1].is_a?(Array)
      ASSIGNMENT_NODE_TYPES.include?(s[1][-1][0])
    end

    def output_value # :nodoc:
      return if is_assignment_expression?(@context.last_line)
      printf @context.return_format, @context.inspect_last_value
    end
  end

  class Context
    attr_accessor :last_line
    def evaluate(line, line_no, exception: nil) # :nodoc:
      @line_no = line_no
      @last_line = line
      if exception
        line = "begin ::Kernel.raise _; rescue _.class; #{line}; end"
        @workspace.local_variable_set(:_, exception)
      end
      set_last_value(@workspace.evaluate(self, line, irb_path, line_no))
    end
  end
end

请注意,由于此猴子补丁IRB::IrbIRB::Context,因此不能保证它将与将来的版本兼容。