Мне нравится Андрей Дейнекос ответ объяснил, что по умолчанию нет.Вы можете установить контекст self
, используя BasicObject # instance_eval или BasicObject # instance_exec .Я не рекомендую делать это, поскольку иногда это может привести к неожиданным результатам.Однако, если вы знаете, что делаете, по-прежнему возможна следующая опция:
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]
Если вы хотите вызвать один методс тем же успехом вы можете сделать (-5..5).select(&:positive?)
, но когда объекты, которые вы перебираете, имеют действительные атрибуты, это может стоить проблем.Например:
people.map.with_ie { "#{id}: #{first_name} - #{last_name}" }
Имейте в виду, что если у вас есть локальная переменная id
, first_name
или last_name
в области видимости, они используются вместо методов объекта.Это также не совсем подходит для хэшей или Enumerable методов, которые передают более одного аргумента блока.В этом случае self
устанавливается в массив, содержащий аргументы.Например:
{a: 1, b: 2}.map.with_ie { self }
#=> [[:a, 1], [:b, 2]]
{a: 1, b: 2}.map.with_ie { self[0] }
#=> [:a, :b]