12
  • A splat on a hash converts it into an array.

    [*{foo: :bar}] # => [[:foo, :bar]]

    Is there some hidden mechanism (such as implicit class cast) going on here, or is it a built-in primitive feature?

  • Besides an array, are nil and hash the only things that disappear/change with the splat operator under Ruby 1.9?

sawa
  • 165,429
  • 45
  • 277
  • 381

1 Answers1

15

A splat will attempt an explicit conversion of an object to an Array.

To do this, it will send to_a and expect an Array as a result.

class Foo
  def to_a
    [1,2,3]
  end
end

a, b, c = *Foo.new
a # => 1

If the object does not respond to to_a, then there is no effect, e.g. [*42] == [42]

Many builtin classes implement to_a. In particular:

  • (because they include Enumerable)
    • Array
    • Hash
    • Range
    • IO and File
    • Enumerator
    • Enumerator::Lazy (Ruby 2.0)
    • Set and SortedSet
  • (additional classes)
    • NilClass
    • MatchData
    • OpenStruct
    • Struct
    • Time
    • Matrix and Vector

All these can thus be splatted:

match, group, next_group = *"Hello, world".match(/(.*), (.*)/)
group # => "Hello"
Marc-André Lafortune
  • 78,216
  • 16
  • 166
  • 166
  • 1
    Splatted `nil` disappears Under Ruby 1.9, and this does not fit the case of there being no effect, so this is the only exception, I guess. Am I right? – sawa Jan 14 '13 at 11:20
  • 2
    Oh, forgot about `nil`. Edited answer. `NilClass` implements `to_a` (by returning `[]`), so it's not a special case. No effect would mean that `[*nil]` would be `[nil]` instead of `[]` – Marc-André Lafortune Jan 14 '13 at 20:35