Is there a default block argument in Ruby?

Viewed 442

I am just starting to do Groovy after mostly doing ruby.

It has a default 'block argument', it, as it were, not officially the terminology for Groovy, but I'm new to Groovy.

(1..10).each {println(it)}

What about Ruby? Is there a default I can use so I don't have to make |my_block_arg| every time?

Thanks!

3 Answers

No, you don't have a "default" in Ruby.

Though, you can do

(1..10).each(&method(:puts))

Like Andrey Deinekos answer explained there is no default. You can set the self context using BasicObject#instance_eval or BasicObject#instance_exec. I don't recommend doing this since it can sometimes result in some unexpected results. However if you know what you're doing the following is still an option:

class Enumerator
  def with_ie(&block)
    return to_enum(__method__) { each.size } unless block_given?
    each { |e| e.instance_eval(&block) }
  end
end

(1..10).each.with_ie { puts self }
# 1
# 2
# 3
# 4
# 5
# 6
# 7
# 8
# 9
# 10
#=> 1..10

(1..10).map.with_ie { self * self }
#=> [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
(-5..5).select.with_ie { positive? }
#=> [1, 2, 3, 4, 5]

If you want to call one method you might as well do (-5..5).select(&:positive?), but when the objects you're iterating over have actual attributes it might be worth the trouble. For example:

people.map.with_ie { "#{id}: #{first_name} - #{last_name}" }

Keep in mind that if you have an local variable id, first_name or last_name in scope those are used instead of the methods on the object. This also doesn't quite work for hashes or Enumerable methods that pass more than one block argument. In this case self is set to an array containing the arguments. For example:

{a: 1, b: 2}.map.with_ie { self }
#=> [[:a, 1], [:b, 2]]
{a: 1, b: 2}.map.with_ie { self[0] }
#=> [:a, :b]

From Ruby 2.7 onwards, you can use numbered block arguments:

(1..10).each { puts _1 }

Granted, this hasn't been very well documented; some references are still using @1, but the above is tested on the official 2.7 version.

Related