2017-02-23 6 views
0

私はRailsチュートリアルの本を見直し、クラスについて話す部分を見ました。次に例を示します。Rubyクラスをインスタンス化するときに有効な引数の数は何ですか?

ここ
class Word < String 
    def palindrome? 
    self == self.reverse 
    end 
end 
# w = Word.new('madamimadam') 
# w.palindrome? #=> true 

私はw変数にWordのクラスに「madamimadam」をインスタンス化。次に私はpalindrome?メソッドを実行します。

私は別の方法に

class SomeClass 
    def some_method 
    self.reverse 
    end 
end 
# s = SomeClass.new('hello') 
# ArgumentError: wrong number of arguments (1 for 0) 

を作成しようとした理由、それは私がSomeClassに引数"hello"を与えることはできませんが、私はWordでそれを行うことができるということですか?私は決して1つの議論を取るかしないかを各クラスに決めることはなかった。

オプションの質問:なぜWordは0から1の引数を期待していますか?それはどこに定義されていますか?あなたが親クラスを指定していない第二の場合では、

w2 = Word.new('hello', 'joe') 
ArgumentError: wrong number of arguments (2 for 0..1) 

答えて

3

、親クラスが引数を取らないそのinitializer from BasicObjectを継承し、デフォルトObject、、です。

最初のケースでは、上記のイニシャライザをオーバーライドして、オプションの引数を1つ取ります(String.newまたはString.new("foo")と書くことができます)。 (これは、2つのキーワード引数、encodingcapacityを取ることができますが、それはポイントの横にある。)

あなたはStringの初期化(1つのオプションの位置引数と1つのオプションのキーワード引数)を複製したい場合、あなたはこれを書くことができます:

class MyString 
    def initialize(str="", encoding: nil, capacity: nil) 
    @encoding = str.encoding || Encoding::ASCII_8BIT 
    # ... 
    end 
end 

(あなたは3つの引数を指定してFooinitializeを定義した場合、あなたはFoo.new(a, b, c)でクラスをインスタンス化します)必要newどのように多くの引数を定義します。

+0

用語に関するコメント: 'initialize'はコンストラクタではありません。 Rubyにはコンストラクタはありません。 'initialize'は他のメソッドと同じようにメソッドです。通常、Class#newによって呼び出されますが、他のメソッドと同様のメソッドです。 Rubyがコンストラクタに持っている最も近いものは 'Class#allocate'メソッド(' Class#new'でも呼び出されます)ですが、これも単なる通常のメソッドです。 –

+0

@JörgWMittag:Meh。それはあいまいな世界です。 [Wiki](https://en.wikipedia.org/wiki/Constructor_(object-oriented_programming)#Ruby)はそれをコンストラクタと呼びます。一方、あなたは正しい: "コンストラクタ"の仕事は、Rubyが 'allocate'を呼び出すことによってRubyが' new'からObjective-Cを呼び出すことによって行うものである "allocator"と "initializer"明示的に '[[Klass alloc] init]'で行い、Javaは割り当てを隠し、初期化子をコンストラクタとして呼び出します。より正確には「イニシャライザ」に変更されましたが、Javaのものよりも「コンストラクタ」と呼ばれる価値はありません。 – Amadan

+0

私は同意しません。 「コンストラクタ」と呼ばれる明確な概念を持つ言語では、コンストラクタはまあまったく別の概念です。たとえば、Javaでは、コンストラクタはメソッドではなく、メソッドとは異なるディスパッチセマンティクスを持ち、メソッドとは異なるバインディングセマンティクスを持ち、メソッドとは異なる継承セマンティクスを持ちます。彼らは "特別な"ものです。実際、コンストラクタ呼び出しのJVMバイトコードは 'invokespecial'と呼ばれます。 Rubyでは、 'initialize'、' allocate'、 'new'は他のメソッドと同様のメソッドです。彼らには特別なことも違うことも絶対にありません。... –

関連する問題