Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

mysterious ruby syntax error

i'm beyond confused: this is almost a copy/paste out of a RoR action mailer guide, and yet it throws a syntax error:

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

the error is:

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, } ^

any ideas? i can't figure out what i'm doing wrong here.

like image 949
kolosy Avatar asked Dec 27 '10 18:12

kolosy


2 Answers

Add parentheses body({...}) to state explicitly you're doing a method call with hash argument.

Otherwise, {...} is probably confused with function (or lambda, whatever's the official term) being passed in the body method: body { puts "Hello world!" }

like image 180
Nikita Rybak Avatar answered Sep 25 '22 08:09

Nikita Rybak


Remove the { and } from the call(1) to #body.


(1) Update: This error happens because { } has two different meanings in Ruby: Hash value expressions and method blocks. If a procedure is called in poetry mode (no parens) then there is an ambiguity if the parser encounters a { after a method name. Is it the start of a block or is it a parameter that is a Hash expression? The assumption, an unfortunate one in your specific case, is that it's a block.

Now, as it happens, Ruby does not require { } around Hash expressions when the hash is the final argument to a method. So the result is that there are at least two ways of resolving this issue: (1) remove the { and the } -- Ruby understands that you are passing a Hash parameter; or (2) add the method parens. Seeing as how Rails is usually used in poetry mode, it seems to make sense to remove characters and take advantage of the clever Ruby parser rather than add them back a la C or Java.

like image 32
DigitalRoss Avatar answered Sep 25 '22 08:09

DigitalRoss