Где разрешено использовать оператор рубиновых сплатов? - PullRequest
18 голосов
/ 22 апреля 2009

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

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

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

Принимая во внимание, что это работает:

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

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

Ответы [ 2 ]

15 голосов
/ 22 апреля 2009

Во-первых, приоритет здесь не проблема, потому что foo = bar || (*zap) работает не лучше. Основное правило заключается в том, что вы не можете выполнять дополнительные операции с восклицательным знаком. Даже что-то простое, например 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). Это показывает, насколько низок приоритет сплата. Точно, как низко это? Лучший ответ, который я могу вам дать - «довольно низкий».

Для интересного примера рассмотрим метод 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).

8 голосов
/ 08 апреля 2011

«Оператор сплат» на самом деле вовсе не оператор, а токен, определенный в грамматике Ruby. Прочтенный grammar.y или грамматика Ruby в форме BNF * скажет вам, что это разрешено в качестве последнего или единственного аргумента:

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