Подтвердить что ты не робот

Где законно использовать оператора ruby ​​splat?

Звёзды прохладные. Они не просто для взрывающихся массивов, хотя это весело. Они также могут быть переданы в массивы и сплющенные массивы (см. http://github.com/mischa/splat/tree/master для исчерпывающего списка того, что они делают.)

Похоже, что нельзя выполнять дополнительные операции над splat, но в 1.8.6/1.9 следующий код вызывает "неожиданный tSTAR":

foo = bar || *zap #=> unexpected tSTAR

В то время как это работает:

foo = *zap || bar #=> works, but of limited value

Где может отображаться символ в выражении?

4b9b3361

Ответ 1

Во-первых, приоритет здесь не проблема, потому что foo = bar || (*zap) работает не лучше. Общее правило заключается в том, что вы не можете выполнять дополнительные операции над splat. Даже то, что просто, как foo = (*zap), недействительно. Это относится и к 1.9.

Сказав это, что вы ожидаете от foo = bar || *zap, если это сработало, это отличается от foo = bar || zap? Даже в случае, например a, b = bar || *zap (который также не работает), a, b = bar || zap выполняет то, что я предполагаю, будет одним и тем же.

Единственная ситуация, когда это может иметь какой-то смысл, - это что-то вроде a, b = foo, bar || *zap. Вы должны обнаружить, что большинство случаев, когда вы хотите использовать это, покрываются a, b = foo, *(bar || zap). Если это не касается вашего дела, вы должны, вероятно, спросить себя, чего вы действительно надеетесь достичь, написав такую ​​уродливую конструкцию.


EDIT:

В ответ на ваши комментарии *zap || bar эквивалентен *(zap || bar). Это демонстрирует, насколько низкий приоритет splat. Насколько он низок? Лучший ответ, который я могу вам дать, - "довольно низкий".

Для интересного примера рассмотрим метод foo, который принимает три аргумента:

def foo(a, b, c)
  #important stuff happens here!
end

foo(*bar = [1, 2, 3]) будет отображаться после назначения и установить аргументы в 1, 2 и 3 соответственно. Сравните это с foo((*bar = [1, 2, 3])), который будет жаловаться на неправильное количество аргументов (1 для 3).

Ответ 2

"Оператор splat" на самом деле не является оператором, а маркером, определенным в грамматике Ruby. Прочитанная грамматика или грамматика Ruby в форме BNF * скажут вам, что она разрешена в качестве последнего или единственного аргумента:

  • в определении метода (за исключением необязательного последнего &foo)
  • в вызове метода (за исключением необязательного последнего &foo)
  • в LHS как назначение, например: a, b, *cs = [1,2,3,4]
  • в RHS присвоения, например: a, b, c = 1, 2, *[3,4,5]
  • в предложении when case case