拦截Ruby程序中的所有put和print语句

时间:2014-11-12 18:57:30

标签: ruby

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

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

不幸的是,较大的框架有时会直接通过putsprint发布内容,因此可以在.cgi脚本中使用。

我需要能够捕获该框架的所有输出,可能会过滤或处理它,然后再将其发送给用户/访客。

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

在最终形式中,我将不得不使用putsprint,但我需要清理那里的一些东西,可能是重定向,也可以选择日志输出,然后才使用puts / print。 / p>

2 个答案:

答案 0 :(得分:2)

易。默认情况下,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将与{{{1}相同1}}。

参见" 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"了解更多信息。

答案 1 :(得分:1)

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

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