Где разрешено использовать оператор рубиновых сплатов?

Знаки классные. Они не только для взрывающихся массивов, хотя это весело. Они также могут приводить к массивам и выравнивать массивы (полный список того, что они делают, см. На 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 ответа

Решение

Во-первых, приоритет не является проблемой здесь, потому что 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), Если это не распространяется на ваш случай, вы, вероятно, должны спросить себя, чего вы действительно надеетесь достичь, написав такую ​​уродливую конструкцию.


РЕДАКТИРОВАТЬ:

В ответ на ваши комментарии, *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).

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

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