【问题标题】:Intercepting all puts and print statements from a Ruby program拦截 Ruby 程序中的所有 puts 和 print 语句
【发布时间】:2014-11-13 03:55:20
【问题描述】:

我有遗留代码,重写它需要很长时间。在那之前,我需要一个“有效”的解决方案,即使它很丑。

代码的主类生成一个长 HTML 字符串并将其存储在 @instance 变量中。

不幸的是,较大的框架有时也会直接输出一些东西,通过putsprint,因此可以在.cgi 脚本中使用。

在将其发送给用户/访问者之前,我需要能够捕获该框架的所有输出,可能对其进行过滤或处理。

是否可以从 Ruby 脚本中捕获所有 putsprint 语句并优雅地处理?

在最终形式中,无论如何我都必须使用putsprint,但我需要清理那里的一些东西,可能会重定向,还可以选择在使用 puts/print 之前记录输出。

【问题讨论】:

  • 如果您觉得答案有帮助,请考虑选择一个。

标签: ruby


【解决方案1】:

简单。默认情况下putsprint 输出到$stdout I/O 通道。将$stdout 重新分配给不同的文件句柄,这些命令的输出将转到新通道。

更改$stdout 指向的位置。

File.open('spool.out', 'wb') do |fo|
  $stdout = fo

  puts 'hello world'

  $stdout = STDOUT
end

将其保存到文件并运行它。您应该会看到一个名为“spool.out”的文件,其中包含“hello world”。

不必将所有内容都包装在 File.open 块中。重要的是您将 $stdout 重新分配给文件句柄,然后稍后将其重置,因此也可以这样做:

$stdout = File.open('spool.out', 'wb')

puts 'hello world'

$stdout.close
$stdout = STDOUT

在启动时,Ruby 脚本可以访问许多不同的全局变量和常量:$stdout 将与 STDOUT 相同,$stderr 将与 STDERR 相同。

有关详细信息,请参阅“Does Ruby use $stdout for writing the output of puts and return?”和“Putting the results of pp (or anything outputted to console) into a string”。

【讨论】:

  • 效果很好 - 我赞成这两个结果,因为它们看起来不错;我只能选择一个答案,所以它是你的
【解决方案2】:

您可以重新定义打印/放置功能以添加新功能。 可以这样做:

def print message
    #do something, like editing the message and logging it
    puts "Im here"
    super "#{message}:edited version"
end

print "hello world"

结果:

->Im here
->hello world:edited version

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-07-27
    • 1970-01-01
    • 2011-06-28
    • 2018-07-24
    • 2021-03-25
    • 1970-01-01
    • 2014-03-10
    • 2021-03-16
    相关资源
    最近更新 更多