阻止 ruby/rails 打印赋值表达式的结果
Prevent ruby/rails from printing results of assignment expressions
当我在 rails 中做这样的事情时:
irb(main):060:0> users = User.where(name: "Joe")
控制台将评估 users
并将其打印出来(可能使用 inspect
或 to_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 .
我猜这是因为在 Ruby 赋值 return 中自动赋值,即
a = 1
#=> 1
如果您深入研究 conf.echo
的文档,您会发现它用于控制是否打印 return 值。
在您的 ~
文件夹或当前文件夹中创建一个名为 .irbrc
的文件。在里面,添加:
IRB.conf[:ECHO] = false
那应该禁用回显。
如果您 puts IRB.conf
会看到您也可以调整的其他设置。
中找到更多信息
编辑:
下面引用的 MR 版本已合并到 irb,但此后进行了几次调整。所以要获得你想要的行为取决于 irb 版本:
如果您至少有 1.2.0
,但少于 1.2.6
:默认行为是 不 打印赋值语句的任何内容。如果您想要旧的行为(始终打印所有内容),则必须设置 IRB.conf[:ECHO_ON_ASSIGNMENT] = true
。
如果您有 1.2.6
,ECHO_ON_ASSIGNMENT
的默认值已更改为 true
,并添加了一个新的配置值:OMIT_ON_ASSIGNMENT
,它将截断长输出对于赋值语句,它默认为 true
。因此,如果您不想为赋值语句打印任何内容,则必须设置 IRB.conf[:ECHO_ON_ASSIGNMENT] = false
。如果您想要旧的行为(始终打印所有内容),则必须设置 IRB.conf[:OMIT_ON_ASSIGNMENT] = false
。
如果您有 1.2.7
或以上,OMIT_ON_ASSIGNMENT
已被删除,让 ECHO_ON_ASSIGNMENT
接受 true
、false
或 :truncate
,默认值为 :truncate
。 true
的值将打印赋值语句的所有内容,false
将不打印任何内容,而 :truncate
将打印截断的版本(例如将 OMIT_ON_ASSIGNMENT
设置为 true
1.2.6
).
请注意,irb gem 版本以上的版本,而不是 ruby 版本(即使 irb
包含在 ruby的标准库)。您可以通过查看 IRB::VERSION
来检查您拥有的 irb
的版本。非常旧的 irb
版本不会设置此常量,因此如果缺少它,则您的版本肯定低于 1.2.0
.
原回答:
在合并 this pull request(或类似的)之前,您可以将以下内容放入 ~/.irbrc
文件中:
require 'ripper'
module IRB
class Irb
ASSIGNMENT_NODE_TYPES = [:assign, :opassign, :massign]
def assignment_expression?(line)
ASSIGNMENT_NODE_TYPES.include?(Ripper.sexp(line)&.dig(1,-1,0))
end
def output_value # :nodoc:
return if 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::Irb
和 IRB::Context
,因此无法保证它与未来的版本兼容。
当我在 rails 中做这样的事情时:
irb(main):060:0> users = User.where(name: "Joe")
控制台将评估 users
并将其打印出来(可能使用 inspect
或 to_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 .
我猜这是因为在 Ruby 赋值 return 中自动赋值,即
a = 1
#=> 1
如果您深入研究 conf.echo
的文档,您会发现它用于控制是否打印 return 值。
在您的 ~
文件夹或当前文件夹中创建一个名为 .irbrc
的文件。在里面,添加:
IRB.conf[:ECHO] = false
那应该禁用回显。
如果您 puts IRB.conf
会看到您也可以调整的其他设置。
编辑:
下面引用的 MR 版本已合并到 irb,但此后进行了几次调整。所以要获得你想要的行为取决于 irb 版本:
如果您至少有 1.2.0
,但少于 1.2.6
:默认行为是 不 打印赋值语句的任何内容。如果您想要旧的行为(始终打印所有内容),则必须设置 IRB.conf[:ECHO_ON_ASSIGNMENT] = true
。
如果您有 1.2.6
,ECHO_ON_ASSIGNMENT
的默认值已更改为 true
,并添加了一个新的配置值:OMIT_ON_ASSIGNMENT
,它将截断长输出对于赋值语句,它默认为 true
。因此,如果您不想为赋值语句打印任何内容,则必须设置 IRB.conf[:ECHO_ON_ASSIGNMENT] = false
。如果您想要旧的行为(始终打印所有内容),则必须设置 IRB.conf[:OMIT_ON_ASSIGNMENT] = false
。
如果您有 1.2.7
或以上,OMIT_ON_ASSIGNMENT
已被删除,让 ECHO_ON_ASSIGNMENT
接受 true
、false
或 :truncate
,默认值为 :truncate
。 true
的值将打印赋值语句的所有内容,false
将不打印任何内容,而 :truncate
将打印截断的版本(例如将 OMIT_ON_ASSIGNMENT
设置为 true
1.2.6
).
请注意,irb gem 版本以上的版本,而不是 ruby 版本(即使 irb
包含在 ruby的标准库)。您可以通过查看 IRB::VERSION
来检查您拥有的 irb
的版本。非常旧的 irb
版本不会设置此常量,因此如果缺少它,则您的版本肯定低于 1.2.0
.
原回答:
在合并 this pull request(或类似的)之前,您可以将以下内容放入 ~/.irbrc
文件中:
require 'ripper'
module IRB
class Irb
ASSIGNMENT_NODE_TYPES = [:assign, :opassign, :massign]
def assignment_expression?(line)
ASSIGNMENT_NODE_TYPES.include?(Ripper.sexp(line)&.dig(1,-1,0))
end
def output_value # :nodoc:
return if 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::Irb
和 IRB::Context
,因此无法保证它与未来的版本兼容。