2

コンソールの場合:

class Logger
end
l = Logger.new

エラーをスローします:ArgumentError: wrong number of arguments (0 for 1) from /home/zzz/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/logger.rb:268:in 'initialize'

なぜロガーを使用しているの/home/zzz/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/logger.rbですか?

4

2 に答える 2

4

私はあなたの2番目の質問に答えようとします。では、なぜRubyはLogger、自分で定義しようとしたクラスではなく、他のクラスを使用しているのでしょうか。

Rubyの基本的な機能の1つは、クラスを再度開くことです。すでに定義され、アプリにロードされているクラスがあるとします。

class A
  def foo
    puts 'foo'
  end
end

A.new.foo
#=> foo

その後、Rubyインタープリターが次のようなものに遭遇した場合:

class A
  def bar
    puts 'bar'
  end
end

クラスAを再定義するのではなく、この定義を前の定義に追加するだけです。結果として、すでに定義されているクラスAは新しいインスタンスメソッドを取得しますbar

A.new.foo # still works
#=> foo
A.new.bar # new method
#=> bar

Rubyがメソッド呼び出しを処理する方法のため、クラスの2番目の定義(実際には再オープン)のAに初期化されたクラスのすべてのインスタンスも、この新しいメソッドを取得します。したがって、クラスを再度開くたびに、クラス自体と、このクラスの以前に初期化されたすべてのインスタンスに新しい機能を追加します。Abar

クラスを再度開くと、既存のクラスのメソッドを書き換えることもできます。

class A
  def foo
    puts 'new foo'
  end
end

A.new.foo
#=> new_foo

その機能を念頭に置いて、Railsがすでに標準Loggerクラスをロードしているという事実を考慮して、定義はクラスを再度開くだけで、何も変更しません。

于 2012-07-10T15:18:03.550 に答える
2

そのクラスはすでにロードされています。おそらく、railsがそれを使用していたためです。クラスを再定義しておらず、単に再度開いているだけです。

既存のクラスを削除できます

Object.send(:remove_const, :Logger)

この場合、以前はLoggerまだ存在していたと呼ばれていたクラスは、定数にバインドされなくLoggerなったため、

class Logger
end

古いクラスを再度開かずに、新しいクラスを作成します。もちろん、古いLoggerクラスの存在を前提としたコードを壊してしまう可能性があります。

テストでこれを行う場合は、rspec2.11の新しい定数スタブに関心があるかもしれません。

于 2012-07-10T15:09:07.560 に答える