【问题标题】:Ruby: Where is STDERR.puts defined?Ruby:STDERR.puts 定义在哪里?
【发布时间】:2019-07-09 03:17:01
【问题描述】:

我了解您在 Ruby 中经常使用的普通 puts 函数来写入标准输出是在模块 Kernel 中定义的,因此要覆盖它,您只需执行以下操作:

module Kernel
  def puts(*args)
    # do custom logic
  end
end

但是,覆盖这个 puts 函数似乎不会影响 STDERR.putsSTDERR.puts 定义在什么模块中?

谢谢

【问题讨论】:

  • 为什么要覆盖STDERR.puts

标签: ruby stdout stderr puts


【解决方案1】:

它是IO。你可以这样检查:

STDERR.method(:puts).owner
#=> IO

【讨论】:

    【解决方案2】:

    STDERRIO 的一个实例;分别覆盖puts。因此,您可以在这里做两种不同的事情:

    1. STDERR 重新分配给您自己设计的新对象(可能是 想法)
    2. 覆盖IO#puts(绝对是个坏主意)
    3. def STDERR.puts ....(不是一个坏主意;但我无法想象自己会这样做)

    【讨论】:

      【解决方案3】:
      [32] pry(main)> STDERR.class
      => IO
      [33] pry(main)> STDERR.method(:puts)
      => #<Method: IO#puts>
      [34] pry(main)> class IO
      [34] pry(main)*   def puts(arg)
      [34] pry(main)*     raise "OVERRIDE"
      [34] pry(main)*   end
      [34] pry(main)* end
      => :puts
      [35] pry(main)> STDERR.puts "test"
      (pry):35:in `puts': OVERRIDE (RuntimeError)
      

      【讨论】:

      • Stack Overflow 上有数百个类似这样的问题,所有问题的答案或多或少都是一样的:找出方法来源的最简单方法就是问方法:STDERR.method(:puts).owner #=&gt; IO。我总是惊讶于人们宁愿花几分钟写一个问题,然后可能等待几个小时的答案,这甚至可能是错误的,而不是仅仅检查自己。
      • 覆盖IO#puts 以更改STDOUT.puts 可能不是最好的主意,因为它会影响任何基于puts 的调用IO,例如所有File 相关putsSTDOUT.puts 甚至全球puts
      • 是的,我不知道这是什么意图。答案更多是关于如何查找定义方法的位置,而不是覆盖它是否是个好主意。覆盖只是为了证明它实际上是在 IO 上定义的。
      猜你喜欢
      • 1970-01-01
      • 2016-03-22
      • 2016-02-19
      • 2016-12-31
      • 2011-10-08
      • 2010-09-30
      • 2013-04-04
      • 2019-01-01
      相关资源
      最近更新 更多