24

How do I create a Ruby function that does not have an explicit number of parameters?

More clarification needed?

4

5 回答 5

31

Use the splat operator *

def foo(a,b,c,*others)
   # this function has at least three arguments,
   # but might have more
   puts a
   puts b
   puts c
   puts others.join(',')
end
foo(1,2,3,4,5,6,7,8,9)
# prints:
# 1
# 2
# 3
# 4,5,6,7,8,9
于 2009-05-17T04:14:07.520 回答
21

Use *rest. here's a nice little tutorial.

于 2009-05-17T03:51:36.747 回答
6

(If I could add a comment to the accepted answer, I would, but I don't have enough points.)

Warning: Be careful about doing this for methods processing general data. It's a great piece of syntax sugar, but there are limits to the number of arguments you can pass to a method before you get a SystemStackError. I've hit that limit using redis.mapped_mget *keys. Also, the limit will change depending on where you use the splat operator. For instance, running pry locally, I can splat arrays of over 130,000 elements to a method. Running within a Celluloid actor, though, that limit can be less than 16,000 elements.

于 2014-12-11T18:51:40.217 回答
2

Here's another article on the subject:

www.misuse.org/science/2008/01/30/passing-multiple-arguments-in-ruby-is-your-friend

Gives some nice examples rolling and unrolling your parameters using "*"

于 2009-05-20T17:23:41.630 回答
0

In addition, here is also an interesting "look-alike" technique to passing multiple named parameters. It's based on the fact that Ruby will convert a list of named parameters to a hash if given in a place where one positional parameter is expected:

def hashed_args_test(args = {})
  p args
end

hashed_args_test(arg1: "val1", arg2: "val2")
# => {:arg1=>"val1", :arg2=>"val2"}

hashed_args_test( {arg1: "val1", arg2: "val2"} )
# => {:arg1=>"val1", :arg2=>"val2"}

So both ways of invoking the method supply a hash of (any number of) elements – whether using the hash syntax explicitly or something that looks exactly like passing named parameters. (Tested with Ruby 2.5.3.)

于 2019-09-29T00:28:35.863 回答