1

クラス定義に「初期化」メソッドが指定されていないときに実際に確認しようとしているのは、あなたが言ったように、クラスは を呼び出す必要があるということです"Object#initialize"。ここでは、カスタマイズして、呼び出されたかどうかを確認しようとしました。そのアプローチで、「ob = A .new」と入力すると、メソッドをオーバーロードできますが、Object#initializeすべてが以下の例外で終了しました。次に、カスタマイズで何か間違ったことをしたと思ったので、例外ブロック内でオブジェクト作成を作成しようとしましたが、「begin」と入力して「ENTER」を押すと、同じエラーが発生しました。

>>  class A
>>  def Object.new initialize
>>   p "hi"
>>   rescue
>>  end
>>  end
=> nil
>>  begin # <~~~ Here I have pressed on ENTER
"hi"  #<~~~~ How was it print out?
/usr/lib/ruby/1.9.1/irb/ruby-token.rb:94:in `Token': undefined method `set_backtrace' for "hi":String (NoMethodError)
    from /usr/lib/ruby/1.9.1/irb/ruby-lex.rb:348:in `block in lex_init'
    from /usr/lib/ruby/1.9.1/irb/slex.rb:236:in `call'
    from /usr/lib/ruby/1.9.1/irb/slex.rb:236:in `match_io'
    from /usr/lib/ruby/1.9.1/irb/slex.rb:221:in `match_io'
    from /usr/lib/ruby/1.9.1/irb/slex.rb:75:in `match'
    from /usr/lib/ruby/1.9.1/irb/ruby-lex.rb:286:in `token'
    from /usr/lib/ruby/1.9.1/irb/ruby-lex.rb:262:in `lex'
    from /usr/lib/ruby/1.9.1/irb/ruby-lex.rb:233:in `block (2 levels) in each_top_level_statement'
    from /usr/lib/ruby/1.9.1/irb/ruby-lex.rb:229:in `loop'
    from /usr/lib/ruby/1.9.1/irb/ruby-lex.rb:229:in `block in each_top_level_statement'
    from /usr/lib/ruby/1.9.1/irb/ruby-lex.rb:228:in `catch'
    from /usr/lib/ruby/1.9.1/irb/ruby-lex.rb:228:in `each_top_level_statement'
    from /usr/lib/ruby/1.9.1/irb.rb:155:in `eval_input'
    from /usr/lib/ruby/1.9.1/irb.rb:70:in `block in start'
    from /usr/lib/ruby/1.9.1/irb.rb:69:in `catch'
    from /usr/lib/ruby/1.9.1/irb.rb:69:in `start'
    from /usr/bin/irb:12:in `<main>'
@ubuntu:~$

今私の質問は-

  • 「こんにちは」はどのように印刷されていますか?

  • 上記のエラーの原因は何ですか?

  • そのようなinitialize定義が許可されていない場合、クラス定義を終了した後にエラーが発生しないのはなぜですか?

編集

@casperに従って、以下を試しました:

>> def Object.new
>> p "hi"
>> end
=> nil
>> begin
/usr/lib/ruby/1.9.1/irb/ruby-token.rb:96: stack level too deep (SystemStackError)

しかし、ここでは"hi"印刷されていません。

では、最初のケースで "hi" を出力したのはなぜでしょうか?

4

1 に答える 1

3

正確に何をしようとしていますか?を再定義したばかりObject.newなので、すべてがうまくいかないことは驚くことではありません。

基本的に、次の方法で同じ効果を得ることができます。

>> def Object.new
>> end
>> [press enter]
KABOOM

その理由は、おそらくREPL ループ"hi"で誰かが呼び出したばかりで、オブジェクトを予期していたのに、代わりに gobledygook を取得したためです。Object.newirb

これを試すこともできます:

def Object.new *args
  p args
end

そして、あなたは面白いものを見るでしょう。ただし、その後は irb を終了したり、何か役に立つことを行うことはできません。繰り返しますが、あなたは壊れObjectました。

これを理解するには、次の文章を読む必要があります:
Ruby では、'new' と 'initialize' の関係は何ですか? 初期化中にnilを返す方法は?

そして、これを試すことができます:

class Object
  class << self
    alias :old_new :new
  end
end

これで、次のことができます。

def Object.new *args
   p args
   old_new *args
end

new古いバージョンをまだ呼び出しているため、これは壊れません。ただし、誰かが呼び出すたびに印刷することになりますnew

于 2013-02-17T20:25:46.750 に答える