クラスがあり、次のようPoint
に実行する方法を知っていると言われています。point * 3
class Point
def initialize(x,y)
@x, @y = x, y
end
def *(c)
Point.new(@x * c, @y * c)
end
end
point = Point.new(1,2)
p point
p point * 3
出力:
#<Point:0x336094 @x=1, @y=2>
#<Point:0x335fa4 @x=3, @y=6>
しかしその後、
3 * point
理解されていません:
Point
Fixnum
(TypeError
)に強制することはできません
したがって、インスタンス メソッドをさらに定義する必要がありますcoerce
。
class Point
def coerce(something)
[self, something]
end
end
p 3 * point
出力:
#<Point:0x3c45a88 @x=3, @y=6>
3 * point
だから と同じだと言われてい3.*(point)
ます。つまり、インスタンス メソッド*
は引数を取りpoint
、 object を呼び出します3
。
さて、このメソッド*
は点を掛ける方法がわからないので、
point.coerce(3)
が呼び出され、配列が返されます。
[point, 3]
そして*
もう一度それに適用されます、それは本当ですか?
これで、これが理解され、クラスPoint
のインスタンス メソッドによって実行されるように、新しいオブジェクトが作成されました。*
Point
質問は:
誰が呼び出すの
point.coerce(3)
ですか?それは自動的にRubyですか、それとも例外をキャッチしての*
メソッド内のコードですか?Fixnum
それともcase
、既知のタイプのいずれかがわからない場合に呼び出すステートメントによるものcoerce
ですか?coerce
常に 2 つの要素の配列を返す必要がありますか? 配列ではありませんか?それとも、3要素の配列にすることができますか?そして、要素 1 の引数を使用して、元の演算子 (またはメソッド)
*
が要素 0 で呼び出されるという規則はありますか? (要素 0 と要素 1 は、 によって返される配列内の 2 つの要素coerce
です。) 誰がそれをしますか? それはRubyによって行われますか、それともコードで行われますFixnum
か? のコードで行うFixnum
場合、強制を行うときに誰もが従うのは「慣例」ですか?したがって、次のようなこと
*
を行うコードである可能性があります。Fixnum
class Fixnum def *(something) if (something.is_a? ...) else if ... # other type / class else if ... # other type / class else # it is not a type / class I know array = something.coerce(self) return array[0].*(array[1]) # or just return array[0] * array[1] end end end
Fixnum
では、インスタンス メソッドに何かを追加するのは本当に難しいのcoerce
でしょうか。すでに多くのコードが含まれており、数行を追加して機能を強化することはできません (ただし、そうしたいことはありますか?)coerce
クラス内のはPoint
非常に一般的であり、*
または+
それらが推移的であるために機能します。Point から Fixnum を引いたものを次のように定義した場合など、推移的でない場合はどうなるでしょうか。point = Point.new(100,100) point - 20 #=> (80,80) 20 - point #=> (-80,-80)