0

抱歉,问题标题含糊不清,但我不知道是什么原因导致以下问题:

module Capistrano
  class Configuration
    def puts string
      ::Kernel.puts 'test'
    end
  end
end

现在当 Capistrano 调用时puts,我看不到“测试”,但我看到了原始输出。

但是,当我还添加此内容时:

module Kernel
  def puts string
    ::Kernel.puts 'what gives?'
  end
end

现在,突然,puts实际上返回的是“test”,而不是“what give?”,不是原始内容,而是“test”。

是否有合理的解释为什么会发生这种情况(除了我对 Ruby Kernel 内部工作原理的有限理解)?

在我看来(但不知何故“似乎有效”)的事情:

  • 我希望第一个块返回“测试”,但它没有
  • 我希望这两个块的组合返回'what give?',但它返回'test'?
  • 我覆盖 Kernel.puts 的方式对我来说似乎是一个永无止境的循环?
4

2 回答 2

0
module Capistrano
  class Configuration
    def puts string
      ::Kernel.puts 'test'
    end
    def an_thing
      puts "foo"
    end
  end
end

Capistrano::Configuration.new.an_thing

给出输出:

test

第二个版本也提供相同的输出。原因是您定义的是实例级别方法而不是类级别方法(这篇文章似乎很好地解释了这些差异)。稍微不同的版本:

module Kernel
  def self.puts string
    ::Kernel.puts 'what gives?'
  end
end

执行以下操作。因为它会导致无限递归,就像您预期的那样。

/tmp/foo.rb:14:in `puts': stack level too deep (SystemStackError)
    from /tmp/foo.rb:14:in `puts'
    from /tmp/foo.rb:4:in `puts'
    from /tmp/foo.rb:7:in `an_thing'
    from /tmp/foo.rb:18

shell returned 1
于 2013-01-01T00:25:53.737 回答
0

由于其编辑功能,我使用答案而不是评论。您可以对其进行编辑以添加更多信息,我稍后可能会删除它。

现在当 Capistrano 调用 puts 时,我看不到“测试”,但我看到了原始输出。

如果不了解 Capistrano 的调用方式puts和调用方式,就很难回答您的问题。我会说如果 puts 显示它的参数,使用原始参数是正常的Kernel#puts(不清楚你所说的original output,我必须假设你的意思是给 puts 的字符串)。

  • 我希望第一个块返回“测试”,但它没有

我看到调用putsCapistrano 模块中类 Configuration 中定义的实例方法的唯一方法是:

Capistrano::Configuration.new.puts 'xxx'

或者

my_inst_var = Capistrano::Configuration.new

和其他地方

my_inst_var.puts 'xxx'

当然它会打印出来test。同样,如果没有看到结果让您感到惊讶的 puts 语句,就不可能知道发生了什么。

  • 我希望这两个块的组合返回'what give?',但它返回'test'?

第二点很神秘,我需要查看调用 puts 的代码,以及控制台输出。

于 2013-01-01T00:52:39.850 回答