私が欲しいのは:
obj = Foo.new(0) # => nil or false
これは機能しません:
class Foo
def initialize(val)
return nil if val == 0
end
end
C/C++/Java/C# では、コンストラクターで値を返すことはできません。
しかし、Rubyでそれが可能かどうか疑問に思っています。
私が欲しいのは:
obj = Foo.new(0) # => nil or false
これは機能しません:
class Foo
def initialize(val)
return nil if val == 0
end
end
C/C++/Java/C# では、コンストラクターで値を返すことはできません。
しかし、Rubyでそれが可能かどうか疑問に思っています。
new
Ruby では、「 」と「 」の関係は何initialize
ですか?
new
通常、 を呼び出しますinitialize
。のデフォルトの実装new
は次のようなものです。
class Class
def new(*args, &block)
obj = allocate
obj.initialize(*args, &block)
# actually, this is obj.send(:initialize, …) because initialize is private
obj
end
end
ただし、もちろん、それをオーバーライドして、必要なことを行うことができます。
初期化中にnilを返す方法は?
私が欲しいのは:
obj = Foo.new(0) # => nil or false
これは機能しません:
class Foo def initialize(val) return nil if val == 0 end end
C/C++/Java/C# では、コンストラクターで値を返すことはできません。
しかし、Rubyでそれが可能かどうか疑問に思っています。
Ruby にはコンストラクターのようなものはありません。Ruby にはメソッドしかなく、値を返すことができます。
あなたが見ている問題は、あるメソッドの戻り値を変更したいのに、別のメソッドをオーバーライドしていることです。method の戻り値を変更したい場合は、他のメソッドではなく、bar
をオーバーライドする必要があります。bar
の動作を変更したい場合は、次のように変更Foo::new
する必要がありますFoo::new
。
class Foo
def self.new(val)
return nil if val.zero?
super
end
end
ただし、完全に初期化され、完全に機能するクラスのインスタンスを返すというの契約に違反するため、これは本当に悪い考えであることに注意してください。new
2 つの方法には重要な違いがあります。
new
クラスメソッドであり、通常はクラスのインスタンスを作成します (これは、Ruby によって保護されているメモリの割り当てなどのトリッキーな処理を処理するため、あまり手を加える必要はありません)。
次に、initialize
インスタンスメソッドである が、要求されたパラメータに従って内部状態を設定するようにオブジェクトに指示します。
必要に応じて、これらのいずれかをオーバーライドできます。たとえば、それを行うのに十分なほど賢くする必要がある場合Foo.new
は、実際に のインスタンスを作成して返す場合があります。FooSubclass
ただし、多くの場合、これらのようなユース ケースは、たとえばFoo.relating_to(bar)
. メソッド like が何をnew
すべきかについて他の人々の期待を裏切ることは、長期的には彼らを助けるよりも混乱させるでしょう.
Singleton
例として、特定のクラスのインスタンスを 1 つだけ存在させるモジュールであるの実装を見てください。メソッドをプライベートにし、オブジェクトの既存のインスタンスを返すか、まだ作成されていない場合は呼び出すメソッドをnew
公開します。instance
new
次のようなことができます:
class Foo
def self.init(val)
new(val) unless val == 0
end
def initialize(val)
#...
end
end
使用例:
obj = Foo.init(0)
=> nil
obj = Foo.init(5)
=> #<Foo:0x00000002970a98>
したい
class Foo
def initialize(val)
return nil if val == 0
end
end
一貫性のないコードになります。
もしあなたが持っていたら
class Foo
def initialize(val)
return nil if val == 0
@val = val
@bar = 42
end
end
もしそうなら何を取り戻したいですFoo.new(1)
か?42
( の戻り値Foo#initialize
) が必要ですか、それともオブジェクトfoo
が必要ですか? foo
のオブジェクトが必要な場合、なぜreturn nilFoo.new(1)
を期待return nil
するのでしょうか?Foo.new(0)
次のようなオブジェクト変数を作成するだけで解決されます。
class Foo
def initialize(val)
@val = val
return nil if @val == 0
end
end
obj = Foo.new(0)
Output:-
=>#<Foo:0x1243b8 @val=0>
出力は、コンピューターによって異なります。