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

Я пытаюсь переписать команду для замены выходных файлов теми же файлами в другом каталоге, создавая карту перевода. В 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, потому что Rubocop говорит, что они злые, и я бы предпочел не использовать «Regexp.last_match», потому что он довольно многословен и превращает эту однострочную строку в блок выполнения.

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


person android.weasel    schedule 29.02.2016    source источник
comment
Вы можете использовать именованные совпадения с gsub, поэтому вам не нужно полагаться на $1 и $2. Передайте их блоку, как и любые другие аргументы блока.   -  person Mohamad    schedule 29.02.2016


Ответы (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, так как вы знаете, что делаете:

#rubocop:disable Style/PerlBackrefs
"-out AAA -out BBB".gsub(/(\s|^)(-out)\s+(\S+)/) do
  "#{$1}#{$2} BLOCK"
end
#rubocop:enable Style/PerlBackrefs
person Aleksei Matiushkin    schedule 29.02.2016
comment
Спасибо, в итоге я сделал последнее, но из вашего ответа я делаю вывод, что нет gsub, который предоставляет объект соответствия в качестве своего параметра? - person android.weasel; 29.02.2016
comment
Нет, к сожалению. Или, можно подумать, так задумано, поскольку у вас всегда есть доступ к глобальным $~, возвращающий последнее успешное совпадение. Поскольку ruby ​​был разработан как однопоточный, gsub, возвращающий последнее совпадение, кажется излишним. (Все вышесказанное — это только мои предположения.) - person Aleksei Matiushkin; 29.02.2016