Search code examples
rubyhashruby-1.9nullsplat

Splat on a hash


  • 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?


Solution

  • 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"