Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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)
like image 562
migu Avatar asked Feb 14 '23 23:02

migu


2 Answers

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)
like image 66
Sean Mackesey Avatar answered Feb 17 '23 13:02

Sean Mackesey


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
like image 30
sawa Avatar answered Feb 17 '23 12:02

sawa