Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to have a one line each block in Ruby?

Tags:

ruby

Is there a one-line method of writing this each block in Ruby?

cats.each do |cat|
   cat.name
end

I'm trying to shorten the amount of code in my project. I'm using Ruby 1.9.2.

Thanks!

like image 762
Goalie Avatar asked Jun 12 '12 07:06

Goalie


People also ask

Is it possible to use each and each in Ruby?

How does each work in Ruby? each is just another method on an object. That means that if you want to iterate over an array with each , you're calling the each method on that array object. It takes a list as it's first argument and a block as the second argument.

What does the .each method do in Ruby?

The each{} method allows one loop through the elements of an array to perform operations on them. It is an enumerator function that allows you to iterate over elements of an array and returns an array.

What does .first mean in Ruby?

The first() is an inbuilt method in Ruby returns an array of first X elements. If X is not mentioned, it returns the first element only. Syntax: range1.first(X) Parameters: The function accepts X which is the number of elements from the beginning. Return Value: It returns an array of first X elements.

Does Ruby have end blocks?

There are two ways of defining a block in Ruby: The first is using the do.. end keyword, the other is using a pair of curly braces. Do.. end block is mainly used when defining a block of code that spans multiple lines, while curly braces {} are used when defining a block of code that spans a single line.


3 Answers

Yes, you can write:

cats.each { |cat| cat.name }

Or simply:

cats.each(&:name)

Note that Enumerable#each returns the same object you are iterating over (here cats), so you should only use it if you are performing some kind of side-effect within the block. Most likely, you wanted to get the cat names, in that case use Enumerable#map instead:

cat_names = cats.map(&:name)
like image 174
tokland Avatar answered Oct 11 '22 06:10

tokland


Just remove the line breaks:

cats.each do |cat| cat.name end

Note, there are two different coding styles when it comes to blocks. One coding style says to always use do/end for blocks which span multiple lines and always use {/} for single-line blocks. If you follow that school, you should write

cats.each {|cat| cat.name }

The other style is to always use do/end for blocks which are primarily executed for their side-effects and {/} for blocks which are primarily executed for their return value. Since each throws away the return value of the block, it only makes sense to pass a block for its side-effects, so, if you follow that school, you should write it with do/end.

But as @tokland mentions, the more idiomatic way would be to write

cats.each(&:name)
like image 27
Jörg W Mittag Avatar answered Oct 11 '22 08:10

Jörg W Mittag


Another trick which I use for rails console/irb is to separate commands with ';' e.g.

[1,2].each do |e| ; puts e; end
like image 16
Zaharije Avatar answered Oct 11 '22 07:10

Zaharije