Где законно использовать оператор ruby splat?
Splats прохладно. Они не только для взрывающихся массивов, хотя это весело. Они также могут привести к массиву и сплющить массивы (см. 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
где может появиться splat в выражении?
2 ответов
во-первых, приоритет здесь не проблема, потому что 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])
будет splat после назначения и установить аргументы 1, 2 и 3 соответственно. Сравните это с foo((*bar = [1, 2, 3]))
который будет жаловаться на неправильное количество аргументов (1 для 3).
"оператор splat" на самом деле не оператор вообще, а токен, определенный в грамматике Ruby. A чтение грамматики.Y или грамматика Ruby в форме BNF* скажет вам, что это разрешено в качестве последнего или единственного аргумента:
- в определении метода (за исключением необязательного last
&foo
) - в вызове метода (за исключением необязательного last
&foo
) - на LHS назначения as, например:
a, b, *cs = [1,2,3,4]
- на RHS задание, например:
a, b, c = 1, 2, *[3,4,5]
- в предложении when оператора case