6

Ruby では、新しいクラスを作成するときに、コンストラクター メソッドを次のように定義します。

class Thing
  def initialize
     do_stuff
  end
end

ただし、実際にオブジェクトのインスタンスを作成すると、インスタンスではなくクラスを呼び出しinitializeていることに気付きます。new

では、代わりに を定義してみません::newか?

class Thing
   def self.new
     do_stuff
   end
end

定義されていない::newシーンの背後にあるものはありますか? initalizeあの二人は全然違うの?定義は::new機能しますか? それとも、def initializeより短い(ではない)だけdef self.newですか?

格差にはそれなりの理由があるに違いないと思う。

4

3 に答える 3

13

Newは、新しいオブジェクトにスペースを割り当てて作成します。次に、Objects initializeメソッドを呼び出して、割り当てられたメモリを使用して新しいオブジェクトを作成します。通常、カスタマイズしたいのは実際の作成だけであり、Object.newメソッドへのメモリ割り当てを残しておくことができるので、initializeメソッドを記述します。内部で新しいことは次のようになります(Cを除く)。

 class Object
    def self.new(*args, &block)
        object = allocate
        object.send(:initialize, *args, &block)
        return object
    end
 end

したがって、Object.newを呼び出すと、実際に何が起こるかは次のとおりです。

1)メモリが割り当てられます2)オブジェクトの初期化メソッドが呼び出されます。

于 2013-01-14T22:39:08.060 に答える
7

インスタンス変数へのアクセスを提供します。

などのインスタンス変数は、@valueインスタンスからのみアクセスできますが、クラス メソッド内からはアクセスできません。これは、プライベート インスタンス変数がインスタンス スコープではなくクラスを持ち、静的コンストラクターからアクセスできる Java などの言語とは異なります。

class Thing
  def initialize
     @value = 42
  end
end

class Thing
  def self.new
    # no way to set the value of @value !!!!!!!!
  end
end

Ruby の歴史に興味がある方のために説明すると、インスタンス プライベート インスタンス変数を使用したオブジェクト モデルは Smalltalk にまでさかのぼります。また、 Pharoのような最新の Smalltalk 方言でも同じパターンnewが実装されており、サブクラスがインスタンス変数を簡単に初期化できるようObjectに呼び出しが実装されています。self initialize

于 2013-01-14T23:26:02.840 に答える
4
  • アブラハムのポイントを詳しく説明すると、事実上、それはラッピング関係を逆転させることです。allocateプリミティブとして持っていて、通常はを定義している場合は、最後にオブジェクトをnew呼び出しallocateて返すなどの一般的なことを常に行う必要がありますが、これは冗長な作業です。とを使用するnewinitialize、前者は後者をラップするため、ラッパーではなく、ラップされるものを定義するだけで済みます。
  • newはクラスメソッドであるため、これを定義する場合、デフォルトではインスタンスメソッドとインスタンス変数にアクセスできず、アクセサーに依存する必要があります。一方、initializeはインスタンスメソッドであるため、インスタンス変数とインスタンスメソッドの操作が簡単になります。
于 2013-01-14T23:12:39.103 に答える