Вы вставляете, не обновляя результат. Вы можете определить столбец имен в основном столбце или установить его уникальным.
Немного неясный тильда тильды "оператор", который вызывает скалярный контекст.
print ~~ localtime;
совпадает с
print scalar localtime;
и отличающийся от
print localtime;
Поскольку 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
Специальные блоки кода такой как BEGIN
, CHECK
и END
. Они прибывают из Awk, но работают по-другому в Perl, потому что это не основано на записи.
BEGIN
блок может использоваться для определения некоторого кода для фазы парсинга; это также выполняется, когда Вы делаете syntax-and-variable-check perl -c
. Например, для загрузки в переменных конфигурации:
BEGIN {
eval {
require 'config.local.pl';
};
if ($@) {
require 'config.default.pl';
}
}
Пустой оператор <>
ромба дескриптора файла имеет свое место в создании инструментов командной строки. Это действует как <FH>
для чтения из дескриптора, за исключением того, что это волшебно выбирает, какой бы ни найден первым: имена файлов командной строки или STDIN. Взятый от perlop:
while (<>) {
... # code for each line
}
Проверка инфекции. С включенной проверкой инфекции жемчуг умрет (или предупредит, с -t
), при попытке передать испорченные данные (примерно разговор, данные снаружи программы) к небезопасной функции (открытие файла, выполнение внешней команды, и т.д.). Очень полезно при записи setuid сценариев или CGIs или чего-либо, где сценарий имеет большие полномочия, чем человек, подающий его данные.
Волшебство goto. goto &sub
делает оптимизированный последний вызов.
отладчик.
use strict
и use warnings
. Они могут сохранить Вас от набора опечаток.
m//
оператор имеет некоторые неясные особые случаи:
?
в качестве разделителя, он только соответствует однажды, если Вы не звоните reset
. '
в качестве разделителя, шаблон не интерполирован. while(/\G(\b\w*\b)/g) {
print "$1\n";
}
\G привязка. жарко .
($x, $y), = ($y, $x) то, что заставило меня хотеть изучить Perl.
конструктор списка 1.. 99 или 'a'.. 'zz' также очень хорош.
"Режим отчаяния" цикла 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";
Это - то, о чем я могу думать первое, что пришло на ум, который не был упомянут.
Я немного опаздываю стороне, но голосование за встроенную связанную хеш-функцию dbmopen()
- она помогла мне много. Это не точно база данных, но если необходимо сохранить данные к диску, это устраняет много проблем и Просто Работ. Это помогло мне начать, когда у меня не было базы данных, не понял Storable.pm, но я знал, что хотел выйти за рамки чтения и записи в текстовые файлы.
Хорошо. Вот другой. Динамический Обзор . Об этом говорили немного в различном сообщении, но я не видел его здесь на скрытых функциях.
Динамический Обзор как Autovivification имеет очень ограниченную сумму языков, которые используют его. Perl и язык Common LISP являются только двумя, я знаю того использования Динамический Обзор.
Мой фаворит полускрытая функция Perl eof
функция. Вот пример в значительной степени непосредственно от perldoc -f eof
это показывает, как можно использовать его для сброса имени файла и $.
(текущий номер строки) легко через несколько файлов, загруженных в командной строке:
while (<>) {
print "$ARGV:$.\t$_";
}
continue {
close ARGV if eof
}
Используйте lvalues для создания кода, действительно путающего:
my $foo = undef ;
sub bar:lvalue{ return $foo ;}
# Then later
bar = 5 ;
print bar ;
Очень поздно стороне, но: атрибуты.
Атрибуты по существу позволяют Вам определить произвольный код, который будет связан с объявлением переменной или подпрограммы. Лучший способ использовать их с Атрибут:: Обработчики ; это облегчает определять атрибуты (с точки зрения, что еще, атрибуты!).
я сделал представление использования их для декларативной сборки сменного класса и его плагинов в YAPC:: 2006, онлайн здесь . Это - довольно уникальная функция.
Можно заменить разделитель в 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!';
Еще один...
кэш Perl:
my $processed_input = $records || process_inputs($records_file);
На Открытом исходном коде Elpeleg, Perl CMS http://www.web-app.net/
Я лично люблю/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
Этот не особенно полезен, но это чрезвычайно тайно. Я наткнулся на это при рытье вокруг в синтаксическом анализаторе 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
действительно предупреждает!
Вы могли бы думать, что можно сделать это для сохранения памяти:
@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});
Оператор goatse *
:
$_ = "foo bar";
my $count =()= /[aeiou]/g; #3
или
sub foo {
return @_;
}
$count =()= foo(qw/a b c d/); #4
Он работает, потому что назначение списка в скалярном контексте дает количество элементов в назначаемом списке.
*
Обратите внимание, не совсем оператор
use Quantum::Superpositions;
if ($x == any($a, $b, $c)) { ... }
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.
Вы можете использовать @ {[...]} для получения интерполированного результата сложных выражений perl
$a = 3;
$b = 4;
print "$a * $b = @{[$a * $b]}";
выводит: 3 * 4 = 12
Разделитель входных записей может быть установлен на ссылку на число для чтения записей фиксированной длины:
$/ = \3; print $_,"\n" while <>; # output three chars on each line
Следующие строки такие же короткие, но более значимые, чем "~~", поскольку они указывают, что возвращается, и нет путаницы с оператором интеллектуального сопоставления:
print "".localtime; # Request a string
print 0+@array; # Request a number
Преобразование Шварца - это метод, который позволяет вам эффективно сортировать по вычисляемому вторичному индексу. Допустим, вы хотите отсортировать список строк по их сумме 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 раз.
Одним из полезных составных операторов для условного добавления строк или списков в другие списки является оператор 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();
] Есть более мощный способ проверки программы на синтаксические ошибки:
perl -w -MO=Lint,no-context myscript.pl
Самое важное, что он может сделать, это сообщить об ошибках 'unexistant subroutine'.
использовать повторную отладку
Документ по использованию повторной отладки
и
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, которые генерируют эти строки. Проверить это.
Две вещи, которые хорошо работают вместе: 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";