Скрытые функции Perl?

Вы вставляете, не обновляя результат. Вы можете определить столбец имен в основном столбце или установить его уникальным.

143
задан 17 revs, 7 users 53% 25 September 2017 в 20:53
поделиться

73 ответа

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

print ~~ localtime;

совпадает с

print scalar localtime;

и отличающийся от

print localtime;
10
ответ дан Sec 25 September 2017 в 20:53
поделиться

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

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

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

Устройство вареного пудинга - в Perl

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

Класс управления файлом/путем - Работы File::Find над еще большим количеством операционных систем, чем .NET

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

Пространства имен Aliasable - 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, которые в АВТОЗАГРУЗКЕ функционируют

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

Один свопинг значения строки - Perl позволяет присвоение списка

Способность заменить даже ядро функционирует с Вашей собственной функциональностью

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

или

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

unlink($_) for @ARGV
36
ответ дан 5 revs, 3 users 85% 25 September 2017 в 20:53
поделиться

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

BEGIN блок может использоваться для определения некоторого кода для фазы парсинга; это также выполняется, когда Вы делаете syntax-and-variable-check perl -c. Например, для загрузки в переменных конфигурации:

BEGIN {
    eval {
        require 'config.local.pl';
    };
    if ($@) {
        require 'config.default.pl';
    }
}
11
ответ дан 3 revs 25 September 2017 в 20:53
поделиться

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

while (<>) {
...         # code for each line
}
12
ответ дан spoulson 25 September 2017 в 20:53
поделиться

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

Волшебство goto. goto &sub делает оптимизированный последний вызов.

отладчик.

use strict и use warnings. Они могут сохранить Вас от набора опечаток.

24
ответ дан 3 revs, 3 users 80% 25 September 2017 в 20:53
поделиться

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

  • , Если Вы используете ? в качестве разделителя, он только соответствует однажды, если Вы не звоните reset.
  • , Если Вы используете ' в качестве разделителя, шаблон не интерполирован.
  • , Если шаблон пуст, он использует шаблон от последнего успешного соответствия.
13
ответ дан 2 revs, 2 users 80% 25 September 2017 в 20:53
поделиться
while(/\G(\b\w*\b)/g) {
     print "$1\n";
}

\G привязка. жарко .

13
ответ дан J.J. 25 September 2017 в 20:53
поделиться

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

конструктор списка 1.. 99 или 'a'.. 'zz' также очень хорош.

5
ответ дан Daniel 25 September 2017 в 20:53
поделиться

"Режим отчаяния" цикла Perl управляет конструкциями, который заставляет их искать стек, чтобы найти, что маркировка соответствия позволяет некоторые любопытные поведения который Тест:: Больше использует в своих интересах, что бы там ни было.

SKIP: {
    skip() if $something;

    print "Never printed";
}

sub skip {
    no warnings "exiting";
    last SKIP;
}

существует мало известный .pmc файл. "используйте Foo", будет искать Foo.pmc в @INC перед Foo.pm. Это было предназначено, чтобы позволить скомпилированному байт-коду быть загруженным сначала, но Модуль:: Скомпилируйте , использует в своих интересах, это к источнику кэша фильтровало модули в течение более быстрого времени загрузки и более легкой отладки.

способность превратить предупреждения в ошибки.

local $SIG{__WARN__} = sub { die @_ };
$num = "two";
$sum = 1 + $num;
print "Never reached";

Это - то, о чем я могу думать первое, что пришло на ум, который не был упомянут.

9
ответ дан Schwern 25 September 2017 в 20:53
поделиться

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

1
ответ дан AmbroseChapel 25 September 2017 в 20:53
поделиться

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

Динамический Обзор как Autovivification имеет очень ограниченную сумму языков, которые используют его. Perl и язык Common LISP являются только двумя, я знаю того использования Динамический Обзор.

4
ответ дан 2 revs, 2 users 56% 25 September 2017 в 20:53
поделиться

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

while (<>) {
  print "$ARGV:$.\t$_";
} 
continue {
  close ARGV if eof
}
3
ответ дан 2 revs 25 September 2017 в 20:53
поделиться

Используйте lvalues для создания кода, действительно путающего:

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

# Then later

bar = 5 ;
print bar ;
4
ответ дан Jeteve 25 September 2017 в 20:53
поделиться

Очень поздно стороне, но: атрибуты.

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

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

3
ответ дан 2 revs, 2 users 94% 25 September 2017 в 20:53
поделиться
  • 1
    @usr Когда я попытался объяснить в своем ответе, виртуальная реализация метода, существует главным образом на уровне IL, не на уровне машинного кода. Так не, проблема doesn' t существуют на x86 уровне, потому что в той точке, существует not' t любые виртуальные методы больше. Могут быть указатели функции, используемые для реализации виртуальных методов, но it' s задание Дрожания, чтобы сделать это таким способом, который собственный код doesn' t должны интересоваться соответствующими деталями непосредственно. –  22 June 2014 в 13:18

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

$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!';
3
ответ дан 2 revs, 2 users 51% 25 September 2017 в 20:53
поделиться

Еще один...

кэш Perl:

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

На Открытом исходном коде Elpeleg, Perl CMS http://www.web-app.net/

0
ответ дан 3 revs, 2 users 82%On Elpeleg 26 September 2017 в 06:53
поделиться

Я лично люблю/e модификатор к s///операция:

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

Вход:

This is a test of regular expressions
^D

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

sihT si a tset fo regular expressions
3
ответ дан Chris Lutz 26 September 2017 в 06:53
поделиться
  • 1
    Я понимаю этот вопрос быть о деталях реализации. Рассмотрение дизассемблирования примера кода, это похоже на то, что vcall к общему методу, действительно влияло на сгенерированный код. – usr 23 June 2014 в 00:20

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

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

работавший, говоря nroff игнорировать весь код и затем помещать суть страницы справочника после КОНЕЦ тег, который говорит 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 для разрешения пустых строк контекста, которые запускаются с определенных команд roff.

              /* perl4's 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 действительно предупреждает!

7
ответ дан Schwern 26 September 2017 в 06:53
поделиться

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

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

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

но это не делает этого. Perl все еще присваивает другую скалярную величину каждому ключу. Devel:: Быстрый взгляд показывает это. 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's a month" if $is_month{lc $mon});
1
ответ дан 2 revs, 2 users 74% 26 September 2017 в 06:53
поделиться

Оператор goatse * :

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

или

sub foo {
    return @_;
}

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

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

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

9
ответ дан 23 November 2019 в 22:56
поделиться

Quantum :: Superpositions

use Quantum::Superpositions;

if ($x == any($a, $b, $c)) { ...  }
3
ответ дан 23 November 2019 в 22:56
поделиться
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's 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
ответ дан 23 November 2019 в 22:56
поделиться

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

$a = 3;
$b = 4;

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

выводит: 3 * 4 = 12

7
ответ дан 23 November 2019 в 22:56
поделиться

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

$/ = \3; print $_,"\n" while <>; # output three chars on each line
9
ответ дан 23 November 2019 в 22:56
поделиться

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

print "".localtime;   # Request a string

print 0+@array;       # Request a number
2
ответ дан 23 November 2019 в 22:56
поделиться

Преобразование Шварца - это метод, который позволяет вам эффективно сортировать по вычисляемому вторичному индексу. Допустим, вы хотите отсортировать список строк по их сумме 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
ответ дан 23 November 2019 в 22:56
поделиться

Одним из полезных составных операторов для условного добавления строк или списков в другие списки является оператор 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
ответ дан 23 November 2019 в 22:56
поделиться

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

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

Самое важное, что он может сделать, это сообщить об ошибках 'unexistant subroutine'.

3
ответ дан 23 November 2019 в 22:56
поделиться

использовать повторную отладку
Документ по использованию повторной отладки

и

perl -MO = Concise [, OPTIONS]
Doc on Concise

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

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

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

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

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

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

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

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

3
ответ дан 23 November 2019 в 22:56
поделиться

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

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
ответ дан 23 November 2019 в 22:56
поделиться