LoginSignup
2
1

More than 5 years have passed since last update.

隊長!あまりフランクに使ってほしくなさげなメソッドを確認いたしました!

Last updated at Posted at 2017-07-09

参考:知って得する!55のRubyのトリビアな記法

隊長!
あまりフランクに使ってほしくなさげなメソッドを確認いたしました!
ご報告になります!:cat::tiger::lion_face:

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メソッドを呼ぶので、そこに望む処理を書きます。

ちなみに :mouse:

3 * NumList[1, 2, 3]した時、selfnは以下のような値になっています。

〜省略〜
  def coerce(n)
    puts "#{self}<#{self.class}>" # [1, 2, 3]<NumList>
    puts "#{n}<#{n.class}>"       # 3<Fixnum>
    [self, n]
  end
〜省略〜

ちなみに:hamster:

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]

「あまりフランクに使ってほしくない」と言いましたが・・・:moyai:

バグが隠れてしまいそうなニオイを感じ、そう書きましたが、
もちろんケースバイケースだと思っております!:chicken::chicken::chicken:

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1