Загадочная синтаксическая ошибка рубина

Я не смущен: это почти копия/вставка из руководства по расписанию действий RoR, и все же он выдает синтаксическую ошибку:

class Contact < ActionMailer::Base


  def contact a_name, a_company, a_phone, a_email, a_comments
    subject    "Contact request from #{name}"
    recipients "[email protected]"
    from       "[email protected]"
    sent_on    Time.now
    body       { :name => a_name, :company => a_company, :phone => a_phone, :email => a_email, :comments => a_comments }
  end

end

ошибка:

app/models/contact.rb:9: syntax error, unexpected tASSOC, expecting '}' body { :name => a_name, :company => a_company... ^ app/models/contact.rb:9: syntax error, unexpected tASSOC, expecting tCOLON2 or '[' or '.' ...{ :name => a_name, :company => a_company, :phone => a_phone,... ^ app/models/contact.rb:9: syntax error, unexpected tASSOC, expecting tCOLON2 or '[' or '.' ...ompany => a_company, :phone => a_phone, :email => a_email, :... ^ app/models/contact.rb:9: syntax error, unexpected tASSOC, expecting tCOLON2 or '[' or '.' ..., :phone => a_phone, :email => a_email, :comments => a_comme... ^ app/models/contact.rb:9: syntax error, unexpected tASSOC, expecting tCOLON2 or '[' or '.' ...email => a_email, :comments => a_comments, } ^

любые идеи? Я не могу понять, что я делаю неправильно здесь.

Ответы

Ответ 1

Добавьте круглые скобки body({...}), чтобы явно указать, что вы выполняете вызов метода с аргументом hash.

В противном случае {...}, вероятно, путают с функцией (или лямбдой, независимо от официального термина), передаваемой в методе body: body { puts "Hello world!" }

Ответ 2

Удалите { и } из вызова (1) до #body.


(1) Обновление: Эта ошибка возникает из-за того, что { } имеет два разных значения в Ruby: выражения хэш-значения и блоки методов. Если процедура вызывается в режиме поэзии (нет парен), тогда возникает неопределенность, если парсер встречает { после имени метода. Является ли это началом блока или это параметр, который является выражением Hash? Предположение, неудачное в вашем конкретном случае, состоит в том, что это блок.

Теперь, как это бывает, Ruby не требует { } вокруг выражений Hash, когда хеш является последним аргументом метода. Таким образом, результат состоит в том, что существует как минимум два способа решения этой проблемы: (1) удалить { и } - Ruby понимает, что вы передаете параметр Hash; или (2) добавить метод parens. Видя, как Rails обычно используется в режиме поэзии, кажется, имеет смысл удалить символы и использовать умный анализатор Ruby вместо того, чтобы добавить их обратно в la C или Java.