Как насчет простого извлечения замены в качестве аргумента и инкапсуляции счетчика с помощью закрытия блока над ним внутри метода?
str = "aaaaaaaaaaaaaaa"
def replacements(replacement, limit)
count = limit
lambda { |original| if count.zero? then original else count -= 1; replacement end }
end
p str.gsub(/a/, &replacements("x", 5))
Вы можете сделать его еще более общим, используя блок для замены:
def limit(n, &block)
count = n
lambda do |original|
if count.zero? then original else count -= 1; block.call(original) end
end
end
Теперь вы можете делать такие вещи, как
p str.gsub(/a/, &limit(5) { "x" })
p str.gsub(/a/, &limit(5, &:upcase))