隊長!
あまりフランクに使ってほしくなさげなメソッドを確認いたしました!
ご報告になります!
Numeric#coerce
数値のリストをn倍したらその要素がn倍されるようなNumListオブジェクトを定義
class NumList < Array
def *(n)
map { |e| e * n }
end
end
NumList[1, 2, 3] * 3 # => [3, 6, 9]
もし、3 * NumList[1, 2, 3]
でも処理できるようにしたい場合、
Numeric#coerceを使う。
class NumList < Array
def *(n)
map { |e| e * n }
end
def coerce(n)
puts "#{self}<#{self.class}>" # [1, 2, 3]<NumList>
puts "#{n}<#{n.class}>" # 3<Fixnum>
[self, n]
end
end
NumList[1, 2, 3] * 3 # => [3, 6, 9]
3 * NumList[1, 2, 3] # => [3, 6, 9]
Fixnum#*は引数が型変換できないときはそのオブジェクトのcoerceメソッドを呼ぶので、そこに望む処理を書きます。
ちなみに
3 * NumList[1, 2, 3]
した時、self
とn
は以下のような値になっています。
〜省略〜
def coerce(n)
puts "#{self}<#{self.class}>" # [1, 2, 3]<NumList>
puts "#{n}<#{n.class}>" # 3<Fixnum>
[self, n]
end
〜省略〜
ちなみに
Numeric#coerceでcoerceは定義されているので、Floatでもコードは変更せず同じような処理ができます。
class NumList < Array
def *(n)
map { |e| e * n }
end
def coerce(n)
# 「3 * NumList[1, 2, 3]を実行で以下のような値になる。
puts "#{self}<#{self.class}>" # [1, 2, 3]<NumList>
puts "#{n}<#{n.class}>" # 1.5<Float>
[self, n]
end
end
1.5 * NumList[1, 2, 3] # => [1.5, 3.0, 4.5]
「あまりフランクに使ってほしくない」と言いましたが・・・
バグが隠れてしまいそうなニオイを感じ、そう書きましたが、
もちろんケースバイケースだと思っております!