74

Forgive the beginner question, but say I have an array:

a = [1,2,3]

And a function somewhere; let's say it's an instance function:

class Ilike
  def turtles(*args)
    puts args.inspect
  end
end

How do I invoke Ilike.turtles with a as if I were calling (Ilike.new).turtles(1,2,3).

I'm familiar with send, but this doesn't seem to translate an array into an argument list.

A parallel of what I'm looking for is the Javascript apply, which is equivalent to call but converts the array into an argument list.

MatBanik
  • 26,356
  • 39
  • 116
  • 178
Steven
  • 17,796
  • 13
  • 66
  • 118

1 Answers1

138

As you know, when you define a method, you can use the * to turn a list of arguments into an array. Similarly when you call a method you can use the * to turn an array into a list of arguments. So in your example you can just do:

Ilike.new.turtles(*a)
sepp2k
  • 363,768
  • 54
  • 674
  • 675
  • 4
    Fantastic. Based on your excellent answer, I've found a more thorough account of this technique in [Wikibooks](http://en.wikibooks.org/wiki/Ruby_Programming/Syntax/Method_Calls#Variable_Length_Argument_List.2C_Asterisk_Operator). This is actually perfectly reasonable given the parallel notation going the other other way. Oh, Ruby indeed. I've also noticed that you can prepend your own arguments without awkward `a.unshift` fidgeting by using `Ilike.new.turtles(1,2,3,*a)`, although postpending seems to require such a manoeuver. – Steven Jan 10 '11 at 02:47
  • 1
    @StevenXu In Ruby 1.9 you can also splat for 'postpending'. `a=[1,2]; b=[4,5]; p(0,*a,3,*b,6) #=> "0\n1\n2\n3\n4\n5\n6"` – Phrogz Jan 10 '11 at 03:34
  • This is a fun technique: `some_func(*'some string of args'.split)` – Dennis Williamson Jul 26 '19 at 11:13