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]