Ruby_Array_2

この記事は、以下のドキュメントを改変(自分なりに整理)して利用しています。

class Array (Ruby 3.0.0 リファレンスマニュアル)

インスタンスメソッド

self & other -> Array
  • 集合の積演算
  • 両方の配列に含まれる要素からなる新しい配列を返す
    • 重複要素は取り除かれる
      • 重複判定はObject#eql?によって行われる
    • 返される配列の要素順はselfと同じ
irb(main):001:0> [1, 2, 3] & [5, 3, 2]
=> [2, 3]
irb(main):001:0> [1, 1, 2, 3, 4, 5] & [1, 2, 2, 3, 5]
=> [1, 2, 3, 5]

irb(main):001:0> [5, 4, 3, 2, 1, 1] & [1, 2, 2, 3, 5]
=> [5, 3, 2, 1]

# memo
# 返される配列の要素順に注意
irb(main):001:0> [1, 'foo', 2, 'Bar'] & ['foo', 'bar', 2]
=> ["foo", 2]
irb(main):001:0> [1, 2, 3] & 1
Traceback (most recent call last):
        5: from /Users/mfham/.rbenv/versions/3.0.0/bin/irb:23:in `<main>'
        4: from /Users/mfham/.rbenv/versions/3.0.0/bin/irb:23:in `load'
        3: from /Users/mfham/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/irb-1.3.0/exe/irb:11:in `<top (required)>'
        2: from (irb):1:in `<main>'
        1: from (irb):1:in `&'
TypeError (no implicit conversion of Integer into Array)
self * times -> Array
  • 配列の内容をtimes回繰り返した新しい配列を作成して返す
    • 値はコピーされない
  • timesに整数以外のオブジェクトを指定した場合は to_int メソッドによる暗黙の型変換を試みる
    • to_intメソッドとは?あとで調べる
  • 整数以外の(暗黙の型変換が行えない)オブジェクトを指定したらTypeError、負の数を指定したらArgumentError
irb(main):001:0> [1, 2, 3] * 3
=> [1, 2, 3, 1, 2, 3, 1, 2, 3]
irb(main):001:0> a = [1, 2, 3]
=> [1, 2, 3]

irb(main):002:0> b = a * 1
=> [1, 2, 3]

irb(main):003:0> a.eql?(b)
=> true

irb(main):004:0> a.equal?(b)
=> false
irb(main):001:0> a = ['foo', 'bar']
=> ["foo", "bar"]

irb(main):002:0> b = a * 3
=> ["foo", "bar", "foo", "bar", "foo", "bar"]

irb(main):003:0> a[0].capitalize!
=> "Foo"

irb(main):004:0> a
=> ["Foo", "bar"]

irb(main):005:0> b
=> ["Foo", "bar", "Foo", "bar", "Foo", "bar"]

# memo
# "値はコピーされない" イコール selfを参照している?
irb(main):001:0> [1, 2, 3] * 0
=> []
irb(main):001:0> [1, 2, 3] * 0.5
=> []

# memo
# 0.5に対してto_intメソッドによる暗黙の型変換が行われた結果、
# 0.5 -> 0 となって [1, 2, 3] * 0 と同じことになるのかな?
irb(main):001:0> [1, 2, 3] * true
Traceback (most recent call last):
        5: from /Users/mfham/.rbenv/versions/3.0.0/bin/irb:23:in `<main>'
        4: from /Users/mfham/.rbenv/versions/3.0.0/bin/irb:23:in `load'
        3: from /Users/mfham/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/irb-1.3.0/exe/irb:11:in `<top (required)>'
        2: from (irb):1:in `<main>'
        1: from (irb):1:in `*'
TypeError (no implicit conversion of true into Integer)
irb(main):001:0> [1, 2, 3] * -1
Traceback (most recent call last):
        5: from /Users/mfham/.rbenv/versions/3.0.0/bin/irb:23:in `<main>'
        4: from /Users/mfham/.rbenv/versions/3.0.0/bin/irb:23:in `load'
        3: from /Users/mfham/.rbenv/versions/3.0.0/lib/ruby/gems/3.0.0/gems/irb-1.3.0/exe/irb:11:in `<top (required)>'
        2: from (irb):1:in `<main>'
        1: from (irb):1:in `*'
ArgumentError (negative argument)
self * sep -> String
  • sepを間に挟んで連結した文字列を返す
    • Array#join(sep)と同じ動作
  • sepに文字列以外のオブジェクトを指定した場合、to_strメソッドによる暗黙の型変換を試みる
    • to_strメソッドとは?あとで調べる
irb(main):001:0> [1, 2, 3] * ','
=> "1,2,3"
irb(main):001:0> [1, 2, 3] * ''
=> "123"
irb(main):001:0> [1, 2, 3] * '5'
=> "15253"

メモ

  • self * timesのselfの破壊的変更時の挙動は覚えておきたい
  • self * times, self * sep, 内部的にはどういう処理になっているのだろうか?
    • 前者は整数以外のオブジェクト指定の場合はto_intメソッドによる暗黙の型変換を試みるし、後者は文字列以外のオブジェクト指定の場合はto_strメソッドによる暗黙の型変換を試みる
    • どっちが優先してチェックされるのだろう?[1, 2, 3] * trueの例外メッセージが参考になりそう