了解 ruby 方法 $stdout 的工作原理
Understanding how ruby method $stdout works
这是一个简单的 ruby 脚本,它接受用户的输入并提供输出(是的,它将被重构)。我希望此脚本将输出提供到文本文件中,而不是控制台 window。这是通过简单地添加 $stdout = File.new('out.txt', 'w')
来完成的,但我认为这一行将只描述一个变量,稍后我将使用它来告诉脚本使用它来将输出写入创建的文件。
我找不到很多关于此方法的文档,想知道此程序如何知道如何将生成的输出写入该文件?
$stdout
是一个全局变量(如 $
所示),根据文档,puts
是:
Equivalent to
$stdout.puts(obj, ...)
如果您将另一个对象分配给 $stdout
,那么 Kernel#puts
只会将 puts
发送到该对象。同样,print
将发送 write
:
class Foo < BasicObject
def puts(*args)
::STDOUT.puts "Foo#puts called with #{args.inspect}"
end
def write(*args)
::STDOUT.puts "Foo#write called with #{args.inspect}"
end
end
$stdout = Foo.new
puts 'hello', 'world'
# Foo#puts called with ["hello", "world"]
print "\n"
# Foo#write called with ["\n"]
请注意,如果您分配给 $stdout
,Ruby 会检查对象是否响应 write
。如果没有,将引发TypeError
。
$stdout
是一个全局变量。默认情况下,它存储与程序的标准输出(默认情况下为控制台)关联的类型 IO
的对象。
puts
is a method of the Kernel
module 实际调用 $stdout.send()
并将其接收的参数列表传递给它。如文档所述,puts(obj, ...)
等同于 $stdout.puts(obj, ...)
.
您的代码将 $stdout
替换为扩展 class IO
的 File
类型的对象。创建时,您的对象会打开文件 out.txt
进行写入,并且与 IO
的继承一起与 $stdout
.
的默认行为完全兼容
由于默认情况下,所有输出都转到 $stdout
,您对 $stdout
的新定义可确保将输出写入文件 out.txt
,而无需对代码进行其他更改。
其他帖子提到的一个事实可能值得强调,这是一个 全局 变量,修改它不是线程安全的。例如,如果您将 $stdout 指向一个新的 IO 流,那么应用程序中(在该进程线程上)将记录到 stdout 的 任何内容 现在将记录到您的新 IO 流。这可能会导致在您的新 IO 流中出现多个意外且可能敏感的输入流。
这是一个简单的 ruby 脚本,它接受用户的输入并提供输出(是的,它将被重构)。我希望此脚本将输出提供到文本文件中,而不是控制台 window。这是通过简单地添加 $stdout = File.new('out.txt', 'w')
来完成的,但我认为这一行将只描述一个变量,稍后我将使用它来告诉脚本使用它来将输出写入创建的文件。
我找不到很多关于此方法的文档,想知道此程序如何知道如何将生成的输出写入该文件?
$stdout
是一个全局变量(如 $
所示),根据文档,puts
是:
Equivalent to
$stdout.puts(obj, ...)
如果您将另一个对象分配给 $stdout
,那么 Kernel#puts
只会将 puts
发送到该对象。同样,print
将发送 write
:
class Foo < BasicObject
def puts(*args)
::STDOUT.puts "Foo#puts called with #{args.inspect}"
end
def write(*args)
::STDOUT.puts "Foo#write called with #{args.inspect}"
end
end
$stdout = Foo.new
puts 'hello', 'world'
# Foo#puts called with ["hello", "world"]
print "\n"
# Foo#write called with ["\n"]
请注意,如果您分配给 $stdout
,Ruby 会检查对象是否响应 write
。如果没有,将引发TypeError
。
$stdout
是一个全局变量。默认情况下,它存储与程序的标准输出(默认情况下为控制台)关联的类型 IO
的对象。
puts
is a method of the Kernel
module 实际调用 $stdout.send()
并将其接收的参数列表传递给它。如文档所述,puts(obj, ...)
等同于 $stdout.puts(obj, ...)
.
您的代码将 $stdout
替换为扩展 class IO
的 File
类型的对象。创建时,您的对象会打开文件 out.txt
进行写入,并且与 IO
的继承一起与 $stdout
.
由于默认情况下,所有输出都转到 $stdout
,您对 $stdout
的新定义可确保将输出写入文件 out.txt
,而无需对代码进行其他更改。
其他帖子提到的一个事实可能值得强调,这是一个 全局 变量,修改它不是线程安全的。例如,如果您将 $stdout 指向一个新的 IO 流,那么应用程序中(在该进程线程上)将记录到 stdout 的 任何内容 现在将记录到您的新 IO 流。这可能会导致在您的新 IO 流中出现多个意外且可能敏感的输入流。