Что символ * (звездочка) делает рядом с аргументом функции и как его использовать в других сценариях? - PullRequest
16 голосов
/ 10 марта 2011

Я использую Ruby on Rails 3, и я хотел бы знать, что означает наличие оператора * рядом с аргументом функции, и понять его использование в других сценариях.

Пример сценария (этот метод взят из среды Ruby on Rails 3):

def find(*args)
  return to_a.find { |*block_args| yield(*block_args) } if block_given?

  options = args.extract_options!

  if options.present?
    apply_finder_options(options).find(*args)
  else
    case args.first
    when :first, :last, :all
      send(args.first)
    else
      find_with_ids(*args)
    end
  end
end

Ответы [ 2 ]

42 голосов
/ 10 марта 2011

Это оператор splat, который происходит от ruby ​​(и, следовательно, не относится к рельсам).Его можно применять двумя способами в зависимости от того, где он используется:

  • , чтобы «упаковать» несколько аргументов в массив
  • , чтобы разбить массив на список аргументов

В вашей функции вы видите оператор сплат, используемый в определении функции.В результате функция принимает любое количество аргументов.Полный список аргументов будет помещен в args в виде массива.

def foo(*args)
  args.each_with_index{ |arg, i| puts "#{i+1}. #{arg}" }
end

foo("a", "b", "c")
# 1. a   <== this is the output
# 2. b
# 3. c

Второй вариант будет при рассмотрении следующего метода:

def bar(a, b, c)
  a + b + c
end

Требуется ровно три аргумента,Теперь вы можете вызывать этот метод следующим образом:

my_array = [1, 2, 3]
bar(*my_array)
# returns 6

. Сплат, примененный в этом случае к массиву, разделит его и передаст каждый элемент массива в качестве отдельного параметра методу.Вы можете сделать то же самое, даже вызвав foo:

foo(*my_array)
# 1. 1   <== this is the output
# 2. 2
# 3. 3

Как вы можете видеть в своем примере метода, эти правила применяются к параметрам блока таким же образом.

3 голосов
/ 10 марта 2011

Это аргумент splat, который означает, что все «дополнительные» аргументы, переданные методу, будут присвоены * args

...