Ответ 3
Существует несколько способов обработки чего-то, подобного макросу C в Perl: исходный фильтр, подпрограмма, Template:: Toolkit или использование функций в вашем текстовом редакторе.
Фильтры источника
Если у вас есть макрос препроцессора стиля C/CPP, можно записать его на Perl (или, фактически, на любом языке), используя прекомпиляцию исходный фильтр. Вы можете написать довольно простые сложные классы Perl, которые работают с текстом исходного кода и выполняют преобразования на нем до того, как код перейдет к компилятору Perl. Вы даже можете запустить свой Perl-код непосредственно через препроцессор CPP, чтобы получить точный тип расширений макросов, которые вы получаете в C/CPP, используя Filter:: CPP.
Дамиан Конвей Фильтр:: Простой является частью дистрибутива ядра Perl. С Filter:: Simple вы можете легко написать простой модуль для выполнения макроса, который вы описываете. Пример:
package myopinion;
# save in your Perl @INC path as "myopinion.pm"...
use Filter::Simple;
FILTER {
s/Hogs/Pigs/g;
s/Hawgs/Hogs/g;
}
1;
Затем файл Perl:
use myopinion;
print join(' ',"Hogs", 'Hogs', qq/Hawgs/, q/Hogs/, "\n");
print "In my opinion, Hogs are Hogs\n\n";
Вывод:
Pigs Pigs Hogs Pigs
In my opinion, Pigs are Pigs
Если вы переписали FILTER, чтобы сделать замену для нужного вам макроса, Filter:: Simple должен работать нормально. Фильтр:: Простой может быть ограничен частями вашего кода для подстанций, таких как исполняемая часть, но не часть POD; только в строках; только в коде.
Исходные фильтры в моем опыте широко не используются. Я в основном видел их с хромыми попытками зашифровать исходный код Perl или юмористический Perl obfuscators. Другими словами, я знаю, что это можно сделать таким образом, но я лично не знаю достаточно о них, чтобы рекомендовать их или сказать, что не использовать их.
Подпрограммы
Sinan Ünür подпрограмма openex - это хороший способ сделать это. Я только добавлю, что общая устаревшая идиома, которую вы увидите, включает передачу ссылки на типglob следующим образом:
sub opensesame {
my $fn=shift;
local *FH;
return open(FH,$fn) ? *FH : undef;
}
$fh=opensesame('> /tmp/file');
Прочитайте perldata, почему именно так...
Инструментарий шаблонов
Template:: Toolkit можно использовать для обработки исходного кода Perl. Например, вы можете написать шаблон по строкам:
[% fw(fp, outfile) %]
выполняемый через Template:: Toolkit, может привести к расширению и замене на:
open my $FP, '>', $outfile or die "$outfile could not be opened for writing:$!";
Template:: Toolkit чаще всего используется для ветки беспорядочного HTML и другого кода презентации от кода приложения в веб-приложениях. Template:: Toolkit очень активно развивается и хорошо документируется. Если ваше единственное использование - это макрос типа, который вы предлагаете, это может быть излишним.
Текстовые редакторы
Чес. Owens использует метод с помощью Vim. Я использую BBEdit и могу легко написать Text Factory, чтобы заменить скелет открытого с точным и развивающимся открытым, который я хочу использовать. В качестве альтернативы вы можете поместить шаблон завершения в свой каталог "Ресурсы" в папке "Perl". Эти скелеты завершения используются, когда вы нажимаете серию ключей, которые вы определяете. Почти любой серьезный редактор будет иметь аналогичную функциональность.
С BBEdit вы даже можете использовать код Perl в логике замены текста. Я использую Perl:: Critic таким образом. Вы можете использовать Template::Toolkit
внутри BBEdit для обработки макросов с помощью некоторого интеллекта. Его можно настроить таким образом, чтобы исходный код не изменялся шаблоном, пока вы не выведете версию для проверки или компиляции; редактор, по сути, выступает в качестве препроцессора.
Две потенциальные проблемы с использованием текстового редактора. Во-первых, это одностороннее/однократное преобразование. Если вы хотите изменить то, что делает ваш "макрос", вы не можете этого сделать, поскольку предыдущий текст "макрос" уже использовался. Вы должны вручную изменить их. Вторая потенциальная проблема заключается в том, что если вы используете форму шаблона, вы не можете отправить макрокоманду исходного кода кому-то другому, поскольку предварительная обработка выполняется внутри редактора.
Не делай этого!
Если вы введете perl -h
, чтобы получить допустимые командные переключатели, выберите один из следующих вариантов:
-P run program through C preprocessor before compilation
Заманчиво! Да, вы можете запустить свой Perl-код через препроцессор C и развернуть макросы стиля C и иметь #defines
. Положите это оружие; уходи; не делай этого. Существует много несовместимости с платформой и языковая несовместимость.
У вас возникают такие проблемы:
#!/usr/bin/perl -P
#define BIG small
print "BIG\n";
print qq(BIG\n);
Отпечатки:
BIG
small
В Perl 5.12 переключатель -P
удален...
Заключение
Самое гибкое решение здесь - это просто написать подпрограмму. Весь ваш код отображается в подпрограмме, легко изменяется и короче. Никакой реальный недостаток, отличный от читаемости вашего кода, возможно.
Template:: Toolkit широко используется. Вы можете написать сложные замены, которые действуют как макросы или даже более сложные, чем макросы C. Если ваша потребность в макросах стоит кривая обучения, используйте Template:: Toolkit.
Для очень простых случаев используйте односторонние преобразования в редакторе.
Если вам действительно нужны макросы стиля C, вы можете использовать Filter:: CPP. Это может иметь ту же несовместимость, что и переключатель perl -P
. Я не могу рекомендовать это; просто изучите способ Perl.
Если вы хотите запустить Perl один лайнер и регулярные выражения Perl против вашего кода перед компиляцией, используйте Filter:: Simple.
И не используйте переключатель -P
. В любом случае вы не можете использовать новые версии Perl.