我正在尝试创建一种将ruby程序的所有三个标准(输入,输出和错误)流镜像到不同文件的方法。
对于输出stdout
和错误stderr
流,我能够做到这一点。
但是,不同的ruby版本之间在如何处理IO流方面存在不一致之处。
底线是 如何处理旧版本的ruby中的流重复(第2点)?
问题摘要
旧的ruby版本不支持可变参数,而新版本则可以处理。
在相同的旧版本中,即使我尝试通过join
输入参数来解决它,流内容也是重复的。
2.1.x
和ruby 2.2.x
中,$stdout
仅接受单个参数。所以对于那些红宝石
$stdout.write("Test") # works
这不起作用
$stdout.write("Hello","Test")
ArgumentError: wrong number of arguments (2 for 1)
from (pry):6:in `write'
但是对于红宝石版本2.5.x
和2.6.x
可变参数有效
$stdout.write("Hello")
$stdout.write("This","works", "as", "well")
流内容重复,如果我添加了特定于版本的代码来处理流参数,则较旧的ruby版本最终将复制流内容。
driver.rb:4 in `puts` --> This is it driver.rb:4 in `puts` -->
在
driver.rb:4 in `puts` --> This is it
这是代码
require_relative 'reox_io.rb'
require_relative 'reox_file.rb'
class Reox
DEFAULT_RECORDING_PATH = "recordings"
def initialize(recording_path)
@recording_paths = recording_path || DEFAULT_RECORDING_PATH
end
def self.record
input_log,output_log,error_log = setup_files
$stdout = ReoxIO.new(STDOUT,output_log)
$stderr = ReoxIO.new(STDERR,error_log)
yield
end
private
def self.setup_files
["input.log","output.log","error.log"].map do |file_name|
self.setup_file(file_name)
end
end
def self.setup_file(file_name)
file = ReoxFile.open(File.join(__dir__,file_name),"a")
file.sync = true
file
end
end
class ReoxFile < File
end
# Insipired from https://stackoverflow.com/a/6407200
require_relative 'reox_file.rb'
class ReoxIO
$LOG_SEPARATOR = " --> ".freeze
def initialize(*streams)
@streams = streams
@verbose = true
end
def write(*content)
@streams.each do |stream|
if @verbose and stream.is_a? ReoxFile
stream.write([caller[2],$LOG_SEPARATOR,*content].join)
else
stream.write(*content)
end
end
end
def flush
@streams.each(&:flush)
end
def close
@streams.each(&:close)
end
end
require_relative 'reox.rb'
Reox.record do
puts "This is it"
end