One of the reasons why Ruby is my favorite language is that it has many shortcuts and can do a lot with a few lines of code. & (ampersand) operator is one great example.
A quick explanation of how & works in Ruby:
# These two calls are equivalent:
numbers.select { |number| number.even? }
numbers.select(&:even?)
& calls the to_proc method on the following object which is a symbol :even? in the example above. (the to_proc method is implemented on symbols.) This means the object will be encapsulated as a block of code (as a Proc object), and then passed to the given method.
This might still look weird to you as it did to me in the beginning because .even? is a built-in method in Ruby. Why can I use it as a symbol? This works because method names in Ruby are internally stored as symbols. For the same reason, you can use this & shortcut for the methods you define as well.
Let's see the examples with Ruby Enumerable that you use everyday:
  
  
  1. find
# Returns the first admin user
# BAD
def find_admin(users)
  users.find { |user| user.admin? }
end
# GOOD
def find_admin(users)
  users.find(&:admin?)
end
  
  
  2. select
# Returns all the admin users
# BAD
def find_admins(users)
  admins = []
  users.each do |user|
    admins << user if user.admin?
  end
  admins
end
# GOOD
def find_admins(users)
  users.select(&:admin?)
end
  
  
  3. count
# Returns the number of the admin users
# BAD
def count_admin(users)
  count = 0
  users.each do |user|
    count += 1 if user.admin?
  end
  count
end
# GOOD
def count_admin(users)
  users.count(&:admin?)
end
  
  
  4. map
# Returns an array of each user's name
# BAD
def user_names(users)
  names = []
  users.each do |user|
    names << user.name
  end
  names
end
# GOOD
def user_names(users)
  users.map(&:name)
end
  
  
  5. any?
# Returns true if at least one user exists.
# BAD
def contains_nil?(users)
  users.each do |user|
    return true if user.nil?
  end
  false
end
# GOOD
def contains_nil?(users)
  users.any?(&:nil?)
end
  
  
  6. max/max_by
# Returns the oldest user.
# BAD
def oldest_user(users)
  oldest = nil
  users.each do |user|
    oldest = user if oldest.nil? || user.age > oldest.age
  end
  oldet
end
# GOOD
def oldest_user(users)
  users.max_by(&:age)
end
Knowing this, when you iterate over an array using a block where you simply return object.method, you will notice code smells and consider using & operator instead.

    
Top comments (2)
Nice list of methods to use !!! Thank you
Thank you for reading!