From: Andrew Stewart Date: 2008-01-18T02:12:44+09:00 Subject: Re: Ruby syntax in "respond_to do |format| line -- can clarify? On 17 Jan 2008, at 16:21, Joshua Beall wrote: > respond_to do |format| > format.html # index.html.erb > format.xml { render :xml => @posts } > end > > But I still don't understand where |format| is coming from, or what > it's > doing. From what I've seen in Ruby, I think of something like | > format| > as being part of a foreach type block. As in > "possible_formats.each do > |format|". Take heart, the code isn't entirely obvious if you're unfamiliar with Ruby! The format between the pipes ("|format|") at the start of the block is a block variable. It could be called anything though the convention is to use "format". When respond_to was first introduced lots of people used "wants" to make the code in the block read nicely and it almost prevailed. Anyway, the block variable is set within the respond_to method: http://dev.rubyonrails.org/browser/trunk/actionpack/lib/ action_controller/mime_responds.rb#L102 module ActionController module MimeResponds module InstanceMethods def respond_to(*types, &block) raise ArgumentError, "respond_to takes either types or a block, never both" unless types.any? ^ block block ||= lambda { |responder| types.each { |type| responder.send(type) } } responder = Responder.new(self) block.call(responder) responder.respond end class Responder # ... end end end end The &block in the respond_to method's signature is set to the do...end block from your snippet. The first two lines of the method are irrelevant to your situation. The third line creates an object that can respond appropriately to different mime types. The fourth line is the one you're interested in: it executes the block, passing in the responder object. So if you look at your block again: do |format| format.html format.xml end ...and you imagine executing it as a method, the block variable, format, should look like a method argument. Accordingly it is set to the responder object passed in by the line: block.call(responder) Thus the format.html and format.xml lines in the block are sending :html and :xml messages to the object in format, i.e. to responder. As it happens responder doesn't have an html method, nor an xml method, so these calls are handled by its method_missing method. http://dev.rubyonrails.org/browser/trunk/actionpack/lib/ action_controller/mime_responds.rb#L139 I recommend reading up on blocks and procs. Here's one article to get you started: http://onestepback.org/index.cgi/Tech/Ruby/RubyBindings.rdoc Regards, Andy Stewart ------- http://airbladesoftware.com