migu
migu

Reputation: 4336

Single array argument versus multiple arguments

I saw a method defined and used like this:

def mention(status, *names)
  ...
end
mention('Your courses rocked!', 'eallam', 'greggpollack', 'jasonvanlue')

Why not just use an array as the second argument instead of combining the arguments into an array using splat?

def mention(status, names)
  ...
end
mention('Your courses rocked!', ['eallam', 'greggpollack', 'jasonvanlue'])

This would also allow more arguments at the end.

def mention(status, names, third_argument, fourth_argument)
  ...
end
mention('Your courses rocked!', ['eallam', 'greggpollack', 'jasonvanlue'], Time.now, current_user)

Upvotes: 4

Views: 124

Answers (4)

sawa
sawa

Reputation: 168071

As Cary Swoveland and vgoff mention, definitions like

def foo arg1, *args, arg2
  ...
end

are possible, so your last point does not hold.


It depends on the use case. If that method takes an argument that is naturally given as an array, then it would be easier for the user to pass an array. For example, suppose a method takes backtrace_locations (array) as its argument. Then it would be better to have:

def foo arg1, backtrace_locations, arg2
  ...
end
foo("foo", $!.backtrace_locations, "bar")

rather than:

def foo arg1, *backtrace_locations, arg2
  ...
end
foo("foo", *$!.backtrace_locations, "bar")

In other cases, when it is the user that types in the flexible numbers of arguments, then as Sean Mackesey also points out, the user might forget the [] around the element when there is only one, so it is better to do:

def foo arg1, *args, arg2
  ...
end
foo("foo", "e1", "bar")
foo("foo", "e1", "e2", "e3", "bar")

rather than:

def foo arg1, args, arg2
  ...
end
foo("foo", ["e1"], "bar")
foo("foo", ["e1", "e2", "e3"], "bar")
foo("foo", "e1", "bar") # => An error likely to happen

Upvotes: 2

Sean Mackesey
Sean Mackesey

Reputation: 10939

The splat feels natural since this method could reasonably be applied to a single or to multiple names. It is annoying and error prone to need to put a single argument in array braces, like mention('your courses rocked!', ['eallam']). The splat also often saves keystrokes even when a method only makes sense to apply to an Array.

Also, there is no reason you can't put your other arguments in with *names:

def mention(status, arg2, arg3, *names)
def mention(status, *names, arg2, arg3)

Upvotes: 3

AdamT
AdamT

Reputation: 6485

It's both about clean code and flexibility. Splat gives you the flexibility while explicitly declaring each input binds your method closer to those input objects. What if the code changes later? What if you had to add more fields? Do you know what you'd call them? What if you had to use this method elsewhere with variable inputs? Splat adds a lot of flexibility and keeps the method declaration concise

Listing too many params is also a code smell.

Check this out: How many parameters are too many?

And here: http://www.codinghorror.com/blog/2006/05/code-smells.html

Long Parameter List:
The more parameters a method has, the more complex it is.
Limit the number of parameters you need in a given method,
or use an object to combine the parameters.

Upvotes: 1

Jeff Storey
Jeff Storey

Reputation: 57162

The splat is more flexible. It's easier to just type in the args than to put them in array.

Upvotes: 2

Related Questions