Why can't I call this without parentheses?

I have a little helper that lets me add legacy fields to models where
they have common prefixes, suffixes, or something else weird. Here is
the method signature:

def legacy_fields(options = {}, *attributes)

end

options is a hash containing things like :prefix => “post_” - and
attributes is a list of attribute names. This gets mixed into the
class with extend, so I call it much like the attr* methods. Can
someone explain why I get syntax errors if I try to call this method
like this (which is how I want to call it to be consistent with
rails):

legacy_fields :prefix = “post_”, :author, :title

or even this:

legacy_fields {:prefix = “post_”}, :author, :title

but this works fine:

legacy fields({:prefix = “post_”}, :author, :title)

The signature looks similar to things like link_to and url_for, which
can be called without parentheses. Any idea of what I’m missing?

thanks,
Rob

The thing is, the full anatomy of a Ruby method call is:

receiver.method_name(arg1, arg2, …) { code block }

You need the parens when your first argument is a literal hash,
because otherwise it will be assumed to be a code block.

David

Ah that makes sense. I have your book David, and enjoyed it quite a
bit, btw. Apparently I should re-read some parts of it. :slight_smile: So,
basically having a hash as the first parameter just means you always
need parens, right?

  • rob

Hi –

On Mon, 26 Jun 2006, Rob S. wrote:

class with extend, so I call it much like the attr* methods. Can
but this works fine:

legacy fields({:prefix = “post_”}, :author, :title)

The signature looks similar to things like link_to and url_for, which
can be called without parentheses. Any idea of what I’m missing?

The thing is, the full anatomy of a Ruby method call is:

receiver.method_name(arg1, arg2, …) { code block }

You need the parens when your first argument is a literal hash,
because otherwise it will be assumed to be a code block.

David


David A. Black ([email protected])
Ruby Power and Light, LLC (http://www.rubypowerandlight.com)

See what the readers are saying about “Ruby for Rails”!

On Jun 26, 2006, at 1:46 PM, Rob S. wrote:

Ah that makes sense. I have your book David, and enjoyed it quite a
bit, btw. Apparently I should re-read some parts of it. :slight_smile: So,
basically having a hash as the first parameter just means you always
need parens, right?

Yes, except in the case where your last parameter is a hash, in
which case you need not add the braces since Ruby will gracefully let
you pass in the hash, almost like named parameters:

def receiver.method_name(arg1, arg2 = {}); end

receiver.method_name “duane”, :a => 1, :b => 2

arg1 = “duane”

arg2 = {:a => 1, :b => 2}

Duane J.
(canadaduane)
http://blog.inquirylabs.com/

It might also be worth pointing out that your arguments aren’t
formatted correctly, i.e.

legacy fields({:prefix = “post_”}, :author, :title)

should really by

legacy_fields({:prefix => “post_”}, :author, :title)

=>, not =

  • james