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実際には「何ができるのか」ではなく、元のコンテンツではなく「テスト」が返されます。

これがなぜ起こっているのか(Rubyカーネルの内部動作についての私の限られた理解を除いて)合理的な説明はありますか?

私に目をそらすもの(しかし、どういうわけか「うまくいくように見える」):

  • 最初のブロックが「test」を返すことを期待しますが、そうではありませんでした
  • 2つのブロックの組み合わせが「何を与えるのか」を返すことを期待しますが、「テスト」を返しますか?
  • Kernel.putsをオーバーライドする方法は、私には終わりのないループのように見えますか?
4

2 に答える 2

0

編集機能があるので、コメントではなく回答を使用します。あなたはそれを編集してより多くの情報を追加することができます、そして私はそれを後で削除するかもしれません。

Capistranoがプットを呼び出すと、「テスト」は表示されませんが、元の出力は表示されます。

キャピストラーノがどのように呼び、どれを呼ぶかを見ずにあなたの質問に答えるのは難しいputsです。putsが元の出力を使用してそのパラメーターを表示するのは正常だと思います(元の出力Kernel#putsを何と呼ぶか​​は明確ではありません。putsに与えられた文字列を意味していると思います)。

  • 最初のブロックが「test」を返すことを期待しますが、そうではありませんでした

putsモジュールCapistranoのクラスConfigurationで定義されたインスタンスメソッドを呼び出す唯一の方法は次のとおりです。

Capistrano::Configuration.new.puts 'xxx'

また

my_inst_var = Capistrano::Configuration.new

そしてどこか他の場所

my_inst_var.puts 'xxx'

そしてもちろんそれは印刷しtestます。繰り返しになりますが、結果があなたを驚かせるputsステートメントを見ずに、何が起こっているのかを知ることは不可能です。

  • 2つのブロックの組み合わせが「何を与えるのか」を返すことを期待しますが、「テスト」を返しますか?

2番目のポイントは不思議で、putsを呼び出すコードとコンソール出力を確認する必要があります。

于 2013-01-01T00:52:39.850 に答える
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

2 番目のバージョンでも同じ出力が得られます。その理由は、クラス レベルのメソッドではなく、インスタンス レベルのメソッドを定義しているためです (この投稿は、違いを説明するのに適しているようです)。少し異なるバージョン:

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 に答える