Скрытые возможности Perl?

150

Каковы некоторые действительно полезные, но эзотерические языковые функции в Perl, которые вы действительно смогли использовать для полезной работы?

Руководство:

  • Попробуйте ограничить ответы на ядро ​​Perl, а не CPAN
  • Приведите пример и краткое описание

Скрытые функции также найдены на других языках. Скрытые функции:

(Все они из Corion answer)

  • C
    • Устройство Duff
    • Переносимость и стандартность
  • С#
    • Цитаты для списков и строк с разделителями пробелов
    • Простые пространства имен
  • Java
    • Статические инициаторы
  • JavaScript
    • Функции являются гражданами первого класса.
    • Область и закрытие блока
    • Вызов методов и аксессуаров косвенно через переменную
  • Ruby
    • Определение методов с помощью кода
  • PHP
    • Прорывная онлайн-документация
    • Магические методы
    • Символьные ссылки
  • Python
    • Обмен одной строкой
    • Возможность заменить даже основные функции своей собственной функциональностью

Другие скрытые функции:

Операторы:

Цитаты конструкций:

Синтаксис и имена:

Модули, Pragmas и параметры командной строки:

Переменные

Циклы и управление потоком:

Регулярные выражения:

Другие функции:

Другие трюки и мета-ответы:


См. также:

  • 0
    Почему плитка "скрытые возможности"? как некоторые из этих функций хорошо документированы
  • 0
    Этот вопрос опоздал на набор вопросов «Скрытые возможности». Все они имеют похожую схему именования. Что касается самих ответов, возможно, они не скрыты, но название уже установлено. Вы всегда можете понизить голос, что вы считаете слишком очевидным (CW, так что без штрафа :)
Показать ещё 5 комментариев
Теги:
hidden-features

77 ответов

54

Оператор триггера полезен для пропуски первой итерации при прокрутке записей (обычно строк), возвращаемых дескриптором файла, без использования переменной флага:

while(<$fh>)
{
  next if 1..1; # skip first record
  ...
}

Запустите perldoc perlop и найдите "флип-флоп" для получения дополнительной информации и примеров.

  • 0
    На самом деле это взято из Awk, где вы можете сделать триггер между двумя шаблонами, написав pattern1, pattern2
  • 15
    Чтобы уточнить, «скрытый» аспект этого заключается в том, что если любой из операндов для скалярного «..» является константой, значение неявно сравнивается с номером строки ввода ($.)
47

В Perl существует много неочевидных функций.

Например, знаете ли вы, что после сигилы может быть пробел?

 $ perl -wle 'my $x = 3; print $ x'
 3

Или что вы можете указывать числовые имена субтитров, если вы используете символические ссылки?

$ perl -lwe '*4 = sub { print "yes" }; 4->()' 
yes

Также существует квази-оператор "bool", который возвращает 1 для истинных выражений и пустую строку для false:

$ perl -wle 'print !!4'
1
$ perl -wle 'print !!"0 but true"'
1
$ perl -wle 'print !!0'
(empty line)

Другие интересные вещи: с помощью use overload вы можете перегрузить строковые литералы и числа (и, например, сделать их BigInts или что-то еще).

Многие из этих вещей фактически документированы где-то или логически следуют из документированных функций, но, тем не менее, некоторые из них не очень хорошо известны.

Обновление: еще один приятный. Ниже были указаны конструкции цитат q{...}, но знаете ли вы, что вы можете использовать буквы как разделители?

$ perl -Mstrict  -wle 'print q bJet another perl hacker.b'
Jet another perl hacker.

Аналогичным образом вы можете писать регулярные выражения:

m xabcx
# same as m/abc/
  • 2
    «Знаете ли вы, что после сигил может быть место?» Я совершенно ошеломлен. Вот это да.
  • 1
    Здорово! !! $ undef_var не создает предупреждение.
Показать ещё 3 комментария
44

Добавить поддержку сжатых файлов с помощью magic ARGV:

s{ 
    ^            # make sure to get whole filename
    ( 
      [^'] +     # at least one non-quote
      \.         # extension dot
      (?:        # now either suffix
          gz
        | Z 
       )
    )
    \z           # through the end
}{gzcat '$1' |}xs for @ARGV;

(кавычки вокруг $_ необходимы для обработки имен файлов с метасимволами оболочки)

Теперь функция <> распакует любые файлы @ARGV, которые заканчиваются на ".gz" или ".Z":

while (<>) {
    print;
}
  • 5
    Это круто на разных уровнях ...
  • 2
    Я не думаю, что вам нужно избежать | в замену.
Показать ещё 2 комментария
42

Одна из моих любимых функций в Perl - использование логического оператора || для выбора между набором вариантов.

 $x = $a || $b;

 # $x = $a, if $a is true.
 # $x = $b, otherwise

Это означает, что можно написать:

 $x = $a || $b || $c || 0;

чтобы принять первое истинное значение из $a, $b и $c, или по умолчанию 0 в противном случае.

В Perl 5.10 существует также оператор //, который возвращает левую сторону, если он определен, а в правой части - в противном случае. Следующее выбирает первое определенное значение из $a, $b, $c или 0 в противном случае:

$x = $a // $b // $c // 0;

Они также могут использоваться с их короткими формами, которые очень полезны для предоставления значений по умолчанию:

$x ||= 0;   # If $x was false, it now has a value of 0.

$x //= 0;   # If $x was undefined, it now has a value of zero.

Cheerio,

Пол

  • 0
    Эти операторы являются находкой для сокращения стандартного кода
  • 4
    Это настолько распространенная идиома, что она вряд ли может рассматриваться как «скрытая» особенность.
Показать ещё 6 комментариев
40

Операторы ++ и унарные - работают не только на числах, но и на строках.

my $_ = "a"
print -$_

печатает -a

print ++$_

печатает b

$_ = 'z'
print ++$_

печатает aa

  • 3
    Процитируем perlvar: «Оператор автоматического декремента не волшебен». Так что -- не работает на строках.
  • 0
    «аа» не кажется естественным элементом после «z». Я ожидал бы следующее самое высокое значение ascii, которое "{".
Показать ещё 4 комментария
36

Поскольку Perl имеет почти все "эзотерические" части из других списков, я расскажу вам одну вещь, которую Perl не может:

Единственное, что Perl не может сделать, это иметь произвольные URL-адреса в вашем коде, потому что оператор // используется для регулярных выражений.

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

Duff Device - в Perl

Переносимость и стандартность - Вероятно, больше компьютеров с Perl, чем с компилятором C

Класс манипуляции файлами/путями - Файл:: Найти работу в еще более операционных системах чем .NET делает

Цитаты для списков с разделителями пробелов и строки - Perl позволяет вам выбирать практически произвольные кавычки для вашего списка и разделителей строк

Алиативные пространства имен - Perl имеет эти сквозные назначения:

*My::Namespace:: = \%Your::Namespace

Статические инициализаторы - Perl может запускать код почти на каждом этапе компиляции и создания объекта, от BEGIN (синтаксический анализ кода) до CHECK (после анализа кода ) до import (при импорте модуля) до new (создание объекта) до DESTROY (уничтожение объекта) до END (выход программы)

Функции являются гражданами первого класса - точно так же, как в Perl

Блокировать область и закрытие - Perl имеет как

Вызов методов и аксессуаров косвенно через переменную - Perl тоже это делает:

my $method = 'foo';
my $obj = My::Class->new();
$obj->$method( 'baz' ); # calls $obj->foo( 'baz' )

Определение методов через код - Perl позволяет это также:

*foo = sub { print "Hello world" };

Прорывная онлайн-документация - Документация Perl находится в режиме онлайн и, вероятно, в вашей системе

Магические методы, которые вызываются при вызове "несуществующей" функции - Perl реализует это в функции AUTOLOAD

Символьные ссылки - вам лучше посоветовать держаться подальше от них. Они будут есть ваших детей. Но, конечно же, Perl позволяет вам предлагать своих детей кровожадным демонам.

Обмен одной строкой - Perl позволяет назначить список

Возможность заменить даже основные функции своей собственной функциональностью

use subs 'unlink'; 
sub unlink { print 'No.' }

или

BEGIN{
    *CORE::GLOBAL::unlink = sub {print 'no'}
};

unlink($_) for @ARGV
  • 0
    Я фанат документации Perl по сравнению с другими языками, но я все еще думаю, что для регулярных выражений и ссылок это можно было бы рационализировать в целом. Например, лучший пример для регулярных выражений - не Perlre, а Perlop
  • 0
    Джон: Вы читали perlrequick и perlretut?
Показать ещё 6 комментариев
35

Autovivification. AFAIK нет другого языка.

  • 0
    Я понятия не имел, что Python и другие не поддерживали это.
  • 0
    ECMAscript autovivs.
Показать ещё 8 комментариев
30

Просто процитировать почти любую странную строку в Perl.

my $url = q{http://my.url.com/any/arbitrary/path/in/the/url.html};

Фактически, различные механизмы цитирования в Perl весьма интересны. Механизмы цитирования, подобные выражению Perl, позволяют процитировать что угодно, указав разделители. Вы можете использовать почти любой специальный символ, например, #,/или открывать/закрывать символы типа(), [] или {}. Примеры:

my $var  = q#some string where the pound is the final escape.#;
my $var2 = q{A more pleasant way of escaping.};
my $var3 = q(Others prefer parens as the quote mechanism.);

Механизмы цитирования:

q: буквальная цитата; единственным символом, который должен быть экранирован, является символ конца. qq: интерпретированная цитата; обрабатывает переменные и escape-символы. Отлично подходит для строк, которые вам нужно процитировать:

my $var4 = qq{This "$mechanism" is broken.  Please inform "$user" at "$email" about it.};

qx: работает как qq, но затем выполняет его как системную команду, не интерактивно. Возвращает весь текст, полученный из стандартного. (Перенаправление, если поддерживается в ОС, также выходит) Также выполняется с обратными кавычками (символ).

my $output  = qx{type "$path"};      # get just the output
my $moreout = qx{type "$path" 2>&1}; # get stuff on stderr too

qr: Интерпретирует как qq, но затем компилирует его как регулярное выражение. Работает с различными опциями в регулярном выражении. Теперь вы можете передать регулярное выражение в виде переменной:

sub MyRegexCheck {
    my ($string, $regex) = @_;
    if ($string)
    {
       return ($string =~ $regex);
    }
    return; # returns 'null' or 'empty' in every context
}

my $regex = qr{http://[\w]\.com/([\w]+/)+};
@results = MyRegexCheck(q{http://myurl.com/subpath1/subpath2/}, $regex);

qw: очень полезный оператор цитаты. Включает в список цитированный набор пробельных разделенных слов. Отлично подходит для заполнения данных в unit test.


   my @allowed = qw(A B C D E F G H I J K L M N O P Q R S T U V W X Y Z { });
   my @badwords = qw(WORD1 word2 word3 word4);
   my @numbers = qw(one two three four 5 six seven); # works with numbers too
   my @list = ('string with space', qw(eight nine), "a $var"); # works in other lists
   my $arrayref = [ qw(and it works in arrays too) ]; 

Они умеют использовать их всякий раз, когда это делает вещи более ясными. Для qx, qq и q я, скорее всего, использую операторы {}. Наиболее распространенной привычкой людей, использующих qw, обычно является оператор(), но иногда вы также видите qw//.

  • 1
    Я иногда использую qw "", чтобы подсветка синтаксиса подсветила его правильно.
  • 0
    У меня работает в SlickEdit. :)
Показать ещё 4 комментария
28

Не очень скрыт, но много раз каждый день программисты на Perl не знают о CPAN. Это особенно относится к людям, которые не являются программистами на полный рабочий день или не работают на Perl в полном объеме.

27

Оператор "for" можно использовать так же, как "с" используется в Pascal:

for ($item)
{
    s/&‎nbsp;/ /g;
    s/<.*?>/ /g;
    $_ = join(" ", split(" ", $_));
}

Вы можете применить последовательность операций s///и т.д. к одной и той же переменной без необходимости повторять имя переменной.

ПРИМЕЧАНИЕ. Неразрывное пространство выше (& nbsp;) скрыло Unicode в нем, чтобы обойти Markdown. Не копируйте его:)

  • 0
    И "map" делает то же самое ... map {....} $ item; Одним из преимуществ использования «для» над «картой» является то, что вы можете использовать «Далее», чтобы выйти.
  • 2
    Кроме того, для элемента, которым манипулируют, перечисляется перед выполнением манипуляции с кодом, что приводит к лучшей читаемости.
Показать ещё 1 комментарий
26

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

my @lines = <DATA>;
for (@lines) {
    print if /bad/;
}

__DATA__
some good data
some bad data
more good data 
more good data 
  • 0
    Это очень некрасиво.
  • 0
    И очень полезно в маленьких тестах!
Показать ещё 4 комментария
26

Оператор quoteword - одна из моих любимых вещей. Для сравнения:

my @list = ('abc', 'def', 'ghi', 'jkl');

и

my @list = qw(abc def ghi jkl);

Значительно меньше шума, проще на глазу. Еще одна действительно приятная вещь о Perl, которую действительно не хватает при написании SQL, заключается в том, что конечная запятая является законной:

print 1, 2, 3, ;

Это выглядит странно, но нет, если вы отделите код другим способом:

print
    results_of_foo(),
    results_of_xyzzy(),
    results_of_quux(),
    ;

Добавление дополнительного аргумента в вызов функции не требует, чтобы вы играли запятыми в предыдущих или завершающих строках. Однострочное изменение не влияет на его окружающие линии.

Это очень приятно работать с вариационными функциями. Это, пожалуй, одна из самых недооцененных функций Perl.

  • 2
    Интересным примером синтаксиса Perl является следующее: for $ _ qw (список вещей) {...}
  • 1
    Вы можете даже злоупотреблять синтаксисом glob для цитирования слов, если вы не используете специальные символы, такие как * ?. Так что вы можете написать for (<a list of stuff>) { ... }
Показать ещё 5 комментариев
25

Проверка тонкости. При включенной проверке taint perl умрет (или предупреждает, -t), если вы попытаетесь передать испорченные данные (грубо говоря, данные извне программы) в небезопасную функцию (открытие файла, запуск внешней команды и т.д.).). Это очень полезно при написании скриптов setuid или CGI или чего-либо, где script имеет больше привилегий, чем тот, кто его подает.

Магический переход. goto &sub выполняет оптимизированный хвостовой вызов.

Отладчик.

use strict и use warnings. Это может спасти вас от множества опечаток.

  • 1
    Почему другие языки не имеют этой функции? Эта функция делает веб-скрипты на Perl на порядок более безопасными.
  • 2
    +1 за проверку «порчи». были объявлены!
23

Новые операции с блоком

Я бы сказал, что способность расширять язык, создавая операции псевдоблока, - это один.

  • Вы объявляете прототип субподачи, указывающий, что он сначала берет ссылку на код:

    sub do_stuff_with_a_hash (&\%) {
        my ( $block_of_code, $hash_ref ) = @_;
        while ( my ( $k, $v ) = each %$hash_ref ) { 
            $block_of_code->( $k, $v );
        }
    }
    
  • Затем вы можете вызвать его в теле так

    use Data::Dumper;
    
    do_stuff_with_a_hash {
        local $Data::Dumper::Terse = 1;
        my ( $k, $v ) = @_;
        say qq(Hey, the key   is "$k"!);
        say sprintf qq(Hey, the value is "%v"!), Dumper( $v );
    
    } %stuff_for
    ;
    

(Data::Dumper::Dumper - еще один полутай скрытый камень). Обратите внимание, что перед блоком вам не нужно ключевое слово sub или запятая перед хешем. Это в конечном итоге выглядит так: map { } @list

Фильтры источника

Кроме того, существуют фильтры источников. Где Perl передаст вам код, чтобы вы могли манипулировать им. Как это, так и операции с блоками, в значительной степени не подходят для этого типа вещей.

Я сделал некоторые опрятные вещи с исходными фильтрами, например, создав очень простой язык, чтобы проверить время, позволяя использовать короткие однострочные Perl для принятия определенных решений:

perl -MLib::DB -MLib::TL -e 'run_expensive_database_delete() if $hour_of_day < AM_7';

Lib::TL будет просто сканировать как "переменные", так и константы, создавать их и подставлять их по мере необходимости.

Опять же, исходные фильтры могут быть беспорядочными, но мощными. Но они могут испортить отладчику что-то ужасное - и даже предупреждения могут быть напечатаны с неправильными номерами строк. Я перестал использовать Damian Switch, потому что отладчик потерял бы все возможности сказать мне, где я на самом деле был. Но я обнаружил, что вы можете минимизировать ущерб, изменяя небольшие разделы кода, сохраняя их в одной строке.

Крюки для сигналов

Это довольно часто делается, но это не все так очевидно. Здесь грабитель, который поросенок спит на старый.

my $old_die_handler = $SIG{__DIE__};
$SIG{__DIE__}       
    = sub { say q(Hey! I'm DYIN' over here!); goto &$old_die_handler; }
    ;

Это означает, что всякий раз, когда какой-либо другой модуль в коде хочет умереть, он должен прийти к вам (если только кто-то другой не разрушит запись на $SIG{__DIE__}). И вы можете быть уведомлены, что кто-то что-то является ошибкой.

Конечно, для достаточно вещей вы можете просто использовать блок END { }, если все, что вы хотите сделать, - это очистить.

overload::constant

Вы можете проверить литералы определенного типа в пакетах, содержащих ваш модуль. Например, если вы используете это в своем import sub:

overload::constant 
    integer => sub { 
        my $lit = shift;
        return $lit > 2_000_000_000 ? Math::BigInt->new( $lit ) : $lit 
    };

это будет означать, что каждое целое число более 2 миллиардов в вызывающих пакетах будет изменено на объект Math::BigInt. (См. overload:: constant).

Группированные целые литеры

Пока мы на нем. Perl позволяет разбивать большие числа на группы из трех цифр и получать из него только синтаксическое целое число. Примечание 2_000_000_000 выше для 2 миллиардов.

  • 5
    При использовании обработчиков $ SIG { DIE } настоятельно рекомендуется проверить $ ^ S, чтобы увидеть, действительно ли ваша программа умирает или просто выдает исключение, которое будет перехвачено. Обычно вы не хотите вмешиваться в последнее.
  • 0
    Ага. Я делаю это вообще. И это хороший момент.
Показать ещё 2 комментария
23

Двоичный "x" - это оператор повторения:

print '-' x 80;     # print row of dashes

Он также работает со списками:

print for (1, 4, 9) x 3; # print 149149149
  • 0
    Это одна из причин, почему Perl был так популярен среди хакеров. perl -e 'print 0x000 x 25';
  • 0
    Также работает со списками: печать за (1, 4, 9) х 3
Показать ещё 1 комментарий
21

На основе того, как переключатели "-n" и "-p" реализованы в Perl 5, вы можете написать, казалось бы, неправильную программу, включая }{:

ls |perl -lne 'print $_; }{ print "$. Files"'

который внутренне преобразуется в этот код:

LINE: while (defined($_ = <ARGV>)) {
    print $_; }{ print "$. Files";
}
  • 6
    Теперь это просто глупо :-)
  • 0
    Иногда известный как "эскимосское приветствие" или просто "эскимосский" ...
Показать ещё 3 комментария
18

map - не только потому, что он делает один код более выразительным, а потому, что он дал мне импульс прочитать немного больше об этом "функциональном программировании".

18

Это мета-ответ, но Perl Tips архивы содержат всевозможные интересные трюки, которые можно сделать с помощью Perl. Архив предыдущих советов доступен в режиме онлайн для просмотра и может быть подписан через список рассылки или подачу атома.

Некоторые из моих любимых советов включают создание исполняемых файлов с PAR, используя autodie для автоматического исключения исключений и использования switch и smart-match в Perl 5.10.

Раскрытие информации: Я являюсь одним из авторов и сторонников Perl-советов, поэтому я, очевидно, очень высоко ценю их.;)

  • 2
    Это, вероятно, один из лучших задокументированных языков, и он задает шаблон для инструментов для поиска документации. Что список в этом вопросе, вероятно, не так необходим, как для других языков.
  • 1
    Autodie выглядит очень красиво.
18

Легко начать с Оператор космического корабля.

$a = 5 <=> 7;  # $a is set to -1
$a = 7 <=> 5;  # $a is set to 1
$a = 6 <=> 6;  # $a is set to 0
  • 0
    Это вряд ли эзотерика!
  • 1
    @Leon: C / C ++ не возвращает значения 3 для чисел. Если память выполняет функции String, то единственные 3 возвращаемых значения, которые я знаю на всем языке STL. AFAIK Python не имеет 3-х числовое сравнение. В Java также нет 3-го обратного сравнения.
Показать ещё 2 комментария
15

Предложение continue в циклах. Он будет выполняться в нижней части каждого цикла, даже тех, которые находятся дальше.

while( <> ){
  print "top of loop\n";
  chomp;

  next if /next/i;
  last if /last/i;

  print "bottom of loop\n";
}continue{
  print "continue\n";
}
15

Мое голосование пойдет для групп (? {}) и (?? {}) в регулярных выражениях Perl. Первый выполняет код Perl, игнорируя возвращаемое значение, второй выполняет код, используя возвращаемое значение как регулярное выражение.

  • 0
    Perl изобрел так много расширений регулярных выражений, что другие программы теперь часто используют pcre (совместимый с perl регулярное выражение) вместо исходного языка регулярных выражений.
  • 0
    Прочитайте небольшую рекламу здесь perldoc.perl.org/… :-D
Показать ещё 3 комментария
13
while(/\G(\b\w*\b)/g) {
     print "$1\n";
}

the\G anchor. Он горячий.

  • 3
    ... и это указывает на позицию конца предыдущего матча.
  • 1
    Но вы должны называть свое регулярное выражение в скалярном контексте.
Показать ещё 1 комментарий
13

Оператор m// имеет некоторые неясные частные случаи:

  • Если вы используете ? в качестве разделителя, он соответствует только одному, если вы не вызываете reset.
  • Если вы используете ' в качестве разделителя, шаблон не интерполируется.
  • Если шаблон пуст, он использует шаблон из последнего успешного совпадения.
  • 2
    Это больше похоже на скрытые ошибки, чем на скрытые возможности! Я не знаю никого, кто любит их. Поток на p5p некоторое время назад обсуждал полезность предполагаемого флага m / $ foo / r, где / r будет означать отсутствие интерполяции (буква не важна), так как никто никогда не сможет вспомнить ни единой кавычки.
  • 2
    @Dland: Согласен; Я бы назвал эти функции скрытыми ошибками и никогда не использовал бы их в производственном коде.
Показать ещё 4 комментария
12

Нулевой дескриптор файла алмазный оператор <> имеет свое место в создании инструментов командной строки. Он действует как <FH> для чтения из дескриптора, за исключением того, что он волшебным образом выбирает то, что было найдено первым: имена файлов командной строки или STDIN. Взято из perlop:

while (<>) {
...         # code for each line
}
  • 4
    Он также следует семантике UNIX использования «-» для обозначения «чтения из stdin». Таким образом, вы можете выполнить perl myscript.pl file1.txt - file2.txt , и perl обработает первый файл, затем stdin, а затем второй файл.
  • 0
    Вы можете overload оператор <> для своих собственных объектов ( <$var> ), чтобы работать как итератор. Однако это не работает, как вы могли ожидать в контексте списка.
11
rename("$_.part", $_) for "data.txt";

переименовывает data.txt.part в data.txt, не повторяя себя.

11

Специальные кодовые блоки, такие как BEGIN, CHECK и END. Они происходят из Awk, но работают по-разному в Perl, потому что они не основаны на записи.

Блок BEGIN может использоваться для указания некоторого кода для фазы синтаксического анализа; он также выполняется, когда вы выполняете проверку синтаксиса и переменной perl -c. Например, чтобы загрузить переменные конфигурации:

BEGIN {
    eval {
        require 'config.local.pl';
    };
    if ($@) {
        require 'config.default.pl';
    }
}
  • 0
    Вы забыли INIT.
  • 0
    @ Аксеман: Вы забыли UNITCHECK . ☺
10

Немного неясным является "оператор" тильд-тильды, который заставляет скалярный контекст.

print ~~ localtime;

совпадает с

print scalar localtime;

и отличается от

print localtime;
  • 5
    Это особенно непонятно, потому что perl5.10.0 также вводит «оператор умного сопоставления», ~~ , который может выполнять сопоставление с регулярным выражением, может посмотреть, содержится ли элемент в массиве и так далее.
  • 0
    Это не скрыто, это запутано (и полезно для гольфа и JAPH).
Показать ещё 3 комментария
9

В разделителе входных записей можно указать ссылку на число для чтения записей фиксированной длины:

$/ = \3; print $_,"\n" while <>; # output three chars on each line
9

Оператор goatse *:

$_ = "foo bar";
my $count =()= /[aeiou]/g; #3

или

sub foo {
    return @_;
}

$count =()= foo(qw/a b c d/); #4

Это работает, потому что назначение списка в скалярном контексте дает количество элементов в списке, который назначается.

* Обратите внимание, что это не оператор

  • 0
    Это самый (ну, наименьший) прекрасный «оператор» за всю историю.
  • 0
    Это напоминает мне о &~ «оператора».
9

tie, интерфейс привязки переменных.

  • 0
    Tie :: File спас мой день один раз!
7

Вы можете использовать @{[...]}, чтобы получить интерполированный результат сложных выражений perl

$a = 3;
$b = 4;

print "$a * $b = @{[$a * $b]}";

Отпечатки: 3 * 4 = 12

7

Этот не особенно полезен, но он чрезвычайно эзотеричен. Я наткнулся на это, копаясь в парсере Perl.

До того, как появился POD, у perl4 был трюк, позволяющий вставлять man-страницу, как nroff, прямо в вашу программу, чтобы она не потерялась. perl4 использовал программу, называемую wrapman (для некоторых деталей см. страницу Pink Camel на стр. 319), чтобы умело внедрить man-страницу nroff в ваш script.

Он работал, говоря nroff игнорировать весь код, а затем помещал мясо man-страницы после тега END, который сообщает Perl прекратить обработку кода. Посмотрел что-то вроде этого:

#!/usr/bin/perl
'di';
'ig00';

...Perl code goes here, ignored by nroff...

.00;        # finish .ig

'di         \" finish the diversion
.nr nl 0-1  \" fake up transition to first page
.nr % 0     \" start at page 1
'; __END__

...man page goes here, ignored by Perl...

Детали магии roff убегают от меня, но вы заметите, что команды roff представляют собой строки или числа в пустотном контексте. Обычно константа в пустоте создает предупреждение. В op.c есть специальные исключения, чтобы разрешить строки контекста void, которые начинаются с определенных команд roff.

              /* perl4 way of mixing documentation and code
                 (before the invention of POD) was based on a
                 trick to mix nroff and perl code. The trick was
                 built upon these three nroff macros being used in
                 void context. The pink camel has the details in
                 the script wrapman near page 319. */
                const char * const maybe_macro = SvPVX_const(sv);
                if (strnEQ(maybe_macro, "di", 2) ||
                    strnEQ(maybe_macro, "ds", 2) ||
                    strnEQ(maybe_macro, "ig", 2))
                        useless = NULL;

Это означает, что 'di'; не вызывает предупреждения, но также не имеет значения 'die'; 'did you get that thing I sentcha?'; или 'ignore this line';.

Кроме того, существуют исключения для числовых констант 0 и 1, которые разрешают голый .00;. Код утверждает, что это было для более общих целей.

            /* the constants 0 and 1 are permitted as they are
               conventionally used as dummies in constructs like
                    1 while some_condition_with_side_effects;  */
            else if (SvNIOK(sv) && (SvNV(sv) == 0.0 || SvNV(sv) == 1.0))
                useless = NULL;

И что вы знаете, 2 while condition предупреждает!

  • 0
    Это действительно скрытая особенность Perl!
7

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

my %number_for = (one => 1, two => 2, three => 3);
my %your_numbers = (two => 2, four => 4, six => 6);
@number_for{keys %your_numbers} = values %your_numbers;
print sort values %number_for; # 12346
  • 0
    % number_for = (% number_for,% your_numbers);
6
use diagnostics;

Если вы начинаете работать с Perl и никогда раньше этого не делали, этот модуль сэкономит вам массу времени и хлопот. Для почти каждого основного сообщения об ошибке, которое вы можете получить, этот модуль даст вам подробное объяснение, почему ваш код ломается, включая некоторые полезные советы о том, как его исправить. Например:

use strict;
use diagnostics;

$var = "foo";

дает вам это полезное сообщение:

Global symbol "$var" requires explicit package name at - line 4.
Execution of - aborted due to compilation errors (#1)
    (F) You've said "use strict vars", which indicates that all variables
    must either be lexically scoped (using "my"), declared beforehand using
    "our", or explicitly qualified to say which package the global variable
    is in (using "::").

Uncaught exception from user code:
        Global symbol "$var" requires explicit package name at - line 4.
Execution of - aborted due to compilation errors.
 at - line 5
use diagnostics;
use strict;

sub myname {
    print { " Some Error " };
};

вы получите этот большой, полезный фрагмент текста:

syntax error at - line 5, near "};"
Execution of - aborted due to compilation errors (#1)
(F) Probably means you had a syntax error.  Common reasons include:

    A keyword is misspelled.
    A semicolon is missing.
    A comma is missing.
    An opening or closing parenthesis is missing.
    An opening or closing brace is missing.
    A closing quote is missing.

Often there will be another error message associated with the syntax
error giving more information.  (Sometimes it helps to turn on -w.)
The error message itself often tells you where it was in the line when
it decided to give up.  Sometimes the actual error is several tokens
before this, because Perl is good at understanding random input.
Occasionally the line number may be misleading, and once in a blue moon
the only way to figure out what triggering the error is to call
perl -c repeatedly, chopping away half the program each time to see
if the error went away.  Sort of the cybernetic version of S.

Uncaught exception from user code:
    syntax error at - line 5, near "};"
Execution of - aborted due to compilation errors.
at - line 7

Оттуда вы можете сделать вывод о том, что может быть неправильно с вашей программой (в этом случае печать полностью отформатирована). Там имеется большое количество известных ошибок при диагностике. Теперь, хотя это было бы неплохо использовать в производстве, оно может служить отличным учебным пособием для тех, кто не знаком с Perl.

6
sub load_file
{
    local(@ARGV, $/) = shift;
    <>;
}

и версию, которая возвращает массив по мере необходимости:

sub load_file
{
    local @ARGV = shift;
    local $/ = wantarray? $/: undef;
    <>;
}
5

@Schwern упомянул о том, что в предупреждениях были допущены ошибки, локализуя $SIG{__WARN__}. Вы также можете сделать это (лексически) с помощью use warnings FATAL => "all";. См. perldoc lexwarn.

В этой заметке, поскольку Perl 5.12, вы можете сказать perldoc foo вместо полного perldoc perlfoo. В заключение!:)

5

($ x, $y) = ($ y, $x) - это то, что заставило меня хотеть изучить Perl.

Конструктор списка 1.99 или 'a'.. 'zz' тоже очень приятный.

5

Также существует $[переменная, которая решает, по какому индексу начинается массив. Значение по умолчанию равно 0, поэтому массив начинается с 0. Установив

$[=1;

Вы можете заставить Perl вести себя как AWK (или Fortran), если вы действительно этого хотите.

  • 3
    Хотя, цитируя документацию perlvar: «Его использование крайне не рекомендуется». Не многие люди ожидают изменения начального индекса массива.
  • 2
    Я бы использовал эту функцию только в одну строку, если когда-либо.
Показать ещё 1 комментарий
4

Этот однострочный рисунок иллюстрирует, как использовать glob для генерации всех словосочетаний алфавита (A, T, C и G → DNA) для слов определенной длины (4):

perl -MData::Dumper -e '@CONV = glob( "{A,T,C,G}" x 4 ); print Dumper( \@CONV )'
4

Один полезный составной оператор для условного добавления строк или списков в другие списки - это оператор x!!:

 print 'the meaning of ', join ' ' =>  
     'life,'                x!! $self->alive,
     'the universe,'        x!! ($location ~~ Universe),
     ('and', 'everything.') x!! 42; # this is added as a list

этот оператор допускает обратный синтаксис, аналогичный

 do_something() if test();
4

Schwartzian Transform - это метод, который позволяет эффективно сортировать по вычисленному вторичному индексу. Скажем, что вы хотели отсортировать список строк по их сумме md5. Нижеприведенные комментарии лучше всего читать назад (что порядок, который я всегда в конечном итоге пишу их):

my @strings = ('one', 'two', 'three', 'four');

my $md5sorted_strings = 
    map { $_->[0] }               # 4) map back to the original value
    sort { $a->[1] cmp $b->[1] }  # 3) sort by the correct element of the list
    map { [$_, md5sum_func($_)] } # 2) create a list of anonymous lists
    @strings                      # 1) take strings

Таким образом, вам нужно выполнить только дорогостоящее вычисление md5 N раз, а не N log N раз.

4

Используйте lvalues, чтобы сделать ваш код действительно запутанным:

my $foo = undef ;
sub bar:lvalue{ return $foo ;}

# Then later

bar = 5 ;
print bar ;
4

Хорошо. Вот еще один. Динамическое масштабирование. О нем немного говорили в другом посте, но я не видел его здесь по скрытым функциям.

Динамическое масштабирование, как Autovivification, имеет очень ограниченное количество языков, которые его используют. Perl и Common Lisp - это единственные, которые я знаю об использовании Dynamic Scoping.

  • 0
    О, да, «local» обозначает переменную с динамической областью, а «my» обозначает переменную в статической области видимости.
4

Как насчет возможности использования

my @symbols = map { +{ 'key' => $_ } } @things;

чтобы сгенерировать массив hashrefs из массива - + перед хэш файлом устраняет неоднозначность блока, поэтому интерпретатор знает, что это hashref, а не блок кода. Высокий.

(Спасибо Дэйву Дойлу за объяснение этого мне на последней встрече в Торонто Перлмонджерс.)

4

Core IO::Handle. Самое главное для меня - это то, что он позволяет autoflush на дескрипторах файлов. Пример:

use IO::Handle;    
$log->autoflush(1);
  • 0
    Не то чтобы мы не знали, как это сделать до IO::Handle , вы знаете.
4

Безопасные отсеки.

С помощью модуля Safe вы можете создать собственную среду в стиле песочницы, используя только перл. Затем вы сможете загружать Perl-скрипты в песочницу.

С уважением,

3

Вы можете использовать разные кавычки на HEREDOCS для получения разных поведений.

my $interpolation = "We will interpolated variables";
print <<"END";
With double quotes, $interpolation, just like normal HEREDOCS.
END

print <<'END';
With single quotes, the variable $foo will *not* be interpolated.
(You have probably seen this in other languages.)
END

## this is the fun and "hidden" one
my $shell_output = <<`END`;
echo With backticks, these commands will be executed in shell.
echo The output is returned.
ls | wc -l
END

print "shell output: $shell_output\n";
3

use re debug
Doc для повторной отладки

и

perl -MO=Concise[,OPTIONS]
Док в сжатом

Помимо гибкости, выразительности и возможности программирования в стиле C, Pascal, Python и других языков, существует несколько команд командной строки pragmas, которые делают Perl моим языком 'goto' для начального kanoodling по алгоритму, регулярному выражению или которые необходимо решить. Эти два являются уникальными для Perl, я считаю, и являются одними из моих фаворитов.

use re debug: Большинство современных ароматов регулярных выражений обязаны их текущей форме и функции Perl. Хотя существует много форм Perl регулярного выражения, которые не могут быть выражены на других языках, почти нет форм выражения других языков, которые не могут быть выражены в Perl. Кроме того, Perl имеет замечательный встроенный отладчик регулярных выражений, чтобы показать, как механизм регулярных выражений интерпретирует ваше регулярное выражение и сопоставляется с целевой строкой.

Пример: Недавно я пытался написать простую процедуру CSV. (Да, да, я знаю, мне следовало использовать Text:: CSV...), но значения CSV не были процитированы и просты,

Мое первое взятие было /^(^(?:(.*?),){$i}/, чтобы извлечь запись я в n CSV-записи. Это отлично работает - за исключением последней записи или n из n. Я мог видеть это без отладчика.

Далее я попробовал /^(?:(.*?),|$){$i}/ Это не сработало, и я не мог сразу понять, почему. Я думал, что я говорю (.*?), за которым следует запятая или EOL. Затем я добавил use re debug в верхней части небольшого теста script. Ах, да, изменение между ,|$ не интерпретировалось таким образом; его интерпретировали как ((.*?),) | ($) - не то, что я хотел.

Требуется новая группировка. Поэтому я пришел к рабочему /^(?:(.*?)(?:,|$)){$i}/. В то время как я был в отладчике регулярных выражений, я был удивлен, сколько циклов потребовалось для соответствия к концу строки. Это термин .*?, который довольно неоднозначен и требует чрезмерного возврата для удовлетворения. Итак, я попробовал /^(?:(?:^|,)([^,]*)){$i}/ Это делает две вещи: 1) уменьшает обратную трассировку из-за жадного соответствия всех, кроме запятой. 2) разрешил оптимизатору регулярных выражений использовать только одно изменение в первом поле. Используя Benchmark, это на 35% быстрее, чем первое регулярное выражение. Отладчик регулярных выражений замечательный, и его мало используют.

perl -MO=Concise[,OPTIONS]: Структуры B и Concise являются огромными инструментами, чтобы увидеть, как Perl интерпретирует ваш шедевр. Использование -MO=Concise печатает результат перевода интерпретатора Perl вашего исходного кода. Есть много вариантов Concise и в B, вы можете написать собственную презентацию OP-кодов.

Как в этом сообщении, вы можете использовать Concise для сравнения различных структур кода. Вы можете чередовать исходные строки с кодами OP, которые генерируют эти строки. Проверьте это.

3

Существует более мощный способ проверки программ на синтаксические ошибки:

perl -w -MO=Lint,no-context myscript.pl

Самое главное, что он может сделать, это сообщить об ошибках "неустойчивой подпрограммы".

3

Quantum::Superpositions

use Quantum::Superpositions;

if ($x == any($a, $b, $c)) { ...  }
3

Мне лично нравится модификатор /e для операции s///:

while(<>) {
  s/(\w{0,4})/reverse($1);/e; # reverses all words between 0 and 4 letters
  print;
}

Input:

This is a test of regular expressions
^D

Выход (я думаю):

sihT si a tset fo regular expressions
3

Очень поздно для вечеринки, но: атрибуты.

Атрибуты в основном позволяют определить произвольный код для связи с объявлением переменной или подпрограммы. Лучший способ их использования - Attribute::Handlers; это упрощает определение атрибутов (в терминах, что еще, атрибуты!).

Я сделал презентацию об их использовании, чтобы декларативно собрать подключаемый класс и его плагины в YAPC:: 2006, в Интернете здесь. Это довольно уникальная функция.

3

Вы можете заменить разделитель в регулярных выражениях и строках практически любым другим. Это особенно полезно для "отклонения синдрома зубочистки", приведенного здесь:

$url =~ /http:\/\/www\.stackoverflow\.com\//;

Вы можете устранить большую часть обратного удара, изменив разделитель. /bar/ является сокращением для m/bar/, которое совпадает с m!bar!.

$url =~ m!http://www\.stackoverflow\.com/!;

Вы можете даже использовать сбалансированные разделители типа {} и []. Я лично их люблю. q{foo} совпадает с 'foo'.

$code = q{
    if( this is awesome ) {
        print "Look ma, no escaping!";
    }
};

Чтобы запутать ваших друзей (и ваш ярлык синтаксиса), попробуйте следующее:

$string = qq'You owe me $1,000 dollars!';
  • 0
    Вы должны явно указать , что при использовании {} (и друзей) , как кавычки, Perl будет балансировать разделители.
3

Моя любимая полускрытая функция Perl - это функция eof. Вот пример, очень похожий непосредственно из perldoc -f eof, который показывает, как вы можете легко использовать его для reset имени файла и $. (номер текущей строки) для нескольких файлов, загруженных в командной строке:

while (<>) {
  print "$ARGV:$.\t$_";
} 
continue {
  close ARGV if eof
}
2

Функция, которая мне больше всего нравится, - это модификаторы выражений.

Не знаю, сколько раз я хотел сделать:

say 'This will output' if 1;
say 'This will not output' unless 1;
say 'Will say this 3 times. The first Time: '.$_ for 1..3;

на других языках. и т.д...

"и т.д." напомнил мне еще одну функцию 5.12, оператора Яда Яда.

Это замечательно, когда вы просто хотите владельца места.

sub something_really_important_to_implement_later {
    ...
} 

Проверьте это: Perl Docs на Яда Яда Оператор.

  • 0
    Вообще-то это многоточие .
2

Вы можете развернуть вызовы функций в строке, например:

print my $foo = "foo @{[scalar(localtime)]} bar";

foo Среда 26 мая 15:50:30 2010 бар

2

Возможность использовать хэш как видимый фильтр в цикле. Мне еще нужно увидеть что-то совершенно приятное на другом языке. Например, я не смог дублировать это в python.

Например, я хочу напечатать строку, если она не была замечена раньше.

my %seen;

for (<LINE>) {
  print $_ unless $seen{$_}++;
}
2

Новая опция -E в командной строке:

> perl -e "say 'hello"" # does not work 

String found where operator expected at -e line 1, near "say 'hello'"
        (Do you need to predeclare say?)
syntax error at -e line 1, near "say 'hello'"
Execution of -e aborted due to compilation errors.

> perl -E "say 'hello'" 
hello
2

Две вещи, которые хорошо работают вместе: IO обрабатывает встроенные строки и использует прототипы функций, чтобы вы могли писать свои собственные функции с синтаксисом grep/map-like.

sub with_output_to_string(&) {           # allows compiler to accept "yoursub {}" syntax.
  my $function = shift;
  my $string   = '';
  my $handle   = IO::Handle->new();
  open($handle, '>', \$string) || die $!; # IO handle on a plain scalar string ref
  my $old_handle = select $handle;
  eval { $function->() };
  select $old_handle;
  die $@ if $@;
  return $string;
}

my $greeting = with_output_to_string {
  print "Hello, world!";
};

print $greeting, "\n";
2

Ниже приведены краткие, но более значимые, чем "~~", поскольку они указывают, что возвращается, и нет путаницы с оператором smart match:

print "".localtime;   # Request a string

print 0+@array;       # Request a number
2

Axeman напомнил мне, насколько легко переносить некоторые из встроенных функций.

До Perl 5.10. В Perl не было красивой печати (скажем), такой как Python.

Итак, в вашей локальной программе вы можете сделать что-то вроде:

sub print {
     print @_, "\n";
}

или добавить некоторые отладки.

sub print {
    exists $ENV{DEVELOPER} ?
    print Dumper(@_) :
    print @_;
}
  • 0
    Также очень легко случайно изменить контекст! Ваша подпрограмма печати (использующая. Для объединения) напечатает количество печатаемых элементов, а не сами элементы. Используя print @_, "\n" (обратите внимание на запятую) сохранит контекст.
  • 0
    :-D ткс за разъяснения. Я буду редактировать соответственно. :-D научи меня писать код без запуска :-P
Показать ещё 3 комментария
1

В следующий раз, когда вы окажетесь на вечеринке, вытащите этот лайнер в оболочку bash, и женщины будут роивать вас, и ваши друзья будут поклоняться вам:

найти. -name "*.txt" | xargs perl -pi -e 's/1: (\ S +)/uc ($ 1)/ge'

Обработать все *.txt файлы и выполнить поиск и замену на месте с помощью регулярного выражения perl. Он преобразует текст после "1:" в верхний регистр и удаляет "1:". Использует модификатор Perl 'e' для обработки второй части поискового/замещающего регулярного выражения как исполняемого кода. Мгновенная однострочная система шаблонов. Использование xargs позволяет обрабатывать огромное количество файлов без использования ограничения длины строки командной строки bash.

1

Добавьте один для функций unpack() и pack(), которые являются большими, если вам нужно импортировать и/или экспортировать данные в формате, который используется другими программами.

Конечно, в наши дни большинство программ позволят вам экспортировать данные в XML, а многие распространенные форматы документов имеют связанные с ними модули Perl, написанные для них. Но это одна из тех функций, которые невероятно полезны, когда вам это нужно, и pack()/unpack(), вероятно, являются причиной того, что люди смогли записать модули CPAN для столь многих проприетарных форматов данных.

1

Использование хешей (где уникальные ключи) для получения уникальных элементов списка:

my %unique = map { $_ => 1 } @list;
my @unique = keys %unique;
1

Интерполяция регулярных выражений матча. Полезным приложением этого является сопоставление в черном списке. Без использования интерполяции оно написано так:

#detecting blacklist words in the current line
/foo|bar|baz/;

Вместо этого можно записать

@blacklistWords = ("foo", "bar", "baz");
$anyOfBlacklist = join "|", (@blacklistWords);
/$anyOfBlacklist/;

Это более подробный, но позволяет населению из файла данных. Также, если список поддерживается в источнике по какой-либо причине, легче поддерживать массив, а затем RegExp.

1

Выражение defined &DB::DB возвращает true, если программа запущена из отладчика.

1

Возможно, вы можете сделать это, чтобы сохранить память:

@is_month{qw(jan feb mar apr may jun jul aug sep oct nov dec)} = undef;

print "It a month" if exists $is_month{lc $mon};

но он этого не делает. Perl по-прежнему присваивает каждому скалярному значению другое скалярное значение. Devel::Peek показывает это. PVHV - хэш. Elt - это ключ, а SV - его значение. Обратите внимание, что каждый SV имеет другой адрес памяти, указывающий, что он не используется.

Dump \%is_month, 12;

SV = RV(0x81c1bc) at 0x81c1b0
  REFCNT = 1
  FLAGS = (TEMP,ROK)
  RV = 0x812480
  SV = PVHV(0x80917c) at 0x812480
    REFCNT = 2
    FLAGS = (SHAREKEYS)
    ARRAY = 0x206f20  (0:8, 1:4, 2:4)
    hash quality = 101.2%
    KEYS = 12
    FILL = 8
    MAX = 15
    RITER = -1
    EITER = 0x0
    Elt "feb" HASH = 0xeb0d8580
    SV = NULL(0x0) at 0x804b40
      REFCNT = 1
      FLAGS = ()
    Elt "may" HASH = 0xf2290c53
    SV = NULL(0x0) at 0x812420
      REFCNT = 1
      FLAGS = ()

Сканер undef занимает столько же памяти, сколько целочисленный скаляр, поэтому вы можете попросить, чтобы просто назначили их всем 1 и избегайте ловушки забывания, чтобы проверить с помощью exists.

my %is_month = map { $_ => 1 } qw(jan feb mar apr may jun jul aug sep oct nov dec);

print "It a month" if $is_month{lc $mon});
  • 1
    Это не экономит память и генерирует хорошую ловушку для ничего не подозревающего программиста. Perl по-прежнему назначает скалярное значение undef каждому ключу, а undef не занимает меньше памяти, чем 1. Используйте Devel :: Peek, чтобы увидеть.
  • 0
    Возможно, вы правы в том, что конструкция undef не экономит память. Однако, на мой взгляд, оно лучше вашего решения по нескольким причинам: 1. метод undef сообщает читателю, что значение не используется 2. инициализатор «1» более сложен без веской причины 3. требует » существует "не более ловушка, чем многие другие вещи в Perl
Показать ещё 1 комментарий
1

Я немного опаздываю на вечеринку, но голосование за встроенную связанную хэш-функцию dbmopen() - это очень помогло мне. Это не совсем база данных, но если вам нужно сохранить данные на диск, это уберет много проблем и Just Works. Это помогло мне начать работу, когда у меня не было базы данных, не понял Storable.pm, но я знал, что хочу продвинуться дальше чтения и записи в текстовые файлы.

0

B:: Deparse - Бэкэндер для Perl для создания Perl-кода. Не то, что вы использовали бы в своем ежедневном кодировании Perl, но может быть полезным в особых обстоятельствах.

Если вы сталкиваетесь с каким-то фрагментом кода, который запутан, или сложным выражением, передайте его через Deparse. Полезно выяснить код JAPH или Perl, который используется в гольф.

$ perl -e '$"=$,;*{;qq{@{[(A..Z)[qq[0020191411140003]=~m[..]g]]}}}=*_=sub{print/::(.*)/};$\=$/;q<Just another Perl Hacker>->();'
Just another Perl Hacker

$ perl -MO=Deparse -e '$"=$,;*{;qq{@{[(A..Z)[qq[0020191411140003]=~m[..]g]]}}}=*_=sub{print/::(.*)/};$\=$/;q<Just another Perl Hacker>->();'
$" = $,;
*{"@{[('A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z')['0020191411140003' =~ /../g]];}";} = *_ = sub {
    print /::(.*)/;
}
;
$\ = $/;
'Just another Perl Hacker'->();
-e syntax OK

Более полезным примером является использование deparse для выяснения кода, лежащего в основе coderef, который вы могли бы получить от другого модуля, или

use B::Deparse;
my $deparse = B::Deparse->new;
$code = $deparse->coderef2text($coderef);
print $code;
0

Мне нравится способ вставки элемента в любое место в массиве, например

= > Вставить $x в позицию $i в массиве @a

@a = ( 11, 22, 33, 44, 55, 66, 77 );
$x = 10;
$i = 3;

@a = ( @a[0..$i-1], $x, @a[$i..$#a] );
0

"теперь"

sub _now { 
        my ($now) = localtime() =~ /([:\d]{8})/;
        return $now;
}

print _now(), "\n"; #  15:10:33
0

Perl отлично подходит как гибкий awk/sed.

Например, можно использовать простую замену для ls | xargs stat, наивно сделанное как:

$ ls | perl -pe 'print "stat "' | sh 

Это не работает, когда вход (имена файлов) имеет пробелы или специальные символы оболочки, такие как |$\. Поэтому в выводе Perl часто требуются одинарные кавычки.

Одно из осложнений с вызовом perl через командную строку -ne заключается в том, что оболочка получает первый кусок на вашем одном слое. Это часто приводит к мучительному побегу, чтобы удовлетворить его.

Одна скрытая функция, которую я использую все время \x27, чтобы включить одну цитату вместо того, чтобы пытаться использовать экранирование оболочки '\''

Итак:

$ ls | perl -nle 'chomp; print "stat '\''$_'\''"' | sh

можно более безопасно записать:

$ ls | perl -pe 's/(.*)/stat \x27$1\x27/' | sh

Это не будет работать со смешными символами в именах файлов, даже цитируется так. Но это будет:

$ ls | perl -pe 's/\n/\0/' | xargs -0 stat
0

с использованием незакрытых блоков с redo или другими управляющими словами для создания пользовательских конструкций циклов.

пересечь связанный список объектов, возвращающих первый метод ->can('print'):

sub get_printer {
    my $self = shift;
    {$self->can('print') or $self = $self->next and redo}
}
0

$0 - это имя выполняемого perl script. Его можно использовать для получения контекста, из которого выполняется модуль.

# MyUsefulRoutines.pl

sub doSomethingUseful {
  my @args = @_;
  # ...
}

if ($0 =~ /MyUsefulRoutines.pl/) {
  # someone is running  perl MyUsefulRoutines.pl [args]  from the command line
  &doSomethingUseful (@ARGV);
} else {
  # someone is calling  require "MyUsefulRoutines.pl"  from another script
  1;
}

Эта идиома полезна для рассмотрения автономного script с некоторыми полезными подпрограммами в библиотеку, которая может быть импортирована в другие скрипты. Python имеет аналогичную функциональность с object.__name__ == "__main__" идиомой.

  • 0
    Что вам нужно, это модули .
0

Еще один...

Кэш Perl:

my $processed_input = $records || process_inputs($records_file);

На Elpeleg Open Source, Perl CMS http://www.web-app.net/

0

Отображение прогресса в script путем печати в той же строке:

$| = 1; # flush the buffer on the next output 

for $i(1..100) {
    print "Progress $i %\r"
}
  • 0
    Это не функция Perl.
0

@Corion - Простые URL-адреса в Perl? Конечно, вы можете даже в интерполированных строках. Единственный раз, когда это имеет значение, - это строка, которую вы фактически использовали в качестве регулярного выражения.

  • 0
    Это происходит из-за шутки, где в C ++ вы можете встраивать URL-адрес в вашу программу, необработанный и без кавычек или комментариев: http://www.example.com ( http: это метка, а // делает оставь комментарий). Это то, что все имеют в виду.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню