Что такое Ruby-эквивалент для Perl s{}{}e?

Я пытаюсь переписать команду для замены выходных файлов теми же файлами в другом каталоге, создавая карту перевода. В Perl я мог бы сделать что-то вроде этого:

s{(-o|--out)\s((?:\S+\/)?(\S+))}{ "$1 " . ($m{$2}="foo/$3") }eg

Мне не понятно, как сделать то же самое под Ruby, потому что:

"-out AAA -out yeah/BBB".
gsub(/((?:\s|^)-out)\s+((?:\S+\/)?(\S+))/) { |f|
  "#{f[1]} #{m[f[2]] = "temp/#{f[3]}"}"
}

результаты в

"o temp/t- temp/u"

потому что 'm' это совпадающая строка, а не совпадающий объект, поэтому #{m[1]} это просто второй символ совпадающей строки.

Я не хочу использовать $1, $2 потому что Рубокоп говорит, что они злые, и я бы предпочел не использовать "Regexp.last_match", потому что он довольно многословен и превращает этот однострочный блок в do-блок.

Разве нет встроенного, который дает мне объект соответствия в качестве параметра?

1 ответ

Решение

Раз ты не хочешь использовать $1 как и в Perl, вы можете использовать именованные совпадения:

"-out AAA -out BBB".gsub(/(?<leading>\s|^)(?<out>-out)\s+(?<rest>\S+)/) do
  "#{$~[:leading]}#{$~[:out]} BLOCK"
end
#⇒ "-out BLOCK -out BLOCK"

Другой вариант - закрыть рубокоп, так как вы знаете, что делаете:

#rubocop:disable Style/PerlBackrefs
"-out AAA -out BBB".gsub(/(\s|^)(-out)\s+(\S+)/) do
  "#{$1}#{$2} BLOCK"
end
#rubocop:enable Style/PerlBackrefs
Другие вопросы по тегам