読者です 読者をやめる 読者になる 読者になる

Bye Bye Moore

猫マンション建築の野望を胸に零細事業主として資本主義の荒波に漕ぎ出したアラサー男の技術メモ

Kernel#Arrayという奇妙なメソッドの挙動について

shuzo-kino.hateblo.jp
の続きです。

まず、ArrayはKernelのメソッドでした。
Array.newのエイリアスとか、そういった類のものではありません。
公式では

引数を配列(Array)に変換した結果を返します。

arg.to_ary と arg.to_a をこの順に呼び出して、返ってきた配列を変換結果とします。

arg に to_ary, to_a のいずれのメソッドも定義されていない場合は 一要素の配列 [arg] を返します。

と書かれており、Rubiniusの実装も

module Kernel
  def Array(obj)
    ary = Rubinius::Type.check_convert_type obj, Array, :to_ary

    return ary if ary

    if array = Rubinius::Type.check_convert_type(obj, Array, :to_a)
      array
    else
      [obj]
    end
  end

 ##略

end

てな感じで実装されています。

nilを適用すると空配列がかえってくる

nilにto_aメソッドを適用すると空配列を返します。

nil.to_a
#>> []

というわけで、Arrayにnilを突っ込むと

Array(nil)
#>>[]

と、空配列を返してくるわけです。

Arrayの挙動を制御したい場合、to_aryやto_aを適切に設計する

なんらかの事情でイタズラしたい場合to_aryやto_aメソッドに細工をしてあげれば

class Mimic
 def initialize(init)
   @init = init
 end

 def to_ary
    [99]
  end

  def to_a
    [42]
  end

end

p Array(Mimic.new(0))
#>> [99]