Метод Ruby Kernel.raise выдает ошибку при заключении параметров в круглые скобки - PullRequest
1 голос
/ 30 марта 2012

Мне нравятся параметры метода, заключенные в круглые скобки, это некоторая ностальгия по Паскалю. При очистке кода, если я нахожу параметры метода без него, я немедленно заключаю их. Сегодня это вызвало ошибки при работе моего рабочего кода, хотя мой синтаксис выглядит нормально в соответствии с документацией.

Документация Kernel.raise имеет следующий формат:

(Object) raise(exception[, string [, array]])

Это все работает:

> raise TypeError
TypeError: TypeError

> raise (TypeError)
TypeError: TypeError

> raise "Error message"
RuntimeError: Error message

> raise ("Error message")
RuntimeError: Error message

Но вложенная версия следующей синтаксической ошибки выдает:

> raise TypeError, "Error message"
TypeError: Error message

> raise (TypeError, "Error message")
SyntaxError: unexpected ')', expecting $end

Я могу жить без этого, я просто хочу знать, почему это заканчивается ошибкой.

Ответы [ 2 ]

5 голосов
/ 30 марта 2012

Вы, наверное, уже знаете, что в идиоматическом Ruby никогда не будет вставляться пробел между концом метода и списком аргументов в скобках. Некоторые руководства по стилю явно запрещают это .

Есть и прагматическая причина.

1.9.2-p290 > def concat(a, b)
1.9.2-p290 >  a + b
1.9.2-p290 > end

1.9.2-p290 > concat 'foo', 'bar'
 => "foobar"
1.9.2-p290 > concat('foo', 'bar')
 => "foobar"
1.9.2-p290 > concat ('foo', 'bar')
SyntaxError: (irb):27: syntax error, unexpected ',', expecting ')'

Вы столкнетесь с ошибками при вызове любого метода, а не только Kernel.raise.

Я не знаком с внутренними компонентами Ruby, но я предполагаю, что причина этого в том, что когда пробел предшествует списку аргументов, Ruby ожидает стиль "без паренов" Так что, конечно, это работает:

1.9.2-p290 :035 > concat ("bar"), ("foo")
 => "barfoo"

Предположительно, Ruby пытается оценить содержимое каждого выражения в скобках перед передачей результата в метод. Я бы предположил, что для написания raise (TypeError, "Error message") требуется, чтобы Ruby вычислил только TypeError, "Error message", что, конечно, не помогает.

3 голосов
/ 30 марта 2012

Круглые скобки используются для группировки выражений и переопределения приоритетов в Ruby. Итак, когда вы говорите

foo (bar, baz)

Вы отправляете сообщение :foo с одним аргументом, который является результатом вычисления выражения bar, baz. И bar, baz не является допустимым выражением, поэтому вы получаете SyntaxError.

foo (bar)

работает, потому что bar является допустимым выражением.

foo (if bar then baz else quux end)

тоже подойдет.

Если вы хотите, чтобы Ruby интерпретировал скобки не для группировки выражений, а для передачи нескольких аргументов вместе с отправкой сообщения, открывающая скобка должна следовать непосредственно за селектором сообщения:

foo(bar, baz)

Это не имеет ничего общего с Kernel#raise, кстати. Вы не можете изменить синтаксис для отправки сообщений в Ruby (на самом деле, вы не можете изменить любой синтаксис в Ruby), поэтому все, что верно для Kernel#raise, также должно быть истинным для любого другого метода.

...