On 17 Jan 2008, at 20:11, Joshua Beall wrote:
> However, there are still
> somethings I don't understand.  Why can't I do this?
>
>     responder.xml( { render :xml => @posts} )

The syntax for a new hash and the syntax for a block can look the  
same -- { ... } -- so you have to help Ruby's interpreter deduce  
which one you want.

Your line above says send the :xml message (i.e. call the xml method)  
with a new hash as the argument.  (Assuming that the result of render 
(:xml => @posts) can be constructed as a hash.)

It doesn't work because the method that handles this call,  
method_missing, doesn't want a hash.  It wants a block.  So you need  
to write this instead:

   responder.xml() { render :xml => @ posts }

Or this:

   responder.xml { render :xml => @posts }

Or this:

   responder.xml do
     render :xml => @posts
   end

etc.

How do we know Responder's method_missing wants a block?  From its  
signature:

   def method_missing(symbol, &block)

The way method_missing works in Ruby, the symbol argument is set to  
the symbolised name of the method that's missing.  In your case, this  
is :xml.  The only other argument specified is &block, so that's what  
the method_missing needs.


> Second, from this line here:
> http://dev.rubyonrails.org/browser/trunk/actionpack/lib/ 
> action_controller/mime_responds.rb#L102
>
> Can you help me understand this line:
> block ||= lambda { |responder| types.each { |type| responder.send 
> (type)
> } }
>
> It looks like it would be overwriting the "block" parameter of the
> "respond_to" method -- and yet apparently it is not?

The ||= syntax is equivalent to += and friends.  In the same way that :-

this:              x += 1
is shorthand for:  x = (x + 1)

You can see that :-

this:              block ||= ...
is shorthand for:  block = (block || ... )

So it means set block to ... unless it's already set to something.   
In your situation respond_to is called with a block, so the line  
doesn't change anything.  The line is there to set the block variable  
if respond_to is called with an array instead of a block.

Regards,
Andy Stewart

-------
http://airbladesoftware.com