Explain Iterator Syntax on Ruby on Rails

前端 未结 7 1072
慢半拍i
慢半拍i 2021-01-20 03:25

I started learning Ruby on Rails and found myself confounded by the syntax, so I had to read about somet of the Ruby syntax. I learned the syntax from http://www.cs.auckland

7条回答
  •  情话喂你
    2021-01-20 04:08

    method_call do [`|' expr...`|'] expr...end
    

    Is not limited to iteration functions.

    In ruby, any method can take a block as an argument. The block can then be called by the method. In the case of an iterator, the method looks something like this:

    def iter
      for i in [:x,:y,:z]
        yield i
      end
    end
    

    If you call iter with a block, it will loop over [:x, :y, :z] and yield each of them to the block, which can then do whatever you want. e.g. to print them out:

    iter { |z| puts z }
    

    You can also use this to hide init and cleanup steps, like opening and closing files. e.g. File.open. File.open, if it were implemented in pure ruby(it's in C for performance) would do something like this.

    def File.open filename, opts
      f = File.new filename, opts
      yield f
      f.close
    end
    

    Which is why you can use

    File.open 'foobar', 'w' do |f|
      f.write 'awesome'
    end
    

    respond_to is similar. It works something like this:( check out the real implementation here)

       def respond_to
         responder = Responder.new(self)
         block.call(responder)
         responder.respond
       end
    

    It creates a responder object that has methods like html that take a block and passes it to you. This turns out to be really handy, because it lets you do things like:

    def action
      @foo = Foo.new params[:foo]
      respond_to do |format|
        if @foo.save
          format.html { redirect_to foo_path @foo }
          format.xml { render :xml => @foo.to_xml }
        else
          flash[:error] = "Foo could not be saved!"
          format.html { render :new }
          format.xml { render :xml => {:errors => @foo.errors }.to_xml}
        end
      end
    end
    

    See how I change the behavior dependent on save inside the block? Doing this would be much more annoying without it.

提交回复
热议问题