2012-03-30 2 views
1

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

документация 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 

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

ответ

5

Возможно, вы уже знаете, что в идиоматическом Ruby никогда не будет вставлено пространство между концом метода и списком аргументов в скобках. Some руководства по стилю explicitly forbid it.

Существует также прагматичная причина.

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 ожидает стиль «no-parens». Поэтому, конечно, это работает:

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

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

3

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

foo (bar, baz) 

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

foo (bar) 

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

foo (if bar then baz else quux end) 

будет работать, тоже.

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

foo(bar, baz) 

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

 Смежные вопросы

  • Нет связанных вопросов^_^