What are those pipe symbols for in Ruby?

What are the pipe symbols for in Ruby?

I'm learning Ruby and RoR, coming from a PHP and Java background, but I keep coming across code like this:

def new 
  @post = Post.new

  respond_to do |format|
    format.html # new.html.erb
    format.xml { render :xml => @post }
  end
end

What is the |format| part doing? What's the equivalent syntax of these pipe symbols in PHP/Java?


Solution 1:

They are the variables yielded to the block.

def this_method_takes_a_block
  yield(5)
end

this_method_takes_a_block do |num|
  puts num
end

Which outputs "5". A more arcane example:

def this_silly_method_too(num)
  yield(num + 5)
end

this_silly_method_too(3) do |wtf|
  puts wtf + 1
end

The output is "9".

Solution 2:

This was very strange to me too at first, but I hope this explanation/walkthru helps you.

The documentation touches the subject, in a quite good way - if my answer doesn't help I am sure their guide will.

First, fire up the Interactive Ruby interpreter by typing irb in your shell and hitting Enter.

Type something like:

the_numbers = ['ett','tva','tre','fyra','fem'] # congratulations! You now know how to count to five in Swedish.

just so that we have an array to play with. Then we create the loop:

the_numbers.each do |linustorvalds|
    puts linustorvalds
end

It will output all the numbers, separated by newlines.

In other languages you'd have to write something like:

for (i = 0; i < the_numbers.length; i++) {
    linustorvalds = the_numbers[i]
    print linustorvalds;
}

The important things to note are that the |thing_inside_the_pipes| can be anything, as long as you are using it consistently. And understand that it is loops we are talking about, that was a thing I didn't get until later on.

Solution 3:

@names.each do |name|
  puts "Hello #{name}!"
end

at http://www.ruby-lang.org/en/documentation/quickstart/4/ is accompanied by this explanation:

each is a method that accepts a block of code then runs that block of code for every element in a list, and the bit between do and end is just such a block. A block is like an anonymous function or lambda. The variable between pipe characters is the parameter for this block.

What happens here is that for every entry in a list, name is bound to that list element, and then the expression puts "Hello #{name}!" is run with that name.