【问题标题】:Understanding how ruby method $stdout works了解 ruby​​ 方法 $stdout 的工作原理
【发布时间】:2017-01-23 13:56:02
【问题描述】:

这是一个简单的 ruby​​ 脚本,它接受用户的输入并提供输出(是的,它将被重构)。我希望这个脚本将输出提供到文本文件中,而不是控制台窗口。这是通过简单地添加$stdout = File.new('out.txt', 'w') 来完成的,但我认为这一行将只描述一个变量,我稍后将使用它来告诉脚本使用它将输出写入创建的文件。

我找不到很多关于这个方法的文档,想知道这个程序如何知道如何将生成的输出写入那个文件?

【问题讨论】:

    标签: ruby stdout


    【解决方案1】:

    $stdout 是一个全局变量。默认情况下,它存储与程序的标准输出(默认情况下,控制台)相关联的IO 类型的对象。

    putsKernel module 的一个方法,它实际上调用$stdout.send() 并将它接收的参数列表传递给它。正如文档所解释的,puts(obj, ...) 等同于 $stdout.puts(obj, ...)

    您的代码将$stdout 替换为File 类型的对象,该对象扩展类IO。创建时,您的对象会打开文件out.txt 进行写入,并且它继承自IO,它与$stdout 的默认行为完全兼容。

    由于默认情况下,所有输出都发送到$stdout,因此您对$stdout 的新定义可确保将输出写入文件out.txt,而无需对代码进行其他更改。

    【讨论】:

    • 哦,这个答案更深了。谢谢!
    【解决方案2】:

    $stdout 是一个全局变量(如$ 所示),根据文档,puts 是:

    相当于

    $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

    【讨论】:

    • 非常好的解释,不仅是关于我的问题的答案,还有关于如何更好地理解文档:))谢谢!!
    【解决方案3】:

    可能值得强调一个事实,正如其他帖子所提到的,这是一个 全局 变量,并且修改它不是线程安全的。例如,如果您将 $stdout 指向一个新的 IO 流,那么将记录到 stdout 的整个应用程序(在该进程线程上)的任何东西现在都将记录到您的新 IO 流中。这可能会导致在您的新 IO 流中出现多个意外且可能敏感的输入流。

    【讨论】:

      猜你喜欢
      • 2016-02-20
      • 2012-12-11
      • 2011-02-18
      • 2018-02-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多