Иногда даже самый обычный, повседневный код приводит к фатальным ошибкам в программе. Любая из следующих типичных команд может стать причиной аварийного завершения:
$barney = $fred / $dino; # Деление на нуль? print "matchn" if /^($wilma)/; # Некорректное регулярное выражение? open CAVEMAN, $fred # Ошибка пользователя приводит к сбою die? or die "Can't open file '$fred' for input: $!";
Некоторые из этих ошибок можно выявить заранее, но обнаружить их все невозможно. (Как проверить строку $wilma из этого примера и убедиться в том, что она содержит корректное регулярное выражение?) К счастью, в Perl имеется простой способ перехвата фатальных ошибок – проверяемый код заключается в блок eval:
eval { $barney = $fred / $dino } ;
Даже если переменная $dino равна нулю, эта строка не приведет к сбою программы. В действительности eval является выражением (а не управляющей конструкцией, как while или foreach), поэтому точка с запятой в конце блока обязательна. Если во время выполнения блока eval происходит фатальная (в обычных условиях) ошибка, блок продолжает работать, но программа аварийно не завершается. Таким образом, сразу же после завершения eval желательно проверить, завершился ли блок нормально или произошла фатальная ошибка. Ответ содержится в специальной переменной $@. Если в блоке была перехвачена фатальная ошибка, $@ будет содержать «последние слова» программы – сообщение вида «Недопустимое деление на нуль в my_program строка 12». Если ошибки не было, переменная $@ пуста. Конечно, это означает, что $@ содержит удобный логический признак для проверки (true в случае ошибки), поэтому после блоков eval часто встречается команда следующего вида:
print "An error occurred: $@" if $@;
Блок eval является полноценным блоком, поэтому он определяет новую область видимости для лексических (my) переменных. В следующем фрагменте показан блок eval в действии:
foreach my $person (qw/ fred wilma betty barney dino pebbles /) {
eval {
open FILE, "<$person"
or die "Can't open file '$person': $!";
my($total, $count);
while (<FILE>) {
$total += $_;
$count++;
}
my $average = $total/$count;
print "Average for file $person was $averagen";
&do_something($person, $average);
};
if ($@) {
print "An error occurred ($@), continuingn";
}
}
Сколько возможных фатальных ошибок перехватывает этот блок? Если произойдет ошибка при открытии файла, она будет перехвачена. Вычисление среднего арифметического может привести к делению на нуль, и эта ошибка тоже перехватывается. Даже вызов загадочной функции &do_something защищается от фатальных ошибок, потому что блок eval перехватывает все фатальные ошибки, происходящие во время его активности. (В частности, это будет удобно, если вы вызываете пользовательскую функцию, написанную другим программистом, но не знаете, насколько надежно она написана.) Если ошибка происходит в ходе обработки одного из файлов, мы получим сообщение об ошибке, но программа спокойно перейдет к следующему файлу. Блоки eval даже могут вкладываться в другие блоки eval. Внутренний блок перехватывает ошибки во время выполнения, не позволяя им добраться до внешних блоков. (Конечно, после завершения внутреннего блока eval можно «перезапустить» ошибку при помощи die, чтобы она была перехвачена внешним блоком.) Блок eval перехватывает любые ошибки, происходящие во время выполнения, в том числе и ошибки при вызове функций (как показано в предыдущем примере).
Ранее мы уже упоминали о том, что eval является выражением, и поэтому после завершающей фигурной скобки необходима точка с запятой. Но как и любое выражение, eval имеет некоторое возвращаемое значение. При отсутствии ошибок значение вычисляется по аналогии с функциями: как результат последнего вычисленного выражения или как значение, возвращаемое на более ранней стадии необязательным ключевым словом return. А вот другой способ выполнения вычислений, при котором вам не нужно беспокоиться о делении на нуль:
my $barney = eval { $fred / $dino };
Если eval перехватывает фатальную ошибку, возвращаемое значение представляет собой либо undef, либо пустой список (в зависимости от контекста). Таким образом, в предыдущем примере $barney либо содержит правильный результат деления, либо undef; проверять $@ необязательно (хотя, вероятно, перед дальнейшим использованием $barney стоит включить проверку defined($barney)). Существуют четыре вида проблем, которые eval перехватить не может. Первую группу составляют очень серьезные ошибки, нарушающие работу Perl, – нехватка памяти или получение необработанного сигнала. Поскольку Perl при этом перестает работать, перехватить эти ошибки он не сможет. Конечно, синтаксические ошибки в блоке eval перехватываются на стадии компиляции – они никогда не возвращаются в $@. Оператор exit завершает программу немедленно, даже если он вызывается в пользовательской функции в блоке eval. (Отсюда следует, что при написании пользовательской функции в случае возникновения проблем следует использовать die вместо exit.)
Четвертую и последнюю разновидность проблем, не перехватываемых блоком eval, составляют предупреждения – пользовательские (из warn) или внутренние (включаемые ключом командной строки –w или директивой use warnings). Для перехвата предупреждений существует специальный механизм, не связанный с eval; за информацией обращайтесь к описанию псевдосигнала __WARN__ в документации Perl. Стоит также упомянуть еще об одной форме eval, которая может быть опасна при неправильном использовании. Более того, некоторые люди считают, что eval вообще не следует использовать в программах по соображениям безопасности. Действительно, eval следует использовать с осторожностью, но здесь имеется в виду другая форма eval – «eval для строк». Если же за ключевым словом eval сразу же следует блок программного кода в фигурных скобках, беспокоиться не о чем – эта разновидность eval безопасна.
Perl eval built-in function is very powerful. In this article let us review how to use regex in eval, trapping errors using eval, create dynamic code using eval, insert a code from a file/sub-routine using eval etc.,
The general form of perl eval expects a expression or a block of code as an argument.
1. Differences Between Various Perl Eval Statements
Let us consider the following perl code snippet:
$expr = ‘$a + $b’;
eval $expr; # 1
eval “$expr”; # 2
eval ‘$expr’; # 3
eval { $expr }; # 4
Case #1 and #2 are identical where perl identifies them as a valid executable statement and evaluates the expression. So, it would produce the result as “30”.
In case #3, the expression cannot be expanded. So, it gives actual expression ($a + $b) as a result. This wont be commonly used by anyone.
Case #4 is identical to case #3, but the statements inside the block is validated for syntax errors at compile time.
2. Regular Expressions Handling with Eval
With the use of eval, we can reduce the number of lines in the code considerably when it needs to match the line for more than a number of regular expressions.
The list of regular expressions can be put into a container (hash / array), and in a loop the regular expressions can be taken one by one and matches with the input line as shown below.
$line = <>;
%hash = (
number => qr/^[0-9]+$/,
alphabets => qr/^[a-zA-Z]+$/
);
while( my ($key,$value) = each(%hash) ) {
if(eval "$line =~ /$value/") {
print "$keyn";
}
}
3. Perl Eval Error Handling – Trapping Errors
Eval is used to trap the errors. During the execution of the subroutine the program might die because of errors, or external calling of die function. During this time, if the block of perl code is executed inside the eval, then program continues to run even after the die or errors, and it also captures the errors or dieing words.
Zero Divide Error:
eval { $average = $total / $count };
print “Error captured : $@n”;
In the above, $count contains the value as 0. When we run the code without the eval block, the program gets exit.
Run After Die
sub func
{
die “dieing in subroutine funcn”;
}
eval { func(); };
print “Error captured : $@n”;
Perl eval can’t catch following errors:
- Uncaught signal
- Running out of memory
- Syntax errors
4. Dynamic Perl Code Using Eval
Eval can compile and executes code from a string at runtime. So, we can write the dynamic perl program using eval.
print “Enter number 1 : ”; $data1 = ; print “Enter number 2 : ”; $data2 = ; print “Enter operator : ”; $operator = ; $str = “$data1 $operator $data2”; $result = eval “$data1 $operator $data2”;
We can execute any number of statements in eval. The result of the eval is the last evaluated expression.
We should be care in using eval on a string, as it might execute untrusted data from a string. If the assignment operations has to be done in the string itself, we should be care on handling the lvalue.
$str = “$result = $data1 $operator $data2”;
eval { $str };
5. Inserting Perl Script From a File or Subroutine during Run Time
In perl we can dynamically load modules at run time. To load modules dynamically, we have to use “require” ( not “use”).
Sample code to load module when the input file is a compressed one,
$filetype = `file $InputFile`;
if($filetype =~ /gzip compressed/) {
print "compressed input file...n";
eval { require PerlIO::gzip; };
}
Common subroutines that are used in the programs can be separated into a file that can be loaded into the perl programs by eval as shown below.
File : common_routines.pl
sub open_file
{
....
}
sub read_file
{
....
}
sub write_file
{
....
}
sub close_file
{
....
}
In the perl script,
sub load_file_subroutines
{
open CODE, 'common_routines.pl';
undef $;
my $code = <code>;
close CODE;
eval $code;
die $@ if $@;
}</code>
6. Perl Eval in Input Time-Outs
The alarm standard library function is used to generate SIGALRM signal after a certain time. This would mainly helps us to avoid the blocking wait on the user input. This can be used with eval to get the user input within a specified time as shown in the example below.
$SIG{ALRM} = &input_timed_out;
eval {
alarm (10);
$buf = <>;
alarm(0); # Cancel the pending alarm if user responds.
};
if ($@ =~ /NO USER INPUT IN TIME/) {
print "Timed out.n";
}
sub input_timed_out {
die "NO USER INPUT IN TIME";
}
I’ve noticed that Exception.pm and Error.pm don’t seem to be extensively used in the Perl community. Is that due to the large footprint of eval for exception handling?
Also Perl programs appear to have a much more lenient policy regarding exception handling in general. Is there a compelling reason for this?
In any event what would be the best method for exception handling in Perl?
the Tin Man
157k41 gold badges211 silver badges300 bronze badges
asked Oct 23, 2010 at 21:53
![]()
ennuikillerennuikiller
45.9k14 gold badges110 silver badges137 bronze badges
2
The consensus of the Perl community seems to be that Try::Tiny is the preferred way of doing exception handling. The «lenient policy» you refer to is probably due to a combination of:
- Perl not being a fully object-oriented language. (e.g. in contrast to Java where
you can’t avoid dealing with exceptions.) - The background of many Perl developers. (Languages like C1 and shell don’t have
exception mechanisms.) - The kind of tasks people tend to use Perl for. (Small scripts for text munging and
report generation where exception handling isn’t needed.) - Perl not having a (good) built-in exception mechanism.
Note that the last item means that you’ll see a lot of code like this:
eval { something() };
if ($@) {
warn "Oh no! [$@]n";
}
That’s exception handling even though it doesn’t use try/catch syntax. It’s fragile, though, and will break in a number of subtle edge cases that most people don’t think about. Try::Tiny and the other exception handling modules on CPAN were written to make it easier to get right.
1. C does have setjmp() and longjmp(), which can be used for a very crude form of exception handling.
answered Oct 23, 2010 at 22:08
Michael CarmanMichael Carman
30.5k9 gold badges73 silver badges122 bronze badges
3
Never test $@ as is, because it is a global variable, so even the test itself can change it.
General eval-template:
my $result;
eval {
$result= something();
# ...
1; # ok
} or do {
my $eval_error= $@ || "error";
# ...
die $eval_error;
}; # needs a semicolon
In practice that is the lightest way. It still leaves a tiny room for funny $@ behaviour, but nothing that really concerned me enough.
answered Jan 17, 2019 at 9:45
As it has been mentioned you can use the traditional way with eval, but if you want to use more elaborate exception trapping, including with exception objects, then I recommend using the try-catch-finally blocks.
There are quite a few perl modules that provide it such as Nice::Try and Syntax::Keyword::Try, but Syntax::Keyword::Try does not provide exception variable assignment or exception class catch like
try
{
# something
}
catch( Exception $e )
{
# catch this in $e
}
Full disclosure: I am the developer of Nice::Try
answered Jun 2, 2020 at 4:45
![]()
JacquesJacques
9051 gold badge12 silver badges15 bronze badges
1
Originally the accepted way in Perl to signal an error was to return
undef and let the users of the function or module
decide what they want to do with it. If they even look at it.
In other languages throwing an exception is the standard way to signal an error.
Some of the Perl modules on CPAN follow the «return undef» path, others will throw an exception.
The question how to deal with that?
Parse dates
In this example we use the Time::Piece module
to parse strings represent dates. The strptime method accept a string representing
a date and a forma string using strptime formatting instructions. It then tries to parse the
string according to the formatting instructions. In our example the formatting instructions
«%d %b, %Y» mean we are expecting to have a number representing the days, followed
by a string representing the month (e.g. ‘Nov’), and then a 4-digit number representing the year.
examples/time_piece.pl
use 5.010;
use strict;
use warnings;
use Time::Piece;
my @dates = ("3 Nov, 1989", "Nov, 1989", "1 Jan, 1999");
foreach my $d (@dates) {
my $tp = Time::Piece->strptime($d, "%d %b, %Y");
say $tp;
}
If we run this code we’ll see the following output:
$ perl examples/time_piece.pl Fri Nov 3 00:00:00 1989 Error parsing time at .../Time/Piece.pm line 469.
What happened here is that we tried to parse 3 strings, but the 2nd string was incorrectly formatted.
The strptime method raised an exception to indicate this failure (probably by calling die)
that caused our script to die.
Catch the exception using eval
While there are other ways to handle exceptions using, for example
Try::Tiny, in this case we look
at the built-in eval statement.
If we wrap a piece of code in an eval block, the eval will capture any exception that might
happen within that block, and it will assign the error message to the $@ variable of Perl.
The simple way to do this looks like this:
(please note, there is a ; after the eval block.)
eval {
# code that might throw exception
};
if ($@) {
# report the exception and do something about it
}
A more robust way to write this looks like this:
eval {
# code that might throw exception
1; # always return true to indicate success
}
or do {
# this block executes if eval did not return true (bacuse of an exception)
# save the exception and use 'Unknown failure' if the content of $@ was already
# removed
my $error = $@ || 'Unknown failure';
# report the exception and do something about it
};
Here too, there is a trailing ;, but it is only after the do block.
Error handling for Time::Piece
We used the eval or do expression we have just seen.
In this solution we have both the creation of $tp
and its use inside the eval block. That’s because if we cannot parse
the date-string then there is no point in trying to us that variable.
examples/time_piece_eval.pl
use 5.010;
use strict;
use warnings;
use Time::Piece;
my @dates = ("3 Nov, 1989", "Nov, 1989", "1 Jan, 1999");
foreach my $d (@dates) {
eval {
my $tp = Time::Piece->strptime($d, "%d %b, %Y");
say $tp;
1;
} or do {
my $error = $@ || 'Unknown failure';
warn "Could not parse '$d' - $error";
};
}
If we run this script we’ll get the following:
Fri Nov 3 00:00:00 1989 Could not parse 'Nov, 1989' - Error parsing time at .../Time/Piece.pm line 469. Fri Jan 1 00:00:00 1999
This means, that although the second string could not parse and Time::Piece raised
an exception, we captured that exception, reported it and then let the foreach
loop go on to the third value that was properly parsed and printed.
In the comments, please wrap your code snippets within <pre> </pre> tags and use spaces for indentation.
Perl родился в Unix и поэтому может получить доступ ко всем распространенным системным вызовам Unix.В средах,отличных от Unix,функциональность некоторых системных вызовов Unix может быть недоступна или подробная информация о доступной функциональности может незначительно отличаться.Это влияет на функции Perl:
Дополнительные сведения о переносимости этих функций см. В perlport и другой доступной документации для конкретной платформы.
Файл test, где X — одна из букв, перечисленных ниже. Этот унарный оператор принимает один аргумент, либо имя файла, либо дескриптор файла, либо дескриптор каталога, и проверяет связанный файл, чтобы узнать, верно ли что-то о нем. Если аргумент опущен, проверяется $_ , за исключением -t , который проверяет стандартный ввод. Если не указано иное, он возвращает 1 для истинного и '' для ложного. Если файл не существует или не может быть проверен, он возвращает undef и устанавливает $! (ошибка). За исключением проверки -l , все они переходят по символическим ссылкам, поскольку используют stat() , а не lstat() .(поэтому оборванные символические ссылки не могут быть проверены и, следовательно, сообщат об ошибке).
Несмотря на забавные названия,старшинство такое же,как и у любого другого унарного оператора.Оператор может быть любым из:
-r File is readable by effective uid/gid. -w File is writable by effective uid/gid. -x File is executable by effective uid/gid. -o File is owned by effective uid. -R File is readable by real uid/gid. -W File is writable by real uid/gid. -X File is executable by real uid/gid. -O File is owned by real uid. -e File exists. -z File has zero size (is empty). -s File has nonzero size (returns size in bytes). -f File is a plain file. -d File is a directory. -l File is a symbolic link (false if symlinks aren't supported by the file system). -p File is a named pipe (FIFO), or Filehandle is a pipe. -S File is a socket. -b File is a block special file. -c File is a character special file. -t Filehandle is opened to a tty. -u File has setuid bit set. -g File has setgid bit set. -k File has sticky bit set. -T File is an ASCII or UTF-8 text file (heuristic guess). -B File is a "binary" file (opposite of -T). -M Script start time minus file modification time, in days. -A Same for access time. -C Same for inode change time (Unix, may differ for other platforms)
Example:
while (<>) { chomp; next unless -f $_; }
Обратите внимание, что -s/a/b/ не выполняет замену с отрицанием. Однако использование -exp($foo) прежнему работает должным образом : только отдельные буквы, следующие за минусом, интерпретируются как проверка файлов.
Эти операторы освобождаются от «похожих на правило функции»,описанных выше.То есть открывающаяся скобка после оператора не влияет на то,сколько из следующего кода составляет аргумент.Поставьте открывающие скобки перед оператором,чтобы отделить его от приведенного кода (конечно,это относится только к операторам,имеющим больший приоритет,чем унарные операторы):
-s($file) + 1024 # probably wrong; same as -s($file + 1024) (-s $file) + 1024 # correct
Интерпретация операторов прав доступа к файлам -r , -R , -w , -W , -x и -X по умолчанию основана исключительно на режиме файла и uid и gid пользователя. Могут быть и другие причины, по которым вы не можете прочитать, записать или выполнить файл: например, элементы управления доступом к сетевой файловой системе, ACL (списки управления доступом), файловые системы только для чтения и нераспознанные исполняемые форматы. Обратите внимание, что использование этих шести конкретных операторов для проверки возможности выполнения той или иной операции обычно является ошибкой, так как это может быть связано с условиями гонки.
Также обратите внимание, что для суперпользователя в локальных файловых системах тесты -r , -R , -w и -W всегда возвращают 1, а -x и -X возвращают 1, если в режиме установлен какой-либо бит выполнения. Таким образом, сценариям, запускаемым суперпользователем, может потребоваться выполнить stat , чтобы определить фактический режим файла, или временно установить свой эффективный uid на что-то другое.
Если вы используете ACL, существует прагма, называемая filetest , которая может давать более точные результаты, чем биты режима голой stat . При use filetest 'access' вышеупомянутые файловые тесты проверяют, может ли (не) быть предоставлено разрешение с использованием семейства системных вызовов access(2) . Также обратите внимание, что тесты -x и -X могут в соответствии с этой прагмой возвращать значение true, даже если не установлены биты разрешения на выполнение (или какие-либо дополнительные ACL разрешения на выполнение). Эта странность связана с определениями базовых системных вызовов. _ за реализации use filetest 'access' _специальный дескриптор файла не будет кэшировать результаты файловых тестов, когда действует эта прагма. Прочтите документацию по прагме filetest для получения дополнительной информации.
-T и -B тесты работают следующим образом . Первый блок или около того файла проверяется, чтобы увидеть, является ли он допустимым UTF-8, который включает символы, отличные от ASCII. Если да, то это файл -T . В противном случае эта же часть файла проверяется на наличие нечетных символов, таких как странные управляющие коды или символы с установленным старшим битом. Если более трети символов странные, это файл -B ; в противном случае это файл -T . Кроме того, любой файл, содержащий нулевой байт в исследуемой части, считается двоичным файлом. (Если выполняется в рамках языкового стандарта использования, который включает LC_CTYPE , нечетные символы — это все, что не является печатаемым или пробелом в текущем языковом стандарте.) Если -T или -B используются для дескриптора файла, проверяется текущий буфер ввода-вывода, а не первый блок. И -T , и -B возвращают истину для пустого файла или файла в EOF при тестировании дескриптора файла. Поскольку для выполнения теста -T вам необходимо прочитать файл , в большинстве случаев вы хотите сначала использовать -f для файла, как в next unless -f $file && -T $file .
Если любому из файловых тестов (или оператору stat или lstat ) присваивается специальный дескриптор файла, состоящий из одиночного подчеркивания, то используется структура stat предыдущего файлового теста (или оператора stat ),сохраняя системный вызов.(Это не работает с -t , и вам нужно помнить, что lstat и -l оставляют значения в структуре статистики для символической ссылки, а не для реального файла.) (Также, если буфер статистики был заполнен вызовом lstat , -T и -B сбросят его с результатами stat _ ). Пример:
print "Can do.n" if -r $a || -w _ || -x _; stat($filename); print "Readablen" if -r _; print "Writablen" if -w _; print "Executablen" if -x _; print "Setuidn" if -u _; print "Setgidn" if -g _; print "Stickyn" if -k _; print "Textn" if -T _; print "Binaryn" if -B _;
Начиная с Perl 5.10.0, как форма чисто синтаксического сахара, вы можете складывать операторы проверки файлов таким образом, что -f -w -x $file эквивалентно -x $file && -w _ && -f _ . (Это всего лишь причудливый синтаксис: если вы используете возвращаемое значение -f $file в качестве аргумента для другого оператора filetest, никакого особого волшебства не произойдет.)
Проблемы с переносимостью: «-X» в perlport .
Чтобы избежать путаницы потенциальных пользователей вашего кода с загадочными синтаксическими ошибками,поместите что-то подобное в верхнюю часть вашего скрипта:
use v5.10;
Возвращает абсолютное значение своего аргумента. Если VALUE опущено, используется $_ .
Принимает входящее соединение через сокет, как это делает accept (2) . Возвращает упакованный адрес, если это удалось, в противном случае — false. См. Пример в разделе «Сокеты: связь клиент / сервер» в perlipc .
В системах , которые поддерживают тесную-на-Exec флаг на файлах, флаг будет установлен для вновь открытого дескриптора файла, как определено значением $^F . Смотрите «$ ^ F» в perlvar .
Устанавливает доставку SIGALRM этому процессу по истечении заданного количества секунд настенных часов. Если SECONDS не указан, используется значение, хранящееся в $_ . (На некоторых машинах, к сожалению, прошедшее время может быть на одну секунду меньше или больше, чем вы указали из-за того, как подсчитываются секунды, а планирование процессов может еще больше задержать доставку сигнала.)
Одновременно может вести счет только один таймер. Каждый вызов отключает предыдущий таймер, и может быть передан аргумент 0 для отмены предыдущего таймера без запуска нового. Возвращаемое значение — это количество времени, оставшееся на предыдущем таймере.
Для задержек с более мелкой детализацией, чем одна секунда, модуль Time :: HiRes (из CPAN и начиная с Perl 5.8, часть стандартного дистрибутива) предоставляет ualarm . Вы также можете использовать Perl-версию select с четырьмя аргументами, оставив первые три аргумента неопределенными, или вы можете использовать интерфейс syscall для доступа к setitimer (2), если ваша система его поддерживает. Подробности смотрите в perlfaq8 .
Обычно ошибочно смешивать вызовы alarm и sleep , потому что sleep может быть реализован внутри вашей системы с alarm .
Если вы хотите использовать alarm для тайм-аута системного вызова, вам нужно использовать пару eval / die . Вы не можете полагаться на аварийный сигнал, вызывающий сбой системного вызова с помощью $! установите значение EINTR , потому что Perl устанавливает обработчики сигналов для перезапуска системных вызовов в некоторых системах. Использование eval / die всегда работает, по модулю предостережений, указанных в «Сигналах» в perlipc .
eval { local $SIG{ALRM} = sub { die "alarmn" }; alarm $timeout; my $nread = sysread $socket, $buffer, $size; alarm 0; }; if ($@) { die unless $@ eq "alarmn"; } else { }
Для получения дополнительной информации см. Perlipc .
Проблемы с переносимостью: «alarm» в perlport .
Возвращает ароктангент Y/X в диапазоне от -PI до PI.
Для операции касания вы можете использовать функцию Math::Trig::tan или использовать знакомое отношение:
sub tan { sin($_[0]) / cos($_[0]) }
Возвращаемое значение для atan2(0,0) определяется реализацией; обратитесь к странице руководства atan2 (3) для получения дополнительной информации.
Проблемы с переносимостью: «atan2» в perlport .
Привязывает сетевой адрес к сокету, как это делает bind (2) . Возвращает true в случае успеха и false в противном случае. ИМЯ должно быть упакованным адресом соответствующего типа для сокета. См. Примеры в разделе «Сокеты: обмен данными между клиентом и сервером» в perlipc .
Обеспечивает чтение или запись FILEHANDLE в «двоичном» или «текстовом» режиме в системах, где библиотеки времени выполнения различают двоичные и текстовые файлы. Если FILEHANDLE является выражением, значение берется как имя дескриптора файла. Возвращает true в случае успеха, в противном случае возвращает undef и устанавливает $! (ошибка).
В некоторых системах (как правило, в системах на базе DOS и Windows) binmode необходим, когда вы не работаете с текстовым файлом. Ради мобильности рекомендуется всегда использовать его, когда это уместно, и никогда не использовать, когда это неуместно. Кроме того, люди могут установить для своего ввода-вывода по умолчанию Unicode в кодировке UTF8, а не байты.
Другими словами: независимо от платформы используйте binmode для двоичных данных, например изображений.
Если LAYER присутствует,то это одна строка,но может содержать несколько директив.Директивы изменяют поведение файла.Если LAYER присутствует,использование binmode в текстовом файле имеет смысл.
Если LAYER опущен или указан как :raw , дескриптор файла становится пригодным для передачи двоичных данных. Это включает отключение возможной трансляции CRLF и пометку ее как байтов (в отличие от символов Unicode). Обратите внимание, что, несмотря на то, что может подразумеваться в«Programming Perl»(Camel, 3-е издание) или где-либо еще :raw — этоnotпросто инверсия :crlf . Другие слои, которые могут повлиять на двоичную природу потока:alsoинвалид. См. PerlIO и обсуждение переменной окружения PERLIO в perlrun .
В :bytes , :crlf , :utf8 , а также любые другие директивы вида :... , называется I / Olayers. Открытая прагма может быть использована для установления по умолчанию слоев I / O.
Параметр LAYER функции binmode описан как «DISCIPLINE» в «Программировании Perl, 3-е издание». Однако с момента публикации этой книги, которую многие называют «Camel III», консенсус в отношении наименования этой функциональности перешел от «дисциплины» к «слою». Поэтому вся документация этой версии Perl относится к «слоям», а не к «дисциплинам». А теперь вернемся к регулярно планируемой документации …
Чтобы пометить FILEHANDLE как UTF-8, используйте :utf8 или :encoding(UTF-8) . :utf8 просто помечает данные как UTF-8 без дополнительной проверки, а :encoding(UTF-8) проверяет, действительно ли данные являются действительными UTF-8. Более подробную информацию можно найти в PerlIO :: encoding .
В общем, binmode следует вызывать после open но до того, как будет произведен какой-либо ввод-вывод для дескриптора файла. Вызов binmode обычно сбрасывает любые ожидающие буферизованные выходные данные (и, возможно, ожидающие входные данные) на дескрипторе. Исключением является слой :encoding , который изменяет кодировку символов по умолчанию для дескриптора. :encoding слой иногда должен быть вызван в середине потока, и не смывать поток. :encoding также неявно накладывает на себя слой :utf8 , потому что внутри Perl работает с символами Unicode в кодировке UTF8.
Операционная система, драйверы устройств, библиотеки C и исполняющая система Perl — все сговорились, чтобы позволить программисту обрабатывать один символ ( n ) как ограничитель строки, независимо от внешнего представления. Во многих операционных системах собственное представление текстового файла совпадает с внутренним представлением, но на некоторых платформах внешнее представление n состоит из более чем одного символа.
Все варианты файлов Unix, Mac OS (старые и новые) и Stream_LF в VMS используют один символ для завершения каждой строки во внешнем представлении текста (даже если этот единственный символ — ВОЗВРАТ ПЕРЕДАЧИ на старых версиях Mac до Дарвина. ОС и является LINE FEED в Unix и большинстве файлов VMS). В других системах, таких как OS / 2, DOS и различных вариантах MS-Windows, ваша программа видит n как простой cJ , но в текстовых файлах хранятся два символа cMcJ . Это означает, что если вы не используете binmode в этих системах, последовательности cMcJ на диске будут преобразованы в n при вводе, а любой n в вашей программе будет преобразован обратно в cMcJ на выходе. Это то, что вам нужно для текстовых файлов, но это может иметь катастрофические последствия для двоичных файлов.
Еще одним следствием использования binmode (в некоторых системах) является то, что специальные маркеры конца файла будут рассматриваться как часть потока данных. Для систем из семейства Microsoft это означает, что если ваши двоичные данные содержат cZ , подсистема ввода-вывода будет рассматривать их как конец файла, если вы не используете binmode .
binmode важен не только для readline и print , но также и при использовании read , seek , sysread , syswrite и tell (подробности см. в perlport ). См. $/ и $ в perlvar , чтобы узнать, как вручную установить входные и выходные последовательности конца строки.
Проблемы с переносимостью: «binmode» в perlport .
Эта функция сообщает объекту, на который ссылается REF, что теперь это объект в пакете CLASSNAME. Если CLASSNAME — пустая строка, она интерпретируется как относящаяся к main пакету. Если CLASSNAME опущен, используется текущий пакет. Поскольку bless часто является последней вещью в конструкторе, для удобства он возвращает ссылку. Всегда используйте версию с двумя аргументами, если производный класс может унаследовать метод, выполняющий благословение. См. Perlobj, чтобы узнать больше о благословении (и благословении) объектов.
Старайтесь всегда благословлять объекты в именах CLASSNAME, написанных в смешанном регистре. Пространства имен со всеми именами в нижнем регистре считаются зарезервированными для прагм Perl. Встроенные типы имеют все имена в верхнем регистре. Чтобы избежать путаницы, вы также можете избегать таких имен пакетов. Рекомендуется избегать имени класса 0 , потому что большая часть кода ошибочно использует результат ref как истинное значение.
См. «Модули Perl» в perlmod .
Вырваться из given блока.
break доступен только в том случае, есливключена функция CORE:: . Функция "switch" включается автоматически с use v5.10 выше) в текущей области.
Возвращает контекст текущего чистого вызова подпрограммы perl.В скалярном контексте возвращает имя пакета вызывающего абонента,если естьisвызывающий объект (то есть, если мы находимся в подпрограмме, eval или require ) и неопределенное значение в противном случае. вызывающий никогда не возвращает подписки XS, и они пропускаются. Следующая подпрограмма на чистом Perl появится вместо подпрограммы XS в возвращаемых значениях вызывающей стороны. В контексте списка вызывающая сторона возвращает
my ($package, $filename, $line) = caller;
Подобно __FILE__ и __LINE__ , имя файла и номер строки, возвращаемые здесь, могут быть изменены с помощью механизма, описанного в разделе «Обычные старые комментарии (не!)» в perlsyn .
С помощью EXPR он возвращает некоторую дополнительную информацию,которую отладчик использует для печати трассировки стека.Значение EXPR показывает,сколько кадров вызова нужно вернуть до текущего.
my ($package, $filename, $line, $subroutine, $hasargs, $wantarray, $evaltext, $is_require, $hints, $bitmask, $hinthash) = caller($i);
Здесь $subroutine — это функция, которую вызвал вызывающий объект (а не функция, содержащая вызывающий объект). Обратите внимание, что $subroutine может быть (eval) , если фрейм является не вызовом подпрограммы, а eval . В таком случае устанавливаются дополнительные элементы $evaltext и $is_require : $is_require имеет значение true, если фрейм создается оператором require или use , $evaltext содержит текст оператора eval EXPR . В частности, для оператора eval BLOCK $subroutine равно (eval) , но $evaltext не определено. (Заметьте также, что каждый оператор use создает фрейм require внутри eval EXPR frame.) $subroutine также может быть (unknown) если эта конкретная подпрограмма была удалена из таблицы символов. $hasargs имеет значение true, если для фрейма был установлен новый экземпляр @_ . $hints и $bitmask содержат прагматические подсказки, с которыми был скомпилирован вызывающий код. $hints соответствует $^H , а $bitmask соответствует ${^WARNING_BITS} . Значения $hints и $bitmask могут изменяться между версиями Perl и не предназначены для внешнего использования.
$hinthash — это ссылка на хэш, содержащий значение %^H , когда вызывающая программа была скомпилирована, или undef , если %^H было пустым. Не изменяйте значения этого хэша, так как они являются фактическими значениями, хранящимися в оптодереве.
Обратите внимание, что единственными видимыми типами кадров вызовов являются вызовы подпрограмм и eval . Другие формы контекста, такие как циклы while или foreach или блоки try , не считаются интересными для caller , поскольку они не изменяют поведение return выражения.
Кроме того, при вызове из пакета БД в контексте списка и с аргументом вызывающий объект возвращает более подробную информацию: он устанавливает переменную списка @DB::args в качестве аргументов, с которыми была вызвана подпрограмма.
Имейте в виду, что оптимизатор мог оптимизировать кадры вызовов до того, как caller получила возможность получить информацию. Это означает, что caller(N) может не вернуть информацию о кадре вызова, который вы ожидаете, для N > 1 . В частности, @DB::args может иметь информацию о предыдущем вызове caller .
Имейте в виду , что установка @DB::args являетсяbest effort, предназначенный для отладки или генерации обратных трассировок, и на него не следует полагаться. В частности, поскольку @_ содержит псевдонимы аргументов вызывающего, Perl не принимает копию @_ , поэтому @DB::args будет содержать модификации, которые подпрограмма вносит в @_ или его содержимое, а не исходные значения во время вызова. @DB::args , как и @_ , не содержит явных ссылок на свои элементы, поэтому в некоторых случаях его элементы могли быть освобождены и перераспределены для других переменных или временных значений. Наконец, побочным эффектом текущей реализации является то, что эффекты shift @_ могутnormallyбыть отмененным (но не pop @_ или другим соединением,andнет, если ссылка на @_ была взята,andс учетом оговорки о перераспределенных элементах), поэтому @DB::args на самом деле является гибридом текущего состояния и начального состояния @_ . Предостережение для покупателя.
Изменяет рабочий каталог на EXPR, если это возможно. Если EXPR опущен, переходит в каталог, указанный $ENV{HOME} , если он установлен; если нет, переходит в каталог, указанный $ENV{LOGDIR} . (В VMS переменная $ENV{'SYS$LOGIN'} также проверяется и используется, если она установлена.) Если ни одна из них не установлена, chdir ничего не делает и завершается ошибкой. В случае успеха возвращает true, в противном случае — false. См. пример под die .
В системах, поддерживающих fchdir (2) , вы можете передать дескриптор файла или каталога в качестве аргумента. В системах, которые не поддерживают fchdir (2) , передача дескрипторов вызывает исключение.
Изменяет права доступа к списку файлов.Первым элементом списка должен быть цифровой режим,который,вероятно,должен быть восьмеричным числом,и который,безусловно,долженnotбыть строкой восьмеричных цифр: 0644 — это нормально, а "0644" — нет. Возвращает количество успешно измененных файлов. См. также oct , если все, что у вас есть, это строка.
my $cnt = chmod 0755, "foo", "bar"; chmod 0755, @executables; my $mode = "0644"; chmod $mode, "foo"; my $mode = "0644"; chmod oct($mode), "foo"; my $mode = 0644; chmod $mode, "foo";
В системах, поддерживающих fchmod (2) , вы можете передавать дескрипторы файлов между файлами. В системах, которые не поддерживают fchmod (2) , передача дескрипторов файлов вызывает исключение. Для распознавания дескрипторы файлов должны передаваться как глобусы или ссылки на глобусы; голые слова считаются именами файлов.
open(my $fh, "<", "foo"); my $perm = (stat $fh)[2] & 07777; chmod($perm | 0600, $fh);
Вы также можете импортировать символьные константы S_I* из модуля Fcntl :
use Fcntl qw( :mode ); chmod S_IRWXU|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH, @executables;
Проблемы с переносимостью: «chmod» в perlport .
Эта более безопасная версия команды chop удаляет всю завершающую строку, соответствующую текущему значению $/ (также известному как $INPUT_RECORD_SEPARATOR в English модуле). Он возвращает общее количество символов, удаленных из всех его аргументов. Он часто используется для удаления новой строки в конце входной записи, когда вы обеспокоены тем, что в окончательной записи может отсутствовать новая строка. В режиме абзаца ( $/ = '' ) он удаляет все завершающие символы новой строки из строки. В режиме slurp ( $/ = undef ) или в режиме записи фиксированной длины ( $/ является ссылкой на целое число или подобное; см. perlvar ), chomp ничего не удалит. Если переменная VARIABLE опущена, она поглощает $_ . Пример:
while (<>) { chomp; my @array = split(/:/); }
Если VARIABLE является хешем, она поглощает значения хеша, но не его ключи, сбрасывая каждый each в процессе.
Ты можешь на самом деле нажимать все,что имеет ценность,включая задание:
chomp(my $cwd = `pwd`); chomp(my $answer = <STDIN>);
Если вы расплющиваете список,то каждый элемент расплющивается,и возвращается общее количество удаленных символов.
Обратите внимание, что круглые скобки необходимы, когда вы перевариваете все, что не является простой переменной. Это потому, что chomp $cwd = `pwd`; интерпретируется как (chomp $cwd) = `pwd`; , а не как chomp( $cwd = `pwd` ) вы могли ожидать. Аналогично, chomp $a, $b интерпретируется как chomp($a), $b а не как chomp($a, $b) .
Отсекает последний символ строки и возвращает отрезанный символ. Это намного эффективнее, чем s/.$//s , поскольку не сканирует и не копирует строку. Если VARIABLE опущен, отбивает $_ . Если VARIABLE является хэшем, она отсекает значения хеша, но не его ключи, сбрасывая каждый each в процессе.
Ты можешь нарезать все,что имеет ценность,включая задание.
Если вы нарезаете список, каждый элемент нарезается. Возвращается только значение последней chop
Обратите внимание, что chop возвращает последний символ. Чтобы вернуть все символы, кроме последнего, используйте substr($string, 0, -1) .
См. также chomp .
Изменение владельца (и группы)списка файлов.Первыми двумя элементами списка должны бытьnumericУид и Гид,в таком порядке.Значение -1 в любой позиции интерпретируется большинством систем,чтобы оставить это значение без изменений.Возвращает количество успешно измененных файлов.
my $cnt = chown $uid, $gid, 'foo', 'bar'; chown $uid, $gid, @filenames;
В системах, поддерживающих fchown (2) , вы можете передавать дескрипторы файлов между файлами. В системах, которые не поддерживают fchown (2) , передача дескрипторов файлов вызывает исключение. Для распознавания дескрипторы файлов должны передаваться как глобусы или ссылки на глобусы; голые слова считаются именами файлов.
Вот пример,который ищет нецифровые uids в файле passwd:
print "User: "; chomp(my $user = <STDIN>); print "Files: "; chomp(my $pattern = <STDIN>); my ($login,$pass,$uid,$gid) = getpwnam($user) or die "$user not in passwd file"; my @ary = glob($pattern); chown $uid, $gid, @ary;
На большинстве систем вам не разрешается изменять право собственности на файл,если только вы не являетесь суперпользователем,хотя вы должны иметь возможность изменять группу на любую из ваших вторичных групп.На небезопасных системах эти ограничения могут быть смягчены,но это не переносное предположение.На POSIX системах вы можете обнаружить это условие таким образом:
use POSIX qw(sysconf _PC_CHOWN_RESTRICTED); my $can_chown_giveaway = ! sysconf(_PC_CHOWN_RESTRICTED);
Проблемы с переносимостью: «chown» в perlport .
Возвращает символ, представленный этим НОМЕРОМ в наборе символов. Например, chr(65) — это "A" в ASCII или Unicode, а chr (0x263a) — это смайлик Unicode.
Отрицательные значения дают символ замены Unicode (chr (0xfffd)), за исключением прагмы bytes , где используются младшие восемь бит значения (усеченные до целого числа).
Если ЧИСЛО опущено, используется $_ .
Для обратного используйте ord .
Обратите внимание,что символы от 128 до 255 (включительно)по умолчанию внутренне не закодированы как UTF-8 по причинам обратной совместимости.
См. Perlunicode для получения дополнительной информации о Unicode.
Эта функция работает так же, как и системный вызов с тем же именем: она делает именованный каталог новым корневым каталогом для всех дальнейших путей, начинающихся с / / вашего процесса и всех его дочерних элементов. (Он не изменяет ваш текущий рабочий каталог, на который это не влияет.) Из соображений безопасности этот вызов ограничен суперпользователем. Если FILENAME не указан, выполняет chroot для $_ .
ПРИМЕЧАНИЕ. В целях безопасности обязательно указывать chdir("/") ( chdir в корневой каталог) сразу после chroot chroot иначе текущий рабочий каталог может оказаться за пределами нового корня.
Проблемы с переносимостью: «chroot» в perlport .
Закрывает файл или трубку,связанную с файловой рукояткой,промывает буферы ввода-вывода и закрывает дескриптор системного файла.Возвращает true,если эти операции прошли успешно,и если ни один слой PerlIO не сообщил об ошибке.Закрывает текущий выбранный файловый дескриптор,если аргумент опущен.
Вам не нужно закрывать FILEHANDLE, если вы собираетесь сразу open его еще раз, потому что open закроет его для вас. (См. open .) Однако явное close входного файла сбрасывает счетчик строк ( $. ), в то время как неявное закрытие, выполненное с помощью open , этого не делает.
Если дескриптор файла получен из конвейерного открытия, close возвращает false, если один из других задействованных системных вызовов терпит неудачу или если его программа завершается с ненулевым статусом. Если единственная проблема заключалась в том, что программа завершилась с ненулевым значением, $! будет установлено на 0 . Закрытие канала также ожидает завершения процесса, выполняющегося в канале, — на случай, если вы захотите впоследствии просмотреть вывод канала — и неявно помещает значение статуса выхода этой команды в $? и ${^CHILD_ERROR_NATIVE} .
Если запущено несколько потоков, close дескриптора файла из конвейерного открытия возвращает значение true, не дожидаясь завершения дочернего процесса, если дескриптор файла все еще открыт в другом потоке.
Закрытие прочитанного конца трубы до того,как процесс записи на другой конец будет завершен,приводит к тому,что записывающее устройство получит СИГНАЛ.Если другой конец не может с этим справиться,обязательно прочитайте все данные перед тем,как закрывать трубу.
Example:
open(OUTPUT, '|sort >foo') or die "Can't start sort: $!"; close OUTPUT or warn $! ? "Error closing sort pipe: $!" : "Exit status $? from sort"; open(INPUT, 'foo') or die "Can't open 'foo' for input: $!";
FILEHANDLE может быть выражением,значение которого может быть использовано в качестве косвенного файлового дескриптора,обычно это настоящее имя файлового дескриптора или автоповидимый дескриптор.
Закрывает каталог, открытый opendir , и возвращает успешное выполнение этого системного вызова.
Попытки подключиться к удаленному сокету, как и connect (2) . Возвращает true в случае успеха и false в противном случае. ИМЯ должно быть упакованным адресом соответствующего типа для сокета. См. Примеры в разделе «Сокеты: обмен данными между клиентом и сервером» в perlipc .
Когда за ним следует BLOCK, continue на самом деле является оператором управления потоком, а не функцией. Если к БЛОКУ присоединен continue while или foreach ), он всегда выполняется непосредственно перед повторным вычислением условного оператора, точно так же, как третья часть цикла for в C. Таким образом, это может быть используется для увеличения переменной цикла, даже если цикл был продолжен с помощью оператора next (что аналогично оператору continue C ).
last , next или redo могут появиться в continue ; last и redo ведут себя так, как если бы они были выполнены в основном блоке. То же самое и next , но, поскольку он будет выполнять continue , он может быть более интересным.
while (EXPR) { do_something; } continue { do_something_else; }
Пропуск секции continue эквивалентен использованию пустой секции, достаточно логично, поэтому next возвращается непосредственно к проверке условия в начале цикла.
Когда BLOCK отсутствует, continue является функцией, которая проходит через текущий блок when или default вместо итерации динамически включающего foreach или выхода из лексически включающего given . В Perl 5.14 и более ранних версиях эта форма continue была доступна только при включенной функции Дополнительную информацию см. в разделе feature и «Switch Statements» в perlsyn .
Возвращает косинус выражения EXPR (выраженный в радианах). Если EXPR опущено, принимает косинус $_ .
Для операции обратного косинуса вы можете использовать функцию Math::Trig::acos или использовать это соотношение:
sub acos { atan2( sqrt(1 - $_[0] * $_[0]), $_[0] ) }
Создает дайджест-строку точно так же, как функция crypt (3) в библиотеке C (при условии, что у вас действительно есть версия, которая не была уничтожена как потенциальное боеприпасы).
crypt — это односторонняя хеш-функция. PLAINTEXT и SALT превращаются в короткую строку, называемую дайджестом, которая возвращается. Одни и те же PLAINTEXT и SALT всегда будут возвращать одну и ту же строку, но нет (известного) способа получить исходный PLAINTEXT из хэша. Небольшие изменения в PLAINTEXT или SALT приведут к большим изменениям в дайджесте.
Функции расшифровки нет.Эта функция не так уж и полезна для криптографии (для этого ищитеCryptмодулей на ближайшем зеркале CPAN), а название «crypt» немного неверно. Вместо этого он в основном используется для проверки идентичности двух частей текста без необходимости передачи или сохранения самого текста. Пример — проверка правильности пароля. Сохраняется дайджест пароля, а не сам пароль. Пользователь вводит пароль, crypt с той же солью, что и сохраненный дайджест. Если два дайджеста совпадают, пароль правильный.
При проверке существующей строки дайджеста вы должны использовать дайджест в качестве соли (например, crypt($plain, $digest) eq $digest ). СОЛЬ, использованная для создания дайджеста, отображается как часть дайджеста. Это гарантирует, что crypt будет хешировать новую строку с той же солью, что и дайджест. Это позволяет вашему коду работать как со стандартной crypt и с более экзотическими реализациями. Другими словами, ничего не предполагайте ни о самой возвращаемой строке, ни о том, сколько байтов SALT может иметь значение.
Обычно результатом является строка из 13 байтов: два первых байта соли, за которыми следуют 11 байтов из набора [./0-9A-Za-z] , и только первые восемь байтов PLAINTEXT имеют значение. Но альтернативные схемы хеширования (например, MD5), схемы безопасности более высокого уровня (например, C2) и реализации на платформах, отличных от Unix, могут создавать разные строки.
При выборе новой соли создайте случайную двухсимвольную строку, символы которой происходят из набора [./0-9A-Za-z] (например, join '', ('.', '/', 0..9, 'A'..'Z', 'a'..'z')[rand 64, rand 64] ). Этот набор символов является всего лишь рекомендацией; символы, разрешенные в соли, зависят исключительно от библиотеки crypt вашей системы, и Perl не может ограничить то, какие соли принимает crypt .
Вот пример,который гарантирует,что кто бы ни запустил эту программу,он знает свой пароль:
my $pwd = (getpwuid($<))[1]; system "stty -echo"; print "Password: "; chomp(my $word = <STDIN>); print "n"; system "stty echo"; if (crypt($word, $pwd) ne $pwd) { die "Sorry...n"; } else { print "okn"; }
Конечно,вводить свой собственный пароль тому,кто вас об этом попросит,неразумно.
Функция crypt не подходит для хеширования больших объемов данных, не в последнюю очередь потому, что вы не можете получить информацию обратно. Посмотрите на модуль Digest для более надежных алгоритмов.
При использовании crypt в строке Unicode (котораяpotentiallyимеет символы с кодовыми точками выше 255), Perl пытается разобраться в ситуации, пытаясь понизить (копию) строки до восьмибитной байтовой строки перед вызовом crypt (для этой копии). Если это сработает, хорошо. В противном случае crypt умирает с Wide character in crypt .
Проблемы с переносимостью: «crypt» в perlport .
[Эта функция была в значительной степени заменена функцией untie .]
Разрывает связь между файлом DBM и хэшем.
Проблемы с переносимостью: «dbmclose» в perlport .
[Эта функция была в значительной степени заменена функцией tie .]
Это связывает файл dbm (3) , ndbm (3) , sdbm (3) , gdbm (3) или Berkeley DB с хешем. HASH — это имя хеша. (В отличие от обычного open , первый аргументnotручка файла,даже если она выглядит как одна из них).DBNAME-это имя базы данных (без.diror.pagрасширение, если оно есть). Если база данных не существует, она создается с защитой, указанной MASK (измененной umask umask . Чтобы предотвратить создание базы данных, если она не существует, вы можете указать MODE равным 0, и функция вернет ложное значение, если не сможет найти существующую базу данных. Если ваша система поддерживает только старые функции DBM, вы можете сделать только один вызов dbmopen в своей программе. В старых версиях Perl, если в вашей системе не было ни DBM, ни ndbm, вызов dbmopen приводил к фатальной ошибке; теперь он возвращается к sdbm(3) .
Если у вас нет прав на запись в файл DBM, вы можете только читать хэш-переменные, но не устанавливать их. Если вы хотите проверить, можете ли вы писать, либо используйте файловые тесты, либо попробуйте установить фиктивную хэш-запись внутри eval, eval отловить ошибку.
Обратите внимание, что такие функции, как keys и values , могут возвращать огромные списки при использовании с большими файлами DBM. Вы можете предпочесть использовать функцию each для перебора больших файлов DBM. Пример:
dbmopen(%HIST,'/usr/lib/news/history',0666); while (($key,$val) = each %HIST) { print $key, ' = ', unpack('L',$val), "n"; } dbmclose(%HIST);
См. Также AnyDBM_File для более общего описания плюсов и минусов различных подходов к dbm, а также DB_File для особенно богатой реализации.
Вы можете контролировать, какую библиотеку DBM вы используете, загрузив эту библиотеку перед вызовом dbmopen :
use DB_File; dbmopen(%NS_Hist, "$ENV{HOME}/.netscape/history.db") or die "Can't open netscape history file: $!";
Проблемы с переносимостью: «dbmopen» в perlport .
Возвращает логическое значение, указывающее, имеет ли EXPR значение, отличное от неопределенного значения undef . Если EXPR отсутствует, проверяется $_ .
Многие операции возвращают undef , чтобы указать на сбой, конец файла, системную ошибку, неинициализированную переменную и другие исключительные ситуации. Эта функция позволяет отличать undef от других значений. (Простой логический тест не различает undef , ноль, пустую строку и "0" , которые одинаково ложны.) Обратите внимание, что, поскольку undef является допустимым скаляром, его присутствие неnecessarilyуказать исключительное состояние: pop возвращает undef , когда его аргумент является пустым массивом,orкогда возвращаемый элемент оказывается undef .
Вы также можете использовать defined(&func) чтобы проверить, была ли когда-либо определена подпрограмма func . На возвращаемое значение не влияют какие-либо предварительные объявления func . Подпрограмма, которая не определена, все еще может быть вызываемой: ее пакет может иметь метод AUTOLOAD , который запускает ее существование при первом вызове; см. perlsub .
Использование defined агрегатов (хэши и массивы) больше не поддерживается. Раньше он сообщал, была ли когда-либо выделена память для этого агрегата. Вместо этого вы должны использовать простой тест на размер:
if (@an_array) { print "has array elementsn" } if (%a_hash) { print "has hash membersn" }
При использовании с хэш-элементом он сообщает вам, определено ли значение, а не существует ли ключ в хеше. Использование exists для последней цели.
Examples:
print if defined $switch{D}; print "$valn" while defined($val = pop(@ary)); die "Can't readlink $sym: $!" unless defined($value = readlink $sym); sub foo { defined &$bar ? $bar->(@_) : die "No bar"; } $debugging = 0 unless defined $debugging;
Примечание. Многие люди склонны злоупотреблять defined , а затем с удивлением обнаруживают, что числа 0 и "" (строка нулевой длины) на самом деле являются определенными значениями. Например, если вы говорите
"ab" =~ /a(.*)b/
Совпадение с образцом завершается успешно, и определяется $1 ,хотя он не соответствует «ничего».На самом деле ничего не совпало. Скорее, он соответствовал чему-то, что оказалось нулевым символом. Все очень откровенно и честно. Когда функция возвращает неопределенное значение, это признание того, что она не может дать вам честный ответ. Таким образом, вы должны использовать defined только тогда, когда ставите под сомнение целостность того, что вы пытаетесь сделать. В других случаях вам нужно простое сравнение с 0 или "" .
См. также undef , exists , ref .
При заданном выражении, определяющем элемент или срез хэша, delete удаляет указанные элементы из этого хэша, так что exists в этом элементе больше не возвращают значение true. Установка хеш-элемента в неопределенное значение не удаляет его ключ, но удаляет его; см. exists .
В контексте списка обычно возвращает значение или удаленные значения или последний такой элемент в скалярном контексте. Длина возвращаемого списка соответствует длине списка аргументов: удаление несуществующих элементов возвращает неопределенное значение в соответствующих позициях. Начиная с Perl 5.28, срез хэша ключ/значение может быть передан в delete , а возвращаемое значение представляет собой список пар ключ/значение (два элемента для каждого элемента, удаленного из хэша).
delete также можно использовать для массивов и срезов массивов, но его поведение менее прямолинейно. Хотя exists вернет false для удаленных записей, удаление элементов массива никогда не изменяет индексы существующих значений; используйте shift или splice для этого. Однако, если какие-либо удаленные элементы попадают в конец массива, размер массива уменьшается до положения самого высокого элемента, который все еще проверяет true на exists , или до 0, если ни один не соответствует. Другими словами, массив не будет иметь завершающих несуществующих элементов после удаления.
ПРЕДУПРЕЖДЕНИЕ. Вызов delete для значений массива настоятельно не рекомендуется. Идея удаления или проверки существования элементов массива Perl концептуально нелогична и может привести к неожиданному поведению.
Удаление из %ENV изменяет среду. Удаление из хэша, привязанного к файлу DBM, удаляет запись из файла DBM. Удаление из tied хэша или массива может не обязательно что-то возвращать; это зависит от реализации метода DELETE tied пакета, который может делать все, что ему заблагорассудится.
Конструкция delete local EXPR локализует удаление в текущем блоке во время выполнения. Пока блок не выйдет, временно удаленные локально элементы больше не существуют. См. «Локальное удаление элементов составных типов» в perlsub .
my %hash = (foo => 11, bar => 22, baz => 33); my $scalar = delete $hash{foo}; $scalar = delete @hash{qw(foo bar)}; my @array = delete @hash{qw(foo baz)};
Далее (неэффективно)удаляются все значения %HASH и @ARRAY:
foreach my $key (keys %HASH) { delete $HASH{$key}; } foreach my $index (0 .. $#ARRAY) { delete $ARRAY[$index]; }
И это тоже:
delete @HASH{keys %HASH}; delete @ARRAY[0 .. $#ARRAY];
Но и то,и другое медленнее,чем присвоение пустого списка или неуточнение %HASH или @ARRAY,что является обычным способом опорожнения агрегата:
%HASH = (); undef %HASH; @ARRAY = (); undef @ARRAY;
EXPR может быть произвольно сложным при условии,что его конечной операцией является элемент или кусочек агрегата:
delete $ref->[$x][$y]{$key}; delete $ref->[$x][$y]->@{$key1, $key2, @morekeys}; delete $ref->[$x][$y][$index]; delete $ref->[$x][$y]->@[$index1, $index2, @moreindices];
die вызывает исключение. Внутри eval исключение помещается в $@ , и eval завершается с неопределенным значением. Если исключение находится за пределами всех вложенных eval , то неперехваченное исключение печатается в STDERR , и Perl завершает работу с кодом выхода, указывающим на ошибку. Если вам нужно выйти из процесса с помощью определенного кода выхода, см. exit .
Equivalent examples:
die "Can't cd to spool: $!n" unless chdir '/usr/spool/news'; chdir '/usr/spool/news' or die "Can't cd to spool: $!n"
В большинстве случаев die вызывается со строкой, используемой в качестве исключения. Вы можете указать один операнд, не являющийся ссылкой, который будет служить исключением, или список из двух или более элементов, которые будут преобразованы в строку и объединены для создания исключения.
Если исключение строки не заканчивается новой строкой, к ней добавляются текущий номер строки сценария и номер строки ввода (если есть), а также новая строка. Обратите внимание, что «номер строки ввода» (также известный как «кусок») зависит от того, какое понятие «строка» действует в настоящее время, и также доступен как специальная переменная $. . Смотрите «$ /» в perlvar и «$». в перлварь .
Подсказка: иногда добавление ", stopped" к вашему сообщению сделает его более понятным, если будет добавлена строка "at foo line 123" . Предположим, у вас запущен скрипт «канаста».
die "/etc/games is no good"; die "/etc/games is no good, stopped";
produce, respectively
/etc/games is no good at canasta line 123. /etc/games is no good, stopped at canasta line 123.
Если LIST был пуст или представлял собой пустую строку, а $@ уже содержит значение исключения (обычно из предыдущего eval ), то это значение используется повторно после добавления "t...propagated" . Это полезно для распространения исключений:
eval { ... }; die unless $@ =~ /Expected exception/;
Если LIST был пуст или превратился в пустую строку, а $@ содержит ссылку на объект, имеющую метод PROPAGATE , этот метод будет вызван с дополнительными параметрами номера файла и строки. Возвращаемое значение заменяет значение в $@ ; т.е. как если бы $@ = eval { $@->PROPAGATE(__FILE__, __LINE__) }; были позваны.
Если LIST был пуст или превратился в пустую строку, и $@ также пусто, то используется строка "Died" .
Вы также можете вызвать die с аргументом ссылки, и если он захвачен внутри eval eval $ $@ содержит эту ссылку. Это позволяет выполнять более сложную обработку исключений с использованием объектов, которые поддерживают произвольное состояние исключения. Такая схема иногда предпочтительнее сопоставления конкретных строковых значений $@ с регулярными выражениями.
Поскольку Perl преобразует сообщения о неперехваченных исключениях в строку перед отображением, вы, вероятно, захотите перегрузить операции строкования для объектов исключений. См. Подробности об этом в разделе « Перегрузка» . Строковое сообщение не должно быть пустым и должно заканчиваться новой строкой, чтобы соответствовать обработке строковых исключений. Кроме того, поскольку ссылка на объект исключения не может быть преобразована в строку без ее разрушения, Perl не пытается добавить местоположение или другую информацию к исключению ссылки. Если вам нужна информация о местоположении со сложным объектом исключения, вам нужно будет организовать размещение информации о местоположении в объекте самостоятельно.
Поскольку $@ является глобальной переменной, будьте осторожны, чтобы анализ исключения, eval , не заменял ссылку в глобальной переменной. Проще всего перед любыми манипуляциями сделать локальную копию референса. Вот пример:
use Scalar::Util "blessed"; eval { ... ; die Some::Module::Exception->new( FOO => "bar" ) }; if (my $ev_err = $@) { if (blessed($ev_err) && $ev_err->isa("Some::Module::Exception")) { } else { } }
Если неперехваченное исключение приводит к выходу интерпретатора, код выхода определяется по значениям $! и $? с этим псевдокодом:
exit $! if $!; exit $? >> 8 if $? >> 8; exit 255;
Как и в случае с exit , $? устанавливается до раскручивания стека вызовов; любые обработчики DESTROY или END могут затем изменить это значение и, следовательно, код выхода Perl.
Цель состоит в том, чтобы втиснуть как можно больше информации о вероятной причине в ограниченное пространство кода выхода системы. Однако, как $! это значение C errno , которое может быть установлено любым системным вызовом, это означает, что значение кода выхода, используемого die , может быть непредсказуемым, поэтому на него нельзя полагаться, кроме как на ненулевое значение.
Вы можете организовать обратный вызов непосредственно перед тем, как die сделает свое дело, установив хук $SIG{__DIE__} . Связанный обработчик вызывается с исключением в качестве аргумента и может изменить исключение, если сочтет нужным, снова вызвав die .См. «%SIG» в perlvar для получения подробной информации о настройке записей %SIG и eval для некоторых примеров. Хотя эта функция должна была запускаться только непосредственно перед выходом вашей программы, в настоящее время это не так: хук $SIG{__DIE__} в настоящее время вызывается даже внутри eval блоков/строк! Если вы хотите, чтобы крючок ничего не делал в таких ситуациях, поставьте
die @_ if $^S;
как первая строка обработчика (см. «$ ^ S» в perlvar ). Поскольку это способствует странным действиям на расстоянии, это противоречивое поведение может быть исправлено в будущих версиях.
См. также exit , warn и модуль Carp .
Не совсем функция. Возвращает значение последней команды в последовательности команд, обозначенной BLOCK. При изменении модификатором цикла while или until выполняет BLOCK один раз перед проверкой условия цикла. (В других операторах модификаторы цикла сначала проверяют условие.)
do BLOCK делаетnotсчитается циклом, поэтому операторы управления циклом next , last или redo не могут использоваться для выхода из блока или его перезапуска. См. perlsyn для альтернативных стратегий.
Использует значение EXPR в качестве имени файла и выполняет содержимое файла как сценарий Perl:
do '/foo/stat.pl'; do './stat.pl'; do '../foo/stat.pl'; do 'stat.pl'; do 'foo/stat.pl';
do './stat.pl' во многом похож на
eval `cat stat.pl`;
за исключением того, что он более краток, не запускает внешних процессов и отслеживает текущее имя файла для сообщений об ошибках. Он также отличается тем, что код, оцениваемый с помощью do FILE , не может видеть лексические элементы в охватывающей области; eval STRING делает. Однако то же самое в том смысле, что он выполняет повторный анализ файла каждый раз, когда вы его вызываете, поэтому вы, вероятно, не захотите делать это внутри цикла.
Использование do с относительным путем (кроме./and../), like
do 'foo/stat.pl';
будет искать в @INC и обновлять %INC если файл найден. См. «@INC» в perlvar и «% INC» в perlvar для этих переменных. В частности, обратите внимание, что, хотя исторически @INC содержал ‘.’ (текущий каталог), что делает эти два случая эквивалентными, что больше не обязательно так, как ‘.’ не включен в @INC по умолчанию в версиях perl 5.26.0 и новее. Вместо этого теперь perl будет предупреждать:
do "stat.pl" failed, '.' is no longer in @INC; did you mean do "./stat.pl"?
Если do может прочитать файл, но не может его скомпилировать, он возвращает undef и устанавливает сообщение об ошибке в $@ . Если do не может прочитать файл, он возвращает undef и устанавливает $! к ошибке. Всегда сначала проверяйте $@ , так как компиляция может привести к сбою, который также установит $! . Если файл успешно скомпилирован, do возвращает значение последнего вычисленного выражения.
Включение библиотечных модулей лучше выполнять с помощью операторов use и require , которые также выполняют автоматическую проверку ошибок и вызывают исключение в случае возникновения проблемы.
Вы можете использовать do для чтения файла конфигурации программы. Ручную проверку ошибок можно выполнить следующим образом:
for $file ("/share/prog/defaults.rc", "$ENV{HOME}/.someprogrc") { unless ($return = do $file) { warn "couldn't parse $file: $@" if $@; warn "couldn't do $file: $!" unless defined $return; warn "couldn't run $file" unless $return; } }
Эта функция вызывает немедленный дамп ядра. См. также ключ командной строки -u в perlrun , который делает то же самое. В первую очередь это делается для того, чтобы вы могли использовать программу undump (не прилагается) для преобразования дампа ядра в исполняемый двоичный файл после инициализации всех ваших переменных в начале программы. Когда новый двоичный файл будет выполнен, он начнется с выполнения goto LABEL (со всеми ограничениями, которые имеет goto ). Думайте об этом как о переходе с промежуточным дампом ядра и реинкарнацией. Если LABEL не указан, перезапускает программу сначала. Свалка dump EXPR форма, доступная, начиная с Perl 5.18.0, позволяет вычислять имя во время выполнения, в остальном она идентична dump LABEL .
ВНИМАНИЕ ! Любые файлы, открытые во время дампа, будутnotбыть уже открытым,когда программа реинкарнируется,с возможной последующей путаницей Perl.
Эта функция сейчас в значительной степени устарела, в основном потому, что очень сложно преобразовать файл ядра в исполняемый файл. Начиная с Perl 5.30, он должен вызываться как CORE::dump() .
В отличие от большинства именованных операторов, это имеет тот же приоритет, что и присваивание. Кроме того, на него не распространяется правило «выглядит как функция», поэтому dump ("foo")."bar" приведет к тому, что «bar» будет частью аргумента команды dump .
Проблемы с переносимостью: «дамп» в perlport .
При вызове хэша в контексте списка возвращает 2-элементный список,состоящий из ключа и значения для следующего элемента хэша.Только в Perl 5.12 и более поздних вернётся также индекс и значение для следующего элемента массива,так что вы можете провести по нему итерацию;старые Perls считают это синтаксической ошибкой.При вызове в скалярном контексте возвращается только ключ (не значение)в хэше или индекс в массиве.
Записи хеша возвращаются в случайном порядке. Фактический случайный порядок зависит от данного хэша; одна и та же последовательность операций над двумя хэшами может привести к различному порядку для каждого хеша. Любая вставка в хэш может изменить порядок, как и любое удаление, за исключением того, что самый последний ключ, возвращаемый каждым each ключами keys может быть удален без изменения порядка. Пока данный хэш не изменен, вы можете полагаться на keys , values и each , чтобы многократно возвращать тот же порядок, что и друг друга. См. «Атаки алгоритмической сложности» в perlsec.для получения подробной информации о том, почему порядок хэширования рандомизирован. Помимо приведенных здесь гарантий, точные детали алгоритма хеширования Perl и порядок обхода хэша могут быть изменены в любом выпуске Perl.
После того, как each вернул все записи из хэша или массива, следующий вызов each возвращает пустой список в контексте списка и undef в скалярном контексте; следующий звонок послеthatодин перезапускает итерацию. Каждый хеш или массив имеет свой собственный внутренний итератор, к которому обращаются each , keys и values . Итератор неявно сбрасывается, когда each достигает конца, как только что описано; его можно явно сбросить, вызвав keys или values в хэше или массиве или сославшись на хеш (но не на массив) в контексте списка. Если вы добавляете или удаляете элементы хэша во время итерации по нему, влияние на итератор не указано; например, записи могут быть пропущены или дублированы, так что не делайте этого. Исключение: всегда безопасно удалить элемент, который был последним возвращен каждым each поэтому следующий код работает правильно:
while (my ($key, $value) = each %hash) { print $key, "n"; delete $hash{$key}; }
Связанные хэши могут отличаться по порядку от хэшей perl.
Итератор, используемый each них, присоединяется к хешу или массиву и используется всеми итерационными операциями, применяемыми к одному и тому же хешу или массиву. Таким образом, все использования each из них в одном хэше или массиве продвигают одно и то же местоположение итератора. Все виды использования each них также подлежат сбросу итератора при любом использовании keys или values в одном и том же хэше или массиве, или при помощи хэша (но не массива), на который ссылаются в контексте списка. Это заставляет each Циклы на основе довольно хрупкие: легко прийти к такому циклу, когда итератор уже частично прошел через объект, или случайно нарушить состояние итератора во время выполнения тела цикла. Достаточно просто явно сбросить итератор перед запуском цикла, но нет способа изолировать состояние итератора, используемое циклом, от состояния итератора, используемого чем-либо еще, что может выполняться в теле цикла. Чтобы избежать этих проблем, используйте цикл foreach , а не while — each .
Это распространяется на использование each в результате анонимного хэша или конструктора массива. Каждый раз создается новый базовый массив или хеш, поэтому каждый из них всегда будет начинать итерацию с нуля, например:
while (my ($key, $value) = each @{ +{ a => 1 } }) { print "$key=$valuen"; }
Это распечатает вашу среду, как программа printenv (1) , но в другом порядке:
while (my ($key,$value) = each %ENV) { print "$key=$valuen"; }
Начиная с Perl 5.14, экспериментальная функция позволяла each использовать скалярное выражение. Этот эксперимент был признан неудачным и был удален с версии Perl 5.24.
Начиная с Perl 5.18 вы можете использовать простой цикл each in while , который будет устанавливать $_ на каждой итерации. Если в качестве условия while / for используется либо выражение each , либо явное присвоение выражения each скаляру , то условие фактически проверяет определенность значения выражения, а не его обычное истинностное значение.
while (each %ENV) { print "$_=$ENV{$_}n"; }
Чтобы избежать путаницы потенциальных пользователей вашего кода,которые работают с более ранними версиями Perl,с загадочными синтаксическими ошибками,поместите такие вещи в верхнюю часть файла,чтобы показать,что ваш код будет работать.onlyна Перлс недавнего винтажа:
use v5.12; use v5.18;
См. также keys , values и sort .
Возвращает 1,если при следующем чтении в FILEHANDLE будет возвращен конец файлаorесли FILEHANDLE не открыт. FILEHANDLE может быть выражением, значение которого дает реальный дескриптор файла. (Обратите внимание, что эта функция на самом деле считывает символ, а затем ungetc его, поэтому в интерактивном контексте бесполезна.) Не eof(FILEHANDLE) из файла терминала (или вызывайте для него eof (FILEHANDLE) ) после того, как конец файла достиг. Если вы это сделаете, такие типы файлов, как терминалы, могут потерять состояние конца файла.
eof без аргумента использует последний прочитанный файл eof Использование eof() с пустыми скобками отличается. Он относится к псевдофайлу, сформированному из файлов, перечисленных в командной строке, и доступ к которому осуществляется с помощью оператора <> . Поскольку <> не открывается явно, как обычный дескриптор файла, eof() перед использованием <> вызовет проверку @ARGV , чтобы определить, доступен ли ввод. Точно так же eof() после того, как <> вернул конец файла, предполагает, что вы обрабатываете другой список @ARGV , и если вы не установили @ARGV , будет считываться ввод из STDIN .; см. «Операторы ввода-вывода» в perlop .
В цикле while (<>) можно использовать eof или eof(ARGV) для обнаружения конца каждого файла,тогда как eof() обнаружит конец только самого последнего файла. Примеры:
while (<>) { next if /^s* print "$.t$_"; } continue { close ARGV if eof; } while (<>) { if (eof()) { print "--------------n"; } print; last if eof(); }
Практический совет: вам почти никогда не нужно использовать eof в Perl, потому что операторы ввода обычно возвращают undef , когда у них заканчиваются данные или возникает ошибка.
eval во всех его формах используется для выполнения небольшой программы Perl, улавливая любые обнаруженные ошибки, чтобы они не привели к сбою вызывающей программы.
Обычный eval без аргументов — это просто eval EXPR , где подразумевается, что выражение содержится в $_ . Таким образом, есть только две настоящие формы eval ; тот, у которого есть EXPR, часто называют «string eval». В строке eval сначала анализируется значение выражения (которое само определяется в скалярном контексте) и, если ошибок не было, выполняется как блок в лексическом контексте текущей программы Perl. Эта форма обычно используется для задержки синтаксического анализа и последующего выполнения текста EXPR до времени выполнения. Обратите внимание, что значение анализируется каждый раз при выполнении eval .
Другая форма называется «блочный eval». Он менее общий, чем строка eval, но код в БЛОКЕ анализируется только один раз (в то же время, когда анализировался код, окружающий сам eval ), и выполняется в контексте текущей программы Perl. Эта форма обычно используется для более эффективного перехвата исключений, чем первая, а также дает возможность проверки кода в BLOCK во время компиляции. BLOCK анализируется и компилируется только один раз. Поскольку ошибки улавливаются, он часто используется для проверки доступности данной функции.
В обеих формах возвращаемое значение является значением последнего выражения, вычисленного внутри мини-программы; также может использоваться оператор return, как и в случае с подпрограммами. Выражение, предоставляющее возвращаемое значение, оценивается в пустом, скалярном или списковом контексте, в зависимости от контекста самого eval . См. wantarray для получения дополнительной информации о том, как можно определить контекст оценки.
Если есть синтаксическая ошибка или ошибка времени выполнения, или выполняется инструкция die eval возвращает undef в скалярном контексте или пустой список в списковом контексте, а $@ устанавливается в сообщение об ошибке. (До версии 5.16 ошибка вызывала возврат undef в контексте списка для синтаксических ошибок,но не для ошибок времени выполнения.)Если ошибки не было, $@ устанавливается в пустую строку. Оператор потока управления, такой как last или goto , может обойти настройку $@ . Имейте в виду, что использование eval не запрещает Perl печатать предупреждения в STDERR и не запихивает текст предупреждающих сообщений в $@ .. Чтобы сделать что-либо из этого, вы должны использовать средство $SIG{__WARN__} или отключить предупреждения внутри BLOCK или EXPR, no warnings 'all' . См. warn , perlvar и предупреждения .
Обратите внимание, что, поскольку eval перехватывает фатальные ошибки, он полезен для определения того, реализована ли конкретная функция (например, socket или symlink Это также механизм перехвата исключений в Perl, где оператор die используется для возбуждения исключений.
До Perl 5.14 присвоение $@ происходило до восстановления локализованных переменных, а это означает, что для запуска вашего кода в более старых версиях требуется временное значение, если вы хотите замаскировать некоторые, но не все ошибки:
{
my $e;
{
local $@;
eval { test_repugnancy() };
$@ =~ /nefarious/ and $e = $@;
}
die $e if defined $e
}
Для каждой формы существуют свои соображения:
- String eval
-
Поскольку возвращаемое значение EXPR выполняется как блок в лексическом контексте текущей программы Perl,любые внешние лексические переменные видны ему,а любые настройки переменных пакета или определения подпрограмм и форматов остаются после него.
- Под
"unicode_eval"особенность -
Если эта функция включена (что является значением по умолчанию в декларации
use 5.16или выше), Perl предполагает, что EXPR является строкой символов. Таким образом, любоеuse utf8илиno utf8в строке не имеет никакого эффекта. Исходные фильтры также запрещены. ( Однакоunicode_stringsможет появляться внутри строки.)См. также оператор
evalbytes, который корректно работает с исходными фильтрами. - Вне
"unicode_eval"функции -
В этом случае поведение является проблематичным и не так легко описывается.Вот две ошибки,которые не могут быть легко исправлены без нарушения существующих программ:
-
Внутреннее хранилище Perl EXPR влияет на поведение исполняемого кода. Например:
my $v = eval "use utf8; '$expr'";
Если $expr равно
"xc4x80"(U+0100 в UTF-8), то значение, хранящееся в$v, будет зависеть от того, хранит ли Perl $expr «обновленным» (ср. utf8 ) или нет:-
При обновлении
$vбудет"xc4x80"(т. е. использованиеuse utf8не имеет никакого эффекта). -
Если не обновляться,
$vбудет"x{100}".
Это нежелательно, поскольку обновление или отсутствие обновления не должно влиять на поведение строки.
-
-
Исходные фильтры, активированные в
eval, проникают в ту область файлов, которая в настоящее время компилируется. Чтобы привести пример с модулем CPAN Semi :: Semicolons :BEGIN { eval "use Semi::Semicolons; # not filtered" }evalbytesисправляет это, чтобы работать так, как можно было бы ожидать:use feature "evalbytes"; BEGIN { evalbytes "use Semi::Semicolons; # filtered" }
-
Проблемы могут возникнуть, если строка расширяет скаляр, содержащий число с плавающей запятой. Этот скаляр может расширяться до букв, таких как
"NaN"или"Infinity"; или, в рамкахuse locale, символ десятичной точки может быть чем-то другим, кроме точки (например, запятой). Ни один из них, вероятно, не будет проанализирован, как вы, вероятно, ожидали.Вы должны особенно тщательно запоминать,что и когда просматривается:
eval $x; eval "$x"; eval '$x'; eval { $x }; eval "$$x++"; $$x++;
Случаи 1 и 2 выше ведут себя одинаково: они запускают код, содержащийся в переменной $ x. (Хотя в случае 2 есть вводящие в заблуждение двойные кавычки, заставляющие читателя задуматься, что еще может происходить (ничего не происходит).) Случаи 3 и 4 также ведут себя одинаково: они запускают код
'$x', который ничего не делает, кроме как возвращает значение из $ x. (Случай 4 предпочтителен по чисто визуальным причинам, но он также имеет то преимущество, что компилируется во время компиляции, а не во время выполнения.) Случай 5 — это место, где обычно выwouldлюбят использовать двойные кавычки,за исключением того,что в данной конкретной ситуации можно просто использовать символические ссылки,как в случае с 6.eval ''выполняется в подпрограмме , определенной вDBпакета не видит обычный окружающий лексическую область, а объем первого не Д.Б. кусок кода , который назвал его. Обычно вам не нужно беспокоиться об этом, если вы не пишете отладчик Perl.Заключительная точка с запятой,если она есть,может быть опущена в значении EXPR.
- Под
- Block eval
-
Если код, который нужно выполнить, не меняется, вы можете использовать форму eval-BLOCK для перехвата ошибок времени выполнения, не подвергаясь каждый раз повторной компиляции. Ошибка, если таковая имеется, по-прежнему возвращается в
$@. Примеры:eval { $answer = $a / $b; }; warn $@ if $@; eval '$answer = $a / $b'; warn $@ if $@; eval { $answer = }; eval '$answer =';
Если вы хотите перехватывать ошибки при загрузке модуля XS, некоторые проблемы с бинарным интерфейсом (такие как перекос версии Perl) могут быть фатальными даже с
eval, если не установлена$ENV{PERL_DL_NONLAZY}См. perlrun .Использование формы
eval {}в качестве ловушки исключения в библиотеках имеет некоторые проблемы. Из-за текущего, возможно, неработающего состояния хуков__DIE__, вы можете не запускать какие-__DIE__хуки __DIE__, которые мог быть установлен пользовательским кодом. Для этой цели можно использоватьlocal $SIG{__DIE__}, как показано в этом примере:eval { local $SIG{'__DIE__'}; $answer = $a / $b; }; warn $@ if $@;
Это особенно важно, учитывая, что хуки
__DIE__могут снова вызыватьdie, что приводит к изменению их сообщений об ошибках:{ local $SIG{'__DIE__'} = sub { (my $x = $_[0]) =~ s/foo/bar/g; die $x }; eval { die "foo lives here" }; print $@ if $@; }Так как это способствует действиям на расстоянии,это антиинтуитивное поведение может быть исправлено в будущем релизе.
eval BLOCKделаетnotсчитается циклом, поэтому операторы управления цикломnext,lastилиredoне могут использоваться для выхода из блока или его перезапуска.Заключительная точка с запятой,если таковая имеется,может быть опущена внутри БЛОКА.
Эта функция похожа на строку eval , за исключением того, что она всегда анализирует свой аргумент (или $_ , если EXPR опущен) как строку байтов. Если строка содержит какие-либо кодовые точки выше 255, то она не может быть строкой байтов, и evalbytes evalbytes с ошибкой, хранящейся в $@ .
use utf8 и no utf8 в строке имеют обычный эффект.
Исходные фильтры,активированные в оцениваемом коде,применяются к самому коду.
evalbytes доступен, начиная с версии Perl 5.16. Чтобы получить к нему доступ, вы должны сказать CORE::evalbytes , но вы можете опустить CORE:: , есливключена функция Это включается автоматически с use v5.16 (или выше) в текущей области.
Функция exec выполняет системную командуи никогда не возвращается; используйте system вместо exec , если вы хотите, чтобы он вернулся. Он терпит неудачу и возвращает false, только если команда не существуетandон выполняется напрямую,а не через командную оболочку вашей системы (см.ниже).
Поскольку использование exec вместо system является распространенной ошибкой , Perl предупреждает вас, если exec вызывается в контексте void и если есть следующий оператор, отличный от die , warn или exit (если предупреждения включены — но вы всегда делаете это). это так?). если тыreallyхотите следовать за exec каким-либо другим оператором, вы можете использовать один из этих стилей, чтобы избежать предупреждения:
exec ('foo') or print STDERR "couldn't exec foo: $!"; { exec ('foo') }; print STDERR "couldn't exec foo: $!";
Если в LIST более одного аргумента, это вызывает execvp (3) с аргументами из LIST. Если в LIST есть только один элемент, аргумент проверяется на наличие метасимволов оболочки, и если они есть, весь аргумент передается в командную оболочку системы для анализа (это /bin/sh -c на платформах Unix, но варьируется на других платформах). Если в аргументе нет метасимволов оболочки, он разбивается на слова и передается непосредственно в execvp , что более эффективно. Примеры:
exec '/bin/echo', 'Your arguments are: ', @ARGV; exec "sort $outfile | uniq";
Если вы действительно не хотите выполнять первый аргумент, но хотите солгать программе, которую вы выполняете, о ее собственном имени, вы можете указать программу, которую вы действительно хотите запустить, как «косвенный объект» (без запятой) в перед СПИСОК, как в exec PROGRAM LIST . (Это всегда заставляет интерпретировать LIST как многозначный список, даже если в списке есть только один скаляр.) Пример:
my $shell = '/bin/csh'; exec $shell '-sh';
или,более конкретно,
exec {'/bin/csh'} '-sh';
Когда аргументы выполняются через системную оболочку, результаты зависят от ее особенностей и возможностей. Подробнее см. «STRING» в perlop .
Использование косвенного объекта с exec или system также более безопасно. Это использование (которое также отлично работает с system ) заставляет интерпретировать аргументы как многозначный список, даже если в списке был только один аргумент. Таким образом, вы защищены от расширения оболочки подстановочными знаками или разделения слов пробелами в них.
my @args = ( "echo surprise" ); exec @args; exec { $args[0] } @args;
Первая версия,без косвенного объекта,запустилаechoпрограмма, передавая ей "surprise" аргумент. Вторая версия — нет; он пытался запустить программу с именем«echo surprise», не нашел и поставил $? на ненулевое значение, указывающее на сбой.
В Windows только синтаксис косвенного объекта exec PROGRAM LIST надежно избегает использования оболочки; exec LIST , даже с более чем одним элементом, вернется к оболочке, если первая порождение не удастся.
Perl пытается очистить все файлы, открытые для вывода до выполнения exec, но это может не поддерживаться на некоторых платформах (см. Perlport ). На всякий случай вам может потребоваться установить $| ( $AUTOFLUSH на английском языке ) или вызовите метод autoflush IO::Handle для любых открытых дескрипторов, чтобы избежать потери вывода.
Обратите внимание, что exec не будет вызывать ваши блоки END и не будет вызывать методы DESTROY для ваших объектов.
Проблемы с переносимостью: «exec» в perlport .
Получив выражение,которое указывает элемент хэша,возвращает true,если указанный элемент в хэше когда-либо был инициализирован,даже если соответствующее значение не определено.
print "Existsn" if exists $hash{$key}; print "Definedn" if defined $hash{$key}; print "Truen" if $hash{$key};
exists также может вызываться для элементов массива, но его поведение гораздо менее очевидно и сильно связано с использованием delete для массивов.
ПРЕДУПРЕЖДЕНИЕ. Вызов exists значений массива настоятельно не рекомендуется. Идея удаления или проверки существования элементов массива Perl концептуально нелогична и может привести к неожиданному поведению.
print "Existsn" if exists $array[$index]; print "Definedn" if defined $array[$index]; print "Truen" if $array[$index];
Хэш или элемент массива может быть истинным только в том случае,если он определен и определен только в том случае,если он существует,но обратное не обязательно совпадает с истинным.
Для данного выражения, задающего имя подпрограммы, возвращает истину, если указанная подпрограмма когда-либо была объявлена, даже если она не определена. Упоминание имени подпрограммы для существует или определено не считается объявлением этого имени. Обратите внимание, что подпрограмма, которая не существует, по-прежнему может быть вызываемой: ее пакет может иметь метод AUTOLOAD , который заставляет его возникать при первом вызове; см. perlsub .
print "Existsn" if exists &subroutine; print "Definedn" if defined &subroutine;
Обратите внимание,что EXPR может быть произвольно сложным,если конечной операцией является поиск хэша или массива ключей или имя подпрограмм:
if (exists $ref->{A}->{B}->{$key}) { } if (exists $hash{A}{B}{$key}) { } if (exists $ref->{A}->{B}->[$ix]) { } if (exists $hash{A}{B}[$ix]) { } if (exists &{$ref->{A}{B}{$key}}) { }
Хотя самый глубоко вложенный массив или хэш-элемент не появится только потому, что его существование было проверено, любые промежуточные элементы появятся. Таким образом, $ref->{"A"} и $ref->{"A"}->{"B"} появятся в результате проверки существования элемента $key выше. Это происходит везде, где используется оператор стрелки, в том числе даже здесь:
undef $ref; if (exists $ref->{"Some key"}) { } print $ref;
Использование вызова подпрограммы, а не имени подпрограммы, в качестве аргумента существования exists ошибкой.
exists ⊂ exists &sub();
Оценивает EXPR и немедленно выходит с этим значением.Пример:
my $ans = <STDIN>; exit 0 if $ans =~ /^[Xx]/;
См. также die . Если EXPR опущен, завершается со статусом 0 . Единственными общепризнанными значениями EXPR являются 0 для успеха и 1 для ошибки; другие значения подлежат интерпретации в зависимости от среды, в которой работает программа Perl. Например, выход 69 (EX_UNAVAILABLE) изsendmailфильтр incoming-mail заставит отправителя вернуть недоставленный элемент,но это не везде так.
Не используйте exit для прерывания подпрограммы, если есть шанс, что кто-то захочет перехватить возникшую ошибку. Вместо этого используйте die , который может быть пойман eval .
Функция exit не всегда завершается немедленно. Сначала он вызывает любые определенные подпрограммы END , но сами эти подпрограммы END не могут прерывать выход. Точно так же любые деструкторы объектов, которые необходимо вызвать, вызываются перед реальным выходом. END могут изменить статус выхода, изменив $? . Если это проблема, вы можете вызвать POSIX::_exit($status) , чтобы избежать обработки END и деструктора. Подробности смотрите в perlmod .
Проблемы с переносимостью: «выход» в perlport .
Returnse(основание натурального логарифма) в степени EXPR. Если EXPR опущен, дает exp($_) .
Возвращает версию EXPR в развернутом виде. Это внутренняя функция, реализующая экранирование F в строках, заключенных в двойные кавычки.
Casefolding-это процесс сопоставления строк с формой,в которой различия в регистре стираются;сравнение двух строк в их casefolded форме фактически является способом спросить,равны ли две строки,независимо от случая.
Грубо говоря,если ты когда-нибудь обнаружишь,что пишешь это…
lc($this) eq lc($that) uc($this) eq uc($that) $this =~ /^Q$thatEz/i
Теперь вы можете писать
fc($this) eq fc($that)
И получить правильные результаты.
Perl реализует только полную форму casefolding, но вы можете получить доступ к простой сгибов с помощью « casefold () » в Unicode :: UCD и « prop_invmap () » в Unicode :: UCD . Для получения дополнительной информации о сворачивании регистра см. Стандарт Unicode, в частности разделы 3.13 Default Case Operations с регистром по умолчанию , 4.2 Case-Normative Case Mappings и 5.18 Отображение регистра , доступные на https://www.unicode.org/versions/latest/ , а также Таблицы случаев доступны по адресу https://www.unicode.org/charts/case/ .
Если EXPR опущен, используется $_ .
Эта функция ведет себя одинаково с различными прагмами, такими как "use feature 'unicode_strings" , как это делает lc , за единственным исключением fc изЛАТИНСКАЯ ЗАГЛАВНАЯ БУКВА ОСТРАЯ S(U+1E9E) в рамках use locale . Регистр этого символа обычно должен быть "ss" , но, как объяснено в разделе lc , изменение регистра, выходящее за границу 255/256, проблематично в локалях и, следовательно, запрещено. Поэтому эта функция в локали вместо этого возвращает строку "x{17F}x{17F}" , которая являетсяЛАТИНСКАЯ СТРОЧНАЯ БУКВА ДЛИННАЯ S. Поскольку сам этот символ сворачивается в "s" , строка из двух из них вместе должна быть эквивалентна одному U + 1E9E при свертывании.
Хотя стандарт Unicode определяет две дополнительные формы сворачивания регистра, одну для тюркских языков и одну, которая никогда не отображает один символ в несколько символов, ядро Perl не обеспечивает их. Однако для реализации может использоваться модуль Unicode::Casing CPAN .
fc доступен, только есливключена функция CORE:: . Функция "fc" включается автоматически с use v5.16 или выше) в текущей области.
Реализует функцию fcntl (2) . Вам, вероятно, придется сказать
use Fcntl;
сначала получить правильные определения констант. Обработка аргументов и возвращаемое значение работают так же, как ioctl ниже. Например:
use Fcntl; my $flags = fcntl($filehandle, F_GETFL, 0) or die "Can't fcntl F_GETFL: $!";
Вам не нужно проверять наличие defined при возврате из fcntl . Как и ioctl , он отображает 0 , возвращаемый системным вызовом, в "0 but true" в Perl. Эта строка истинна в логическом контексте и 0 в числовом контексте. Он также освобожден от обычного Argument "..." isn't numeric предупреждением о неправильном числовом преобразовании.
Обратите внимание, что fcntl вызывает исключение, если используется на машине, которая не реализует fcntl (2) . См. Модуль Fcntl или справочную страницу fcntl (2), чтобы узнать, какие функции доступны в вашей системе.
Вот пример настройки дескриптора файла с именем $REMOTE на неблокирующий режим на системном уровне. Вам придется вести переговоры $| хотя сам по себе.
use Fcntl qw(F_GETFL F_SETFL O_NONBLOCK); my $flags = fcntl($REMOTE, F_GETFL, 0) or die "Can't get flags for the socket: $!n"; fcntl($REMOTE, F_SETFL, $flags | O_NONBLOCK) or die "Can't set flags for the socket: $!n";
Проблемы с переносимостью: «fcntl» в perlport .
Специальный токен, который возвращает имя файла, в котором он встречается. Его можно изменить с помощью механизма, описанного в разделе «Обычные старые комментарии (не!)» В perlsyn .
Возвращает дескриптор файла для дескриптора файла или дескриптора каталога или undefined, если дескриптор файла не открыт. Если на уровне ОС нет реального дескриптора файла, как это может случиться с дескрипторами файлов, подключенными к объектам памяти через open со ссылкой для третьего аргумента, возвращается -1.
Это в основном полезно для создания растровых изображений для операций select и низкоуровневых операций обработки tty POSIX. Если FILEHANDLE является выражением, значение принимается как косвенный дескриптор файла, обычно это его имя.
Вы можете использовать это,чтобы узнать,относятся ли два дескриптора к одному и тому же базовому дескриптору:
if (fileno($this) != -1 && fileno($this) == fileno($that)) { print "$this and $that are dupsn"; } elsif (fileno($this) != -1 && fileno($that) != -1) { print "$this and $that have different " . "underlying file descriptorsn"; } else { print "At least one of $this and $that does " . "not have a real file descriptorn"; }
Поведение fileno в дескрипторе каталога зависит от операционной системы. В системе с dirfd(3) или аналогичной, fileno в дескрипторе каталога возвращает базовый файловый дескриптор, связанный с дескриптором; в системах без такой поддержки он возвращает неопределенное значение и устанавливает $! (ошибка).
Вызывает flock (2) или его эмуляцию на FILEHANDLE. Возвращает истину в случае успеха и ложь в случае неудачи. Выдает фатальную ошибку, если используется на машине, которая не реализует блокировку flock (2) , fcntl (2) или lockf (3) . flock — это переносимый интерфейс Perl для блокировки файлов, хотя он блокирует только файлы целиком, а не записи.
Две потенциально неочевидные, но традиционные семантики flock заключаются в том, что он бесконечно ожидает, пока блокировка не будет предоставлена, и что его блокировки являются просто рекомендательными . Такие дискреционные блокировки более гибкие, но дают меньше гарантий. Это означает, что программы, которые также не используют flock , могут изменять файлы, заблокированные с помощью flock . См. Perlport, документацию по вашему порту и локальные страницы руководства по вашей системе. Если вы пишете переносимые программы, лучше всего предполагать традиционное поведение. (Но если вы этого не сделаете, вы, как всегда, должны чувствовать себя совершенно свободно, чтобы писать для особенностей вашей собственной системы (иногда называемых «функциями»). Рабское следование соображениям переносимости не должно мешать вам выполнять свою работу.)
OPERATION — это один из LOCK_SH, LOCK_EX или LOCK_UN, возможно в сочетании с LOCK_NB. Эти константы традиционно имеют значения 1, 2, 8 и 4, но вы можете использовать символические имена, если вы импортируете их из модуля Fcntl либо по отдельности, либо в виде группы с помощью тега :flock . LOCK_SH запрашивает разделяемую блокировку, LOCK_EX запрашивает исключительную блокировку, а LOCK_UN освобождает ранее запрошенную блокировку. Если LOCK_NB побитовое ИЛИ с LOCK_SH или LOCK_EX, тогда flock возвращается немедленно, а не блокирует ожидание блокировки; проверьте статус возврата, чтобы узнать, получили ли вы его.
Чтобы избежать возможности неправильной координации,Perl теперь промывает FILEHANDLE перед блокировкой или разблокировкой.
Обратите внимание, что эмуляция, построенная с помощью lockf (3) , не обеспечивает разделяемых блокировок и требует, чтобы FILEHANDLE был открыт с намерением записи. Это семантика, которую реализует lockf (3) . Однако большинство, если не все системы, реализуют lockf (3) с точки зрения блокировки fcntl (2) , поэтому разная семантика не должна укусить слишком много людей.
Обратите внимание, что эмуляция fcntl (2) для flock (3) требует, чтобы FILEHANDLE был открыт с намерением чтения для использования LOCK_SH, и требует, чтобы он был открыт с намерением записи для использования LOCK_EX.
Также обратите внимание, что некоторые версии flock не могут блокировать вещи по сети; для этого вам нужно будет использовать более специфичный для системы fcntl . Если хотите, вы можете заставить Perl игнорировать системную функцию flock (2) и, таким образом, обеспечить собственную эмуляцию на основе fcntl (2) , передав параметр -Ud_flock параметруConfigureпрограмма,когда вы настраиваете и создаете новый Perl.
Вот почтовый аппендикс для систем BSD.
use Fcntl qw(:flock SEEK_END); sub lock { my ($fh) = @_; flock($fh, LOCK_EX) or die "Cannot lock mailbox - $!n"; seek($fh, 0, SEEK_END) or die "Cannot seek - $!n"; } sub unlock { my ($fh) = @_; flock($fh, LOCK_UN) or die "Cannot unlock mailbox - $!n"; } open(my $mbox, ">>", "/usr/spool/mail/$ENV{'USER'}") or die "Can't open mailbox: $!"; lock($mbox); print $mbox $msg,"nn"; unlock($mbox);
В системах, которые поддерживают настоящий flock(2) , блокировки наследуются при вызовах fork , тогда как те, которые должны прибегать к более капризной функции fcntl(2) , теряют свои блокировки, что значительно усложняет написание серверов.
См. Также DB_File для других примеров flock .
Проблемы с переносимостью: «flock» в perlport .
Выполняет системный вызов fork(2) для создания нового процесса, выполняющего ту же программу в той же точке. Он возвращает дочерний pid родительскому процессу, 0 дочернему процессу или undef , если вилка не удалась. Файловые дескрипторы (а иногда и блокировки этих дескрипторов) являются общими, а все остальное копируется. В большинстве систем, поддерживающих fork(2) , большое внимание было уделено тому, чтобы сделать его чрезвычайно эффективным (например, с использованием технологии копирования при записи на страницах данных), что сделало его доминирующей парадигмой многозадачности за последние несколько десятилетий.
Perl пытается очистить все файлы, открытые для вывода, перед тем, как разветвлять дочерний процесс, но это может не поддерживаться на некоторых платформах (см. Perlport ). На всякий случай вам может потребоваться установить $| ( $AUTOFLUSH на английском языке ) или вызовите метод autoflush IO::Handle для любых открытых дескрипторов, чтобы избежать дублирования вывода.
Если вы fork , даже не дождавшись своих детей, вы накопите зомби. В некоторых системах этого можно избежать, установив для $SIG{CHLD} значение "IGNORE" . См. также perlipc для получения дополнительных примеров разветвления и пожинания умирающих детей.
Обратите внимание,что если ваш дочерний процесс наследует системные файловые дескрипторы,такие как STDIN и STDOUT,которые на самом деле подключены через трубу или сокет,даже если вы выйдете,то удаленный сервер (например,CGI скрипт или фоновая работа,запущенная из удаленной оболочки)не подумает,что вы закончили.Вы должны открыть их заново,чтобы/dev/nullесли это какая-то проблема.
На некоторых платформах, таких как Windows, где системный вызов fork(2) недоступен, Perl может быть построен для эмуляции fork в интерпретаторе Perl. Эмуляция разработана на уровне программы Perl, чтобы быть максимально совместимой с форком «Unix»(2) . Однако у него есть ограничения, которые необходимо учитывать в коде, предназначенном для переноса. См. Perlfork для более подробной информации.
Проблемы с переносимостью: «форк» в perlport .
Объявите формат изображения для использования функцией write . Например:
format Something = Test: @<<<<<<<< @||||| @>>>>> $str, $%, '$' . int($num) . $str = "widget"; $num = $cost/$quantity; $~ = 'Something'; write;
См. Perlform для многих деталей и примеров.
Это внутренняя функция, используемая format s, хотя вы также можете вызвать ее. Он форматирует (см. perlform ) список значений в соответствии с содержимым PICTURE, помещая вывод в выходной накопитель формата, $^A (или $ACCUMULATOR на английском языке ). В конце концов, когда write завершена, содержимое $^A записывается в некоторый дескриптор файла. Вы также можете прочитать $^A , а затем установить $^A обратно в "" . Обратите внимание, что формат обычно делает одну formline на строку формы, но formline самой функции все равно, сколько новых строк встроено в ИЗОБРАЖЕНИЕ. Это означает, что токены ~ и ~~ рассматривают всю ИЗОБРАЖЕНИЕ как одну строку. Поэтому вам может потребоваться использовать несколько строк форм для реализации единого формата записи, как и в компиляторе format .
Будьте осторожны, если вы заключите изображение в двойные кавычки, потому что символ @ может означать начало имени массива. formline всегда возвращает true. См. Другие примеры в perlform .
Если вы пытаетесь использовать это вместо write для захвата вывода, вам может быть проще открыть дескриптор файла для скаляра ( open my $fh, ">", $output ) и записать его вместо этого.
Возвращает следующий символ из входного файла, прикрепленного к FILEHANDLE, или неопределенное значение в конце файла, или если произошла ошибка (в последнем случае установлен $! ). Если FILEHANDLE опущен, считывается из STDIN. Это не особенно эффективно. Однако он не может использоваться сам по себе для выборки отдельных символов, не дожидаясь, пока пользователь нажмет Enter. Для этого попробуйте что-нибудь вроде:
if ($BSD_STYLE) { system "stty cbreak </dev/tty >/dev/tty 2>&1"; } else { system "stty", '-icanon', 'eol', "01"; } my $key = getc(STDIN); if ($BSD_STYLE) { system "stty -cbreak </dev/tty >/dev/tty 2>&1"; } else { system 'stty', 'icanon', 'eol', '^@'; } print "n";
Определение того, следует ли устанавливать $BSD_STYLE оставлено читателю в качестве упражнения.
Функция POSIX::getattr может сделать это более переносимым в системах, требующих соответствия POSIX. См. также модуль Term::ReadKey на CPAN.
Это реализует одноименную библиотечную функцию C,которая на большинстве систем возвращает текущий логин из/etc/utmp, если есть. Если он возвращает пустую строку, используйте getpwuid .
my $login = getlogin || getpwuid($<) || "Kilroy";
Не рассматривайте getlogin для аутентификации: он не так безопасен, как getpwuid .
Проблемы с переносимостью: «getlogin» в perlport .
Возвращает упакованный адрес sockaddr другого конца соединения SOCKET.
use Socket; my $hersockaddr = getpeername($sock); my ($port, $iaddr) = sockaddr_in($hersockaddr); my $herhostname = gethostbyaddr($iaddr, AF_INET); my $herstraddr = inet_ntoa($iaddr);
Возвращает текущую группу процессов для указанного PID. Используйте PID 0 , чтобы получить текущую группу процессов для текущего процесса. Вызовет исключение, если используется на машине, которая не реализует getpgrp(2) . Если PID не указан, возвращает группу процессов текущего процесса. Обратите внимание, что POSIX-версия getpgrp не принимает аргумент PID, поэтому только PID==0 действительно переносим.
Проблемы с переносимостью: «getpgrp» в perlport .
Возвращает идентификатор процесса родительского процесса.
Примечание для пользователей Linux: Между версиями v5.8.1 и v5.16.0 Perl работал над семантикой потоков, отличных от POSIX, в меньшинстве систем Linux (и систем Debian GNU / kFreeBSD), которые использовали LinuxThreads, с тех пор эта эмуляция была удалена. Подробности смотрите в документации к $$ .
Проблемы с переносимостью: «getppid» в perlport .
Возвращает текущий приоритет процесса, группы процессов или пользователя. (См. Getpriority (2) .) Вызовет фатальное исключение, если используется на машине, которая не реализует getpriority (2) .
WHICH может быть любым из PRIO_PROCESS , PRIO_PGRP или PRIO_USER , импортированным из «RESOURCE CONSTANTS» в POSIX .
Проблемы с переносимостью: «getpriority» в perlport .
Эти процедуры такие же,как и их аналоги в библиотеке системы C.В контексте списка,возвращаемые значения из различных подпрограмм get выглядят следующим образом:
my ( $name, $passwd, $gid, $members ) = getgr* my ( $name, $aliases, $addrtype, $net ) = getnet* my ( $name, $aliases, $port, $proto ) = getserv* my ( $name, $aliases, $proto ) = getproto* my ( $name, $aliases, $addrtype, $length, @addrs ) = gethost* my ( $name, $passwd, $uid, $gid, $quota, $comment, $gcos, $dir, $shell, $expire ) = getpw*
(Если запись не существует, возвращаемое значение — единственное бессмысленное истинное значение.)
Точное значение поля $ gcos различается, но обычно оно содержит настоящее имя пользователя (в отличие от имени для входа) и другую информацию, относящуюся к пользователю. Однако помните, что во многих системах пользователи могут изменять эту информацию, и поэтому ей нельзя доверять, и, следовательно, $ gcos испорчен (см. Perlsec ). $ Passwd и $ shell, зашифрованный пароль пользователя и оболочка входа в систему также испорчены по той же причине.
В скалярном контексте вы получаете имя,если только функция не была поиском по имени,в этом случае вы получаете другую вещь,какой бы она ни была.(Если запись не существует,вы получаете неопределенное значение.)Например:
my $uid = getpwnam($name); my $name = getpwuid($num); my $name = getpwent(); my $gid = getgrnam($name); my $name = getgrgid($num); my $name = getgrent();
Ingetpw*()поля $ quota, $ comment и $ expire особенные, поскольку они не поддерживаются во многих системах. Если квота $ не поддерживается, это пустой скаляр. Если он поддерживается, он обычно кодирует дисковую квоту. Если поле $ comment не поддерживается, это пустой скаляр. Если он поддерживается, он обычно кодирует некоторый административный комментарий о пользователе. В некоторых системах поле $ quota может быть $ change или $ age — полями, которые имеют отношение к устареванию пароля. В некоторых системах поле $ comment может быть $ class. Поле $ expire, если оно присутствует, кодирует срок действия учетной записи или пароль. Чтобы узнать о доступности и точном значении этих полей в вашей системе, обратитесь к getpwnam (3) и к вашей системеpwd.hфайл. Вы также можете узнать из Perl, что означают ваши поля $ quota и $ comment и есть ли у вас поле $ expire, используя модуль Config и значения d_pwquota , d_pwage , d_pwchange , d_pwcomment и d_pwexpire . Файлы теневых паролей поддерживаются только в том случае, если ваш поставщик реализовал их интуитивно понятным способом, при котором вызов обычных подпрограмм библиотеки C получает теневые версии, если вы работаете с привилегиями или если существуют функции shadow (3), как в System V ( это включает Solaris и Linux). Те системы, которые реализуют собственный теневой пароль, вряд ли будут поддерживаться.
Стоимость членов,возвращаемаяgetgr*()это разделенный пробелами список имен участников группы.
For thegethost*()функции, если переменная h_errno поддерживается в C, она будет возвращена вам через $? если вызов функции не удался. Значение @addrs , возвращаемое успешным вызовом, представляет собой список необработанных адресов, возвращаемых соответствующим вызовом библиотеки. В Интернет-домене каждый адрес имеет длину четыре байта; вы можете распаковать его, сказав что-нибудь вроде:
my ($w,$x,$y,$z) = unpack('W4',$addr[0]);
Библиотека Socket немного облегчает эту задачу:
use Socket; my $iaddr = inet_aton("127.1"); my $name = gethostbyaddr($iaddr, AF_INET); my $straddr = inet_ntoa($iaddr);
Напротив,чтобы разрешить имя хоста в IP-адрес,вы можете записать это:
use Socket; my $packed_ip = gethostbyname("www.perl.org"); my $ip_address; if (defined $packed_ip) { $ip_address = inet_ntoa($packed_ip); }
Убедитесь, что gethostbyname вызывается в контексте SCALAR и что возвращаемое значение проверяется на определенность.
Функция getprotobynumber , хотя и принимает только один аргумент, имеет приоритет над оператором списка, так что будьте осторожны:
getprotobynumber $number eq 'icmp' getprotobynumber($number eq 'icmp') getprotobynumber($number) eq 'icmp'
Если вы устали вспоминать, какой элемент списка возврата содержит какое возвращаемое значение, интерфейсы по имени предоставляются в стандартных модулях: File::stat , Net::hostent , Net::netent , Net::protoent , Net::servent , Time::gmtime , Time::localtime и User::grent . Они переопределяют обычные встроенные функции, предоставляя версии, возвращающие объекты с соответствующими именами для каждого поля. Например:
use File::stat; use User::pwent; my $is_his = (stat($filename)->uid == pwent($whoever)->uid);
Хотя кажется, что это одни и те же вызовы методов (uid), это не так, потому что объект File::stat отличается от объекта User::pwent .
Многие из этих функций небезопасны в многопоточной среде, где их может использовать более одного потока. В частности, такие функции, как getpwent() итерацию для каждого процесса, а не для каждого потока, поэтому, если два потока выполняют итерацию одновременно, ни один из них не получит все записи.
В некоторых системах есть поточно-ориентированные версии некоторых функций, например getpwnam_r() вместо getpwnam() . Там Perl автоматически и незаметно заменяет поточно-ориентированную версию без предварительного уведомления. Это означает, что код, который безопасно выполняется в одних системах, может дать сбой в других, в которых отсутствуют поточно-ориентированные версии.
Проблемы с переносимостью: «getpwnam» в perlport на «endservent» в perlport .
Возвращает упакованный адрес sockaddr этого конца соединения SOCKET,в случае,если вы не знаете этот адрес,потому что у вас есть несколько различных IP-адресов,которые могли войти в соединение.
use Socket; my $mysockaddr = getsockname($sock); my ($port, $myaddr) = sockaddr_in($mysockaddr); printf "Connect to %s [%s]n", scalar gethostbyaddr($myaddr, AF_INET), inet_ntoa($myaddr);
Запрашивает параметр с именем OPTNAME, связанный с SOCKET на данном УРОВНЕ. Параметры могут существовать на нескольких уровнях протокола в зависимости от типа сокета, но по крайней мере будет существовать самый верхний уровень сокета SOL_SOCKET (определенный в модуле Socket ).Для запроса опций на другом уровне должен быть предоставлен номер соответствующего протокола, управляющего опцией. Например, чтобы указать, что опция должна интерпретироваться протоколом TCP, LEVEL должен быть установлен на номер протокола TCP, который вы можете получить с помощью getprotobyname .
Функция возвращает упакованную строку, представляющую запрошенную опцию сокета, или undef в случае ошибки, с указанием причины ошибки в $! . То, что находится в упакованной строке, зависит от LEVEL и OPTNAME; обратитесь к getockopt(2) за подробностями. Обычным случаем является то, что параметр является целым числом, и в этом случае результатом является упакованное целое число, которое вы можете декодировать, используя unpack с форматом i (или I ).
Вот пример для проверки,включен ли алгоритм Нэгла в сокет:
use Socket qw(:all); defined(my $tcp = getprotobyname("tcp")) or die "Could not determine the protocol number for tcp"; my $packed = getsockopt($socket, $tcp, TCP_NODELAY) or die "getsockopt TCP_NODELAY: $!"; my $nodelay = unpack("I", $packed); print "Nagle's algorithm is turned ", $nodelay ? "offn" : "onn";
Проблемы с переносимостью: «getsockopt» в perlport .
В контексте списка возвращает (возможно, пустой) список расширений имен файлов для значения EXPR, как это сделала бы оболочка Unix Bash. В скалярном контексте glob перебирает такие расширения имени файла, возвращая undef , когда список исчерпан. Если EXPR опущен, используется $_ .
my @txt_files = glob("*.txt"); my @perl_files = glob("*.pl *.pm"); while (my $file = glob("*.mp3")) { }
Glob также поддерживает альтернативный синтаксис с использованием < > в качестве разделителей. Хотя этот синтаксис поддерживается, вместо него рекомендуется использовать glob , так как он более удобен для чтения и поиска.
my @txt_files = <"*.txt">;
Если вам нужно подстановку файлов без учета регистра, это можно сделать с помощью параметра :nocase модуля bsd_glob .
use File::Glob qw(:globally :nocase); my @txt = glob("readme*");
Обратите внимание, что glob разбивает свои аргументы на пробелы и рассматривает каждый сегмент как отдельный шаблон. Таким образом, glob("*.c *.h") соответствует всем файлам с.cor.hрасширение. Выражение glob(".* *") Соответствует всем файлам в текущем рабочем каталоге. Если вы хотите подделать имена файлов, которые могут содержать пробелы, вам придется использовать дополнительные кавычки вокруг пустого имени файла, чтобы защитить его. Например, чтобы указать имена файлов, в которых следует e , за которым следует пробел, за которым следует f , используйте одно из следующих значений:
my @spacies = <"*e f*">; my @spacies = glob('"*e f*"'); my @spacies = glob(q("*e f*"));
Если бы тебе нужно было пропустить переменную,ты мог бы это сделать:
my @spacies = glob("'*${var}e f*'"); my @spacies = glob(qq("*${var}e f*"));
Если непустые фигурные скобки являются единственными подстановочными знаками, используемыми в glob , имена файлов не совпадают, но потенциально может быть возвращено много строк. Например, получается девять строк, по одной на каждое сочетание фруктов и цветов:
my @many = glob("{apple,tomato,cherry}={green,yellow,red}");
Этот оператор реализован с использованием стандартного расширения File::Glob . Подробности смотрите в bsd_glob ,включая bsd_glob , который не рассматривает пробелы как разделитель шаблонов.
Если glob выражение используется как условие цикла while или for , оно будет неявно присвоено $_ . Если в качестве условия while / for используется glob выражение или явное присвоение glob выражения скаляру , то условие фактически проверяет определенность значения выражения, а не его регулярное значение истинности.
Детали внутренней реализации:
Это внутренняя функция, реализующая оператор <*.c> , но вы можете использовать ее напрямую. Оператор <*.c> более подробно обсуждается в разделе «Операторы ввода-вывода» в perlop .
Проблемы с переносимостью: «glob» в perlport .
Работает так же, как localtime , но возвращаемые значения локализованы для стандартного часового пояса Гринвича.
Примечание. При вызове в контексте списка $ isdst, последнее значение, возвращаемое gmtime, всегда равно 0 . В GMT нет перехода на летнее время.
Проблемы с переносимостью: «gmtime» в perlport .
Форма goto LABEL находит оператор, помеченный LABEL, и возобновляет выполнение там. Его нельзя использовать для выхода из блока или подпрограммы, переданной sort . Его можно использовать для перехода почти в любое другое место в пределах динамической области видимости, в том числе за пределы подпрограмм, но обычно лучше использовать какую-либо другую конструкцию, например last или die . Автор Perl никогда не чувствовал необходимости использовать эту форму goto (то есть в Perl; C — другое дело). (Разница в том, что C не предлагает именованные циклы в сочетании с управлением циклом. Perl предлагает, и это заменяет большинство структурированных применений goto goto других языках.)
Форма goto EXPR ожидает, что EXPR будет оценивать ссылку на код или имя метки. Если он оценивается как ссылка на код, он будет обрабатываться как goto &NAME , как показано ниже. Это особенно полезно для реализации хвостовой рекурсии через goto __SUB__ .
Если выражение оценивается как имя метки, его область действия будет разрешена динамически. Это позволяет вычислять goto для FORTRAN, но не обязательно рекомендуется, если вы оптимизируете для удобства сопровождения:
goto ("FOO", "BAR", "GLARCH")[$i];
Как показано в этом примере, goto EXPR освобожден от правила «выглядит как функция». Пара скобок, следующая за ним, не (обязательно) ограничивает аргумент. goto("NE")."XT" эквивалентно goto NEXT . Кроме того, в отличие от большинства именованных операторов, это имеет тот же приоритет, что и присваивание.
Использование goto LABEL или goto EXPR для перехода в конструкцию устарело и приведет к предупреждению. Даже в этом случае его нельзя использовать для перехода к какой-либо конструкции, требующей инициализации, такой как подпрограмма, цикл foreach или given блок. В общем, его нельзя использовать для перехода к параметру бинарного оператора или оператора списка, но его можно использовать для перехода к параметруfirstпараметр бинарного оператора. ( «Первый» операнд оператора присваивания = является его правым операндом.) Его также нельзя использовать для перехода в оптимизируемую конструкцию.
Форма goto &NAME сильно отличается от других форм goto . На самом деле, это вообще не goto в обычном смысле, и на нем нет клейма, связанного с другими goto. Вместо этого он выходит из текущей подпрограммы (теряя все изменения, установленные local ) и немедленно вызывает вместо нее названную подпрограмму, используя текущее значение @_ . Это используется подпрограммами AUTOLOAD , которые хотят загрузить другую подпрограмму, а затем сделать вид, что другая подпрограмма была вызвана в первую очередь (за исключением того, что любые изменения @_ goto @_ подпрограмме распространяются на другую подпрограмму) . даже не caller сможет сказать, что эта подпрограмма была вызвана первой.
Имя не обязательно должно быть именем подпрограмм;это может быть скалярная переменная,содержащая ссылку на код,или блок,который вычисляет ссылку на код.
По духу это похоже на grep (1) и его родственников , но не то же самое . В частности, он не ограничивается использованием регулярных выражений.
Вычисляет BLOCK или EXPR для каждого элемента LIST (локально устанавливая $_ для каждого элемента) и возвращает значение списка, состоящее из тех элементов, для которых выражение было оценено как истинное. В скалярном контексте возвращает, сколько раз выражение было истинным.
my @foo = grep(!/^#/, @bar);
or equivalently,
my @foo = grep {!/^#/} @bar;
Обратите внимание, что $_ — это псевдоним значения списка, поэтому его можно использовать для изменения элементов списка. Хотя это полезно и поддерживается, это может привести к странным результатам, если элементы LIST не являются переменными. Точно так же grep возвращает псевдонимы в исходный список, так же как индексная переменная цикла for создает псевдонимы элементов списка. То есть изменение элемента списка, возвращаемого grep (например, в foreach , map или другом grep ), фактически изменяет элемент в исходном списке. Обычно этого следует избегать при написании понятного кода.
См. также map для списка, составленного из результатов BLOCK или EXPR.
Интерпретирует EXPR как шестнадцатеричную строку и возвращает соответствующее числовое значение. Если EXPR опущен, используется $_ .
print hex '0xAf'; print hex 'aF'; $valid_input =~ /A(?:0?[xX])?(?:_?[0-9a-fA-F])*z/
Шестнадцатеричная строка состоит из шестнадцатеричных цифр и необязательного префикса 0x или x . Каждой шестнадцатеричной цифре может предшествовать одно подчеркивание, которое будет игнорироваться. Любой другой символ вызывает предупреждение и заставляет игнорировать остальную часть строки (даже начальные пробелы, в отличие от oct ). Могут быть представлены только целые числа, и целочисленное переполнение вызывает предупреждение.
Чтобы преобразовать строки, которые могут начинаться с любого из 0 , 0x или 0b , см. oct . Чтобы представить что-то в виде шестнадцатеричного кода, загляните в printf , sprintf и unpack .
import нет . Это обычный метод (подпрограмма), определенный (или унаследованный) модулями, которые хотят экспортировать имена в другой модуль. Функция use вызывает метод import для используемого пакета. См. также use , perlmod и Exporter .
Функция индекса ищет одну строку внутри другой, но без поведения, подобного подстановочному знаку, при полном совпадении с образцом регулярного выражения. Он возвращает позицию первого вхождения SUBSTR в STR в POSITION или после него. Если POSITION опущено, поиск начинается с начала строки. POSITION до начала строки или после ее конца обрабатывается, как если бы это было начало или конец, соответственно. ПОЛОЖЕНИЕ и возвращаемое значение основаны на нуле. Если подстрока не найдена, index возвращает -1.
Поиск символов или строк:
index("Perl is great", "P"); index("Perl is great", "g"); index("Perl is great", "great");
Попытка найти то,чего нет:
index("Perl is great", "Z");
Использование смещения для нахожденияsecondoccurrence:
index("Perl is great", "e", 5);
Возвращает целую часть EXPR. Если EXPR опущен, используется $_ . Вы не должны использовать эту функцию для округления: во-первых, потому что она усекает до 0 , и во-вторых, потому что машинное представление чисел с плавающей запятой может иногда давать противоречивые результаты. Например, int(-6.725/0.025) дает -268, а не правильное -269; это потому, что это больше похоже на -268,99999999999994315658. Обычно функции sprintf , printf или POSIX::floor и POSIX::ceil служат вам лучше, чем int .
Реализует функцию ioctl (2) . Вам, вероятно, сначала придется сказать
require "sys/ioctl.ph";
чтобы получить правильные определения функций.Еслиsys/ioctl.phне существует или не имеет правильных определений,которые вам придётся свернуть,основываясь на ваших заголовочных файлах C,таких как<sys/ioctl.h>. (Существует Perl-скрипт h2ph, который поставляется с Perl-комплектом, который может вам в этом помочь, но это нетривиально.) SCALAR будет читаться и / или записываться в зависимости от ФУНКЦИИ; указатель C на строковое значение SCALAR будет передан в качестве третьего аргумента фактического вызова ioctl . (Если SCALAR не имеет строкового значения, но имеет числовое значение, будет передано это значение, а не указатель на строковое значение. Чтобы гарантировать, что это правда, добавьте 0 к скаляру перед его использованием.) pack и unpack функции могут потребоваться для управления значениями структур, используемых ioctl .
Возвращаемое значение ioctl (и fcntl ) выглядит следующим образом:
if OS returns: then Perl returns: -1 undefined value 0 string "0 but true" anything else that number
Таким образом,Perl возвращает правду об успехе и ложь о неудаче,но при этом вы можете легко определить фактическое значение,возвращаемое операционной системой:
my $retval = ioctl(...) || -1; printf "System returned %dn", $retval;
Специальная строка "0 but true" исключается из Argument "..." isn't numeric предупреждением о неправильных числовых преобразованиях.
Проблемы с переносимостью: «ioctl» в perlport .
Соединяет отдельные строки СПИСКА в единую строку с полями,разделенными значением EXPR,и возвращает эту новую строку.Пример:
my $rec = join(':', $login,$passwd,$uid,$gid,$gcos,$home,$shell);
Помните, что в отличие от split , join не принимает шаблон в качестве первого аргумента. Сравните split .
Вызывается в контексте списка,возвращает список,состоящий из всех ключей именованного хэша,или только в Perl 5.12 или более поздней версии,индексов массива.Релизы на Perl до версии 5.12 приведут к синтаксической ошибке,если вы попытаетесь использовать аргумент массива.В скалярном контексте возвращает количество ключей или индексов.
Записи хеша возвращаются в случайном порядке. Фактический случайный порядок зависит от данного хэша; одна и та же последовательность операций над двумя хэшами может привести к различному порядку для каждого хеша. Любая вставка в хэш может изменить порядок, как и любое удаление, за исключением того, что самый последний ключ, возвращаемый каждым each ключами keys может быть удален без изменения порядка. Пока данный хэш не изменен, вы можете полагаться на keys , values и each , чтобы многократно возвращать тот же порядок, что и друг друга. См. «Атаки алгоритмической сложности» в perlsec.для получения подробной информации о том, почему порядок хэширования рандомизирован. Помимо приведенных здесь гарантий, точные детали алгоритма хеширования Perl и порядок обхода хэша могут быть изменены в любом выпуске Perl. Связанные хэши могут вести себя иначе, чем хэши Perl, в отношении изменения порядка вставки и удаления элементов.
В качестве побочного эффекта вызов keys сбрасывает внутренний итератор ХЕША или МАССИВА (см. each ) перед получением ключей. В частности, вызов keys в пустом контексте сбрасывает итератор без дополнительных затрат.
Вот еще один способ печати вашего окружения:
my @keys = keys %ENV; my @values = values %ENV; while (@keys) { print pop(@keys), '=', pop(@values), "n"; }
или как насчет сортировки по клавишам:
foreach my $key (sort(keys %ENV)) { print $key, '=', $ENV{$key}, "n"; }
Возвращаемые значения являются копиями исходных ключей в хеше, поэтому их изменение не повлияет на исходный хэш. Сравните values .
Чтобы отсортировать хэш по значению, вам нужно использовать функцию sort . Вот убывающий числовой вид хэша по его значениям:
foreach my $key (sort { $hash{$b} <=> $hash{$a} } keys %hash) { printf "%4d %sn", $hash{$key}, $key; }
keys , используемые в качестве lvalue, позволяют увеличить количество сегментов хэша, выделенных для данного хэша. Это может дать вам определенную эффективность, если вы знаете, что хэш будет большим. (Это похоже на предварительное расширение массива путем присвоения большего числа массиву $#array.) Если вы скажете
keys %hash = 200;
тогда для %hash будет выделено не менее 200 сегментов — фактически 256 из них, поскольку он округляется до следующей степени двойки. Эти сегменты будут сохранены, даже если вы выполните %hash = () , используйте undef %hash , если вы хотите освободить хранилище, пока %hash все еще находится в области действия. Вы не можете уменьшить количество сегментов, выделенных для хэша, используя keys таким образом (но вам не нужно беспокоиться о том, что вы сделаете это случайно, поскольку попытка не даст никакого эффекта). keys @array в контексте lvalue является синтаксической ошибкой.
Начиная с Perl 5.14, экспериментальная функция позволяла keys принимать скалярное выражение. Этот эксперимент был признан неудачным и был удален с версии Perl 5.24.
Чтобы избежать путаницы потенциальных пользователей вашего кода,которые работают с более ранними версиями Perl,с загадочными синтаксическими ошибками,поместите такие вещи в верхнюю часть файла,чтобы показать,что ваш код будет работать.onlyна Перлс недавнего винтажа:
use v5.12;
См. также each , values и sort .
Отправляет сигнал в список процессов.Возвращает количество аргументов,которые были успешно использованы для сигнала (которое не обязательно совпадает с количеством фактически убитых процессов,например,где была убита группа процессов).
my $cnt = kill 'HUP', $child1, $child2; kill 'KILL', @goners;
СИГНАЛ может быть либо именем сигнала (строка), либо номером сигнала. Имя сигнала может начинаться с префикса SIG , поэтому FOO и SIGFOO относятся к одному и тому же сигналу. Строковая форма SIGNAL рекомендуется для переносимости, поскольку один и тот же сигнал может иметь разные номера в разных операционных системах.
Список имен сигналов, поддерживаемых текущей платформой, можно найти в $Config{sig_name} , который предоставляется модулем Config . Смотрите Config для более подробной информации.
Имя отрицательного сигнала совпадает с номером отрицательного сигнала, убивая группы процессов вместо процессов. Например, kill '-KILL', $pgrp и kill -9, $pgrp отправит SIGKILL всей указанной группе процессов. Это означает, что вы обычно хотите использовать положительные, а не отрицательные сигналы.
Если SIGNAL — это либо число 0, либо строка ZERO (или SIGZERO ), сигнал процессу не отправляется, но kill проверяет, является ли онpossibleчтобы послать ему сигнал (короче говоря, что процесс принадлежит одному и тому же пользователю, или мы являемся суперпользователем). Это полезно для проверки того, что дочерний процесс все еще жив (даже если только в качестве зомби) и не изменил свой UID. Смотрите в perlport примечания о переносимости этой конструкции.
Поведение убийства,когдаPROCESSчисло равно нулю или отрицательное зависит от операционной системы.Например,на POSIX-совместимых системах ноль будет сигнализировать о текущей группе процессов,-1 будет сигнализировать обо всех процессах,а любое другое отрицательное число PROCESS будет действовать как отрицательное число сигнала и убьет всю указанную группу процессов.
Если и СИГНАЛ,и ПРОЦЕСС отрицательны,результаты не определены.Предупреждение может быть выдано в будущей версии.
См. «Сигналы» в perlipc для более подробной информации.
На некоторых платформах, таких как Windows, где системный вызов fork(2) недоступен, Perl может быть построен для эмуляции fork на уровне интерпретатора. Эта эмуляция имеет ограничения, связанные с уничтожением, которые необходимо учитывать для кода, работающего в Windows, и для кода, предназначенного для переноса.
Смотрите perlfork для более подробной информации.
Если нетLISTпроцессов, сигнал не посылается, а возвращаемое значение равно 0. Эта форма, однако, иногда используется, потому что она вызывает выполнение проверок на заражение, если ваш perl поддерживает проверки на заражение. Но см. «Отмывание и обнаружение испорченных данных» в perlsec .
Проблемы с переносимостью: «убить» в perlport .
Последняя команда похожа на оператор break в C last используемый в циклах); он немедленно выходит из рассматриваемого цикла. Если LABEL опущен, команда относится к самому внутреннему охватывающему циклу. Последняя форма last EXPR , доступная, начиная с Perl 5.18.0, позволяет вычислять имя метки во время выполнения, в остальном она идентична last LABEL . Блок continue , если он есть, не выполняется:
LINE: while (<STDIN>) { last LINE if /^$/; }
last не может возвращать значение из блока, который обычно возвращает значение, например eval {} , sub {} или do {} . Он будет выполнять свое поведение управления потоком, которое исключает любое возвращаемое значение. Его не следует использовать для выхода из grep или map .
Обратите внимание, что блок сам по себе семантически идентичен циклу, который выполняется один раз. Таким образом last можно использовать для досрочного выхода из такого блока.
См. также continue для иллюстрации того, как работают last , next и redo .
В отличие от большинства именованных операторов, это имеет тот же приоритет, что и присваивание. На него также не распространяется правило похожести на функцию, поэтому last ("foo")."bar" приведет к тому, что «bar» будет частью аргумента last .
Возвращает версию EXPR в нижнем регистре. Если EXPR опущен, используется $_ .
my $str = lc("Perl is GREAT");
То,что возвращается,зависит от нескольких факторов:
- Если
use bytes: -
Результаты соответствуют правилам ASCII. Только символы
A-Zменяются наa-zсоответственно. - В противном случае, если действует
use localeдляLC_CTYPE: -
Уважает текущую локаль
LC_CTYPEдля кодовых точек <256; и использует правила Unicode для остальных кодовых точек (последнее может произойти, только если также установлен флаг UTF8). Смотрите perllocale .Начиная с версии 5.20, Perl использует полные правила Unicode, если языковой стандарт — UTF-8. В противном случае в этой схеме есть недостаток, заключающийся в том, что изменения случая, которые пересекают границу 255/256, не являются четко определенными. Например, строчная ЛАТИНСКАЯ ЗАГЛАВНАЯ БУКВА SHARP S (U + 1E9E) в правилах Unicode — это U + 00DF (на платформах ASCII). Но при
use locale(до версии 5.20 или не в локали UTF-8) нижний регистр U + 1E9E является самим собой, потому что 0xDF может не быть LATIN SMALL LETTER SHARP S в текущей локали, а Perl не имеет возможности зная, существует ли этот символ в локали, не говоря уже о том, какой это код. Perl возвращает результат, превышающий 255 (почти всегда входной символ неизменен) для всех экземпляров (а их немного), в которых граница 255/256 в противном случае была бы пересечена; и начиная с v5.22, он вызываетпредупреждение о локали . - В противном случае,если в EXPR установлен флаг UTF8:
-
Для изменения регистра используются правила Юникода.
- В противном случае, если
use feature 'unicode_strings'илиuse locale ':not_characters': -
Для изменения регистра используются правила Юникода.
- Otherwise:
-
Для изменения дела используются ASCII правила.Низкий регистр любого символа вне диапазона ASCII-это сам символ.
Примечание. Это внутренняя функция, реализующая экранирование L в строках с двойными кавычками.
my $str = "Perl is LGREATE";
Возвращает значение EXPR с первым символом в нижнем регистре. Это внутренняя функция, реализующая экранирование l в строках, заключенных в двойные кавычки.
Если EXPR опущен, используется $_ .
Эта функция ведет себя одинаково с различными прагмами, например, в локали, как это делает lc .
Возвращает длину вcharactersот значения EXPR. Если EXPR опущен, возвращает длину $_ . Если EXPR не определено, возвращает undef .
Эту функцию нельзя использовать для всего массива или хэша, чтобы узнать, сколько в них элементов. Для этого используйте scalar @array scalar keys %hash @array и скалярные ключи% hash соответственно.
Как и все символьные операции в Perl, length обычно работает с логическими символами, а не с физическими байтами. Чтобы узнать, сколько байтов займет строка, закодированная как UTF-8, используйте length(Encode::encode('UTF-8', EXPR)) ( сначала вам нужно будет use Encode См. Кодирование и перлуникод .
Специальный токен, который компилируется в текущий номер строки. Его можно изменить с помощью механизма, описанного в разделе «Обычные старые комментарии (не!)» В perlsyn .
Создает новое имя,связанное со старым именем.Возвращает правду для успеха,ложь в противном случае.
Проблемы с переносимостью: «ссылка» в perlport .
Делает то же самое, что и системный вызов listen (2) . Возвращает true в случае успеха и false в противном случае. См. Пример в разделе «Сокеты: связь клиент / сервер» в perlipc .
Вы действительно, вероятно, захотите использовать my вместо этого, потому что local это не то, что большинство людей считают «местным». Подробнее см. в разделе «Частные переменные через my()» в perlsub .
Local изменяет перечисленные переменные, чтобы они были локальными для включающего блока, файла или eval. Если указано более одного значения, список должен быть заключен в круглые скобки. См. «Временные значения через local ()» в perlsub для получения подробной информации, включая проблемы со связанными массивами и хешами.
Конструкцию delete local EXPR также можно использовать для локализации удаления элементов массива/хэша в текущем блоке. См. «Локальное удаление элементов составных типов» в perlsub .
Преобразует время,возвращаемое функцией времени,в 9-элементный список,в котором время анализируется для местного часового пояса.Обычно используется следующим образом:
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
Все элементы списка являются числовыми и происходят прямо из структуры C `struct tm ‘. $sec , $min и $hour — секунды, минуты и часы указанного времени.
$mday — это день месяца, а $mon — месяц в диапазоне 0..11 0 до 11, где 0 означает январь, а 11 — декабрь. Это позволяет легко получить название месяца из списка:
my @abbr = qw(Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec); print "$abbr[$mon] $mday";
$year содержит количество лет, прошедших с 1900 года. Чтобы получить год из 4 цифр, напишите:
$year += 1900;
Чтобы получить последние две цифры года (например,»01″ в 2001 году),сделайте:
$year = sprintf("%02d", $year % 100);
$wday — это день недели, где 0 означает воскресенье, а 3 — среду. $yday — день года в диапазоне 0..364 (или 0..365 в високосных годах).
$isdst имеет значение true, если указанное время наступает, когда действует летнее время, и false в противном случае.
Если EXPR опущен, localtime использует текущее время (которое возвращает time ).
В скалярном контексте localtime возвращает значение ctime(3) :
my $now_string = localtime;
Это скалярное значение всегда на английском языке и не зависит от языкового стандарта. Чтобы получить аналогичные, но зависящие от локали строки даты, попробуйте, например:
use POSIX qw(strftime); my $now_string = strftime "%a %b %e %H:%M:%S %Y", localtime; my $now_string = strftime "%a %b %e %H:%M:%S %Y", gmtime;
C $ now_string> будет отформатирован в соответствии с текущим языковым стандартом LC_TIME, в котором работает программа или поток. См. Perllocale, чтобы узнать, как настроить и изменить этот языковой стандарт. Обратите внимание, что %a и %b , краткие формы дня недели и месяца года, не обязательно могут состоять из трех символов.
Модули Time ::gmtime и Time::localtime предоставляют удобный механизм доступа по имени к функциям gmtime и localtime соответственно.
Для полного представления даты и времени посмотрите модуль DateTime на CPAN.
Для GMT вместо местного времени используйте встроенную функцию gmtime .
См. также модуль Time::Local (для преобразования секунд, минут, часов и т. д. обратно в целочисленное значение, возвращаемое time ) и функцию mktime модуля POSIX .
Проблемы переносимости: «localtime» в perlport .
Эта функция накладывает консультативную блокировку на общую переменную или объект,на который делается ссылка,и который содержится вTHINGпока замок не выйдет из строя.
Возвращаемое значение является самим скаляром,если аргумент является скаляром,или ссылкой,если аргумент является хэшем,массивом или подпрограммным.
lock — «слабое ключевое слово»; это означает, что если вы определили функцию с этим именем (до любых ее вызовов), вместо этого будет вызвана эта функция. Если вы не use threads::shared это ничего не делает. См. threads::shared .
Возвращает естественный логарифм (базовыйe) EXPR. Если EXPR не указан, возвращает журнал $_ . Чтобы получить логарифм другого основания, используйте базовую алгебру: журнал числа по основанию N равен натуральному логарифму этого числа, деленному на натуральный логарифм N. Например:
sub log10 { my $n = shift; return log($n)/log(10); }
См. также exp для обратной операции.
Делает то же самое, что и функция stat (включая установку специального дескриптора файла _ ), но выводит статистику по символической ссылке вместо файла, на который указывает символическая ссылка. Если в вашей системе не реализованы символические ссылки, выполняется обычная stat Для получения более подробной информации см. документацию по stat .
Если EXPR не указан, статистика $_ .
Проблемы с переносимостью: «lstat» в perlport .
Оператор соответствия. См. «Операторы, похожие на кавычки в регулярных выражениях» в perlop .
Оценивает BLOCK или EXPR для каждого элемента LIST (локально устанавливая $_ для каждого элемента) и составляет список результатов каждой такой оценки. Каждый элемент LIST может создавать ноль, один или несколько элементов в сгенерированном списке, поэтому количество элементов в сгенерированном списке может отличаться от количества в LIST. В скалярном контексте возвращает общее количество сгенерированных таким образом элементов. В контексте списка возвращает сгенерированный список.
my @chars = map(chr, @numbers);
переводит список номеров в соответствующие символы.
my @squares = map { $_ * $_ } @numbers;
переводит список чисел в их квадратные значения.
my @squares = map { $_ > 5 ? ($_ * $_) : () } @numbers;
показывает,что количество возвращаемых элементов может отличаться от количества входных элементов.Чтобы опустить элемент,верните пустой список ().Это также может быть достигнуто путем записи
my @squares = map { $_ * $_ } grep { $_ > 5 } @numbers;
что делает намерение более ясным.
Карта всегда возвращает список, который может быть назначен хешу, так что элементы становятся парами ключ / значение. См. Perldata для получения более подробной информации.
my %hash = map { get_a_key_for($_) => $_ } @array;
просто забавный способ писать
my %hash; foreach (@array) { $hash{get_a_key_for($_)} = $_; }
Обратите внимание, что $_ — это псевдоним значения списка, поэтому его можно использовать для изменения элементов списка. Хотя это полезно и поддерживается, это может привести к странным результатам, если элементы LIST не являются переменными. Использование для этой цели обычного цикла foreach в большинстве случаев было бы понятнее. См. также grep для списка, состоящего из тех элементов исходного списка, для которых BLOCK или EXPR оцениваются как истинные.
{ запускает как ссылки на хеш, так и блоки, поэтому map { ... может быть либо началом карты BLOCK LIST, либо картой EXPR, LIST. Поскольку Perl не ожидает закрытия } , он должен угадывать, с чем он имеет дело, основываясь на том, что он находит сразу после { . Обычно он делает это правильно, но если этого не происходит, он не поймет, что что-то не так, пока не доберется до } и не обнаружит отсутствующую (или неожиданную) запятую. Синтаксическая ошибка будет сообщаться рядом с } , но вам нужно будет что-то изменить рядом с { , например, использовать унарный + или точку с запятой, чтобы помочь Perl:
my %hash = map { "L$_" => 1 } @array my %hash = map { +"L$_" => 1 } @array my %hash = map {; "L$_" => 1 } @array my %hash = map { ("L$_" => 1) } @array my %hash = map { lc($_) => 1 } @array my %hash = map +( lc($_) => 1 ), @array my %hash = map ( lc($_), 1 ), @array
или чтобы заставить конструктор анонимного хэша использовать +{ :
my @hashes = map +{ lc($_) => 1 }, @array
чтобы получить список анонимных хэшей,каждый из которых содержит только по одной записи.
Создает каталог, указанный FILENAME, с разрешениями, указанными MODE (как изменено umask ). В случае успеха возвращается true; в противном случае он возвращает false и устанавливает $! (ошибка). MODE по умолчанию равен 0777, если он опущен, а FILENAME по умолчанию равен $_ , если он опущен.
В общем, лучше создавать каталоги с разрешающим РЕЖИМОМ и позволять пользователю изменять его с помощью своего umask , чем предоставлять ограничивающий РЕЖИМ и не давать пользователю возможности быть более разрешительным. Исключениями из этого правила являются случаи, когда файл или каталог должны оставаться закрытыми (например, почтовые файлы). В документации по umask выбор РЕЖИМА обсуждается более подробно.
Обратите внимание,что в соответствии с POSIX 1003.1-1996 ФИЛЕНАМА может иметь любое количество трейлинговых слэшей.В некоторых операционных и файловых системах это неправильно,поэтому Perl автоматически удаляет все трейлинговые слэши,чтобы все были довольны.
Чтобы рекурсивно создать структуру каталогов, посмотрите на функцию make_path модуля File :: Path .
Вызов функции System V IPC msgctl (2) . Вам, вероятно, придется сказать
use IPC::SysV;
сначала получить правильные определения констант. Если CMD — IPC_STAT , то ARG должна быть переменной, которая будет содержать возвращаемую структуру msqid_ds . Возвращает как ioctl : неопределенное значение для ошибки, "0 but true" для нуля или фактическое возвращаемое значение в противном случае. См. также «SysV IPC» в perlipc и документацию для IPC::SysV и IPC::Semaphore .
Проблемы с переносимостью: «msgctl» в perlport .
Вызывает функцию System V IPC msgget(2) . Возвращает идентификатор очереди сообщений или undef в случае ошибки. См. также «SysV IPC» в perlipc и документацию для IPC::SysV и IPC::Msg .
Проблемы с переносимостью: «msgget» в perlport .
Вызывает IPC-функцию System V msgrcv для получения сообщения из очереди сообщений с идентификатором в переменную VAR с максимальным размером сообщения SIZE. Обратите внимание, что когда сообщение получено, тип сообщения как собственное длинное целое число будет первым в VAR, за которым следует фактическое сообщение. Эту упаковку можно открыть с помощью unpack("l! a*") . Загрязняет переменную. Возвращает true в случае успеха, false в случае ошибки. См. также «SysV IPC» в perlipc и документацию для IPC::SysV и IPC::Msg .
Проблемы с переносимостью: «msgrcv» в perlport .
Вызывает IPC-функцию System V msgsnd для отправки сообщения MSG в идентификатор очереди сообщений. MSG должен начинаться с собственного длинного целочисленного типа сообщения, за которым следует само сообщение. Такого рода упаковки можно добиться с помощью pack("l! a*", $type, $message) . Возвращает true в случае успеха, false в случае ошибки. См. также «SysV IPC» в perlipc и документацию для IPC::SysV и IPC::Msg .
Проблемы с переносимостью: «msgsnd» в perlport .
my объявляет перечисленные переменные локальными (лексически) для окружающего блока, файла my eval . Если указано более одной переменной, список должен быть заключен в круглые скобки.
Обратите внимание, что со списком в скобках undef можно использовать в качестве фиктивного заполнителя, например, чтобы пропустить присвоение начальных значений:
my ( undef, $min, $hour ) = localtime;
Повторное объявление переменной в той же области или операторе «затеняет» предыдущее объявление, создавая новый экземпляр и предотвращая доступ к предыдущему. Обычно это нежелательно и, если включены предупреждения, приведет к предупреждению в shadow категории.
Точная семантика и интерфейс TYPE и ATTRS все еще развиваются. TYPE может быть пустым словом, константой, объявленной с use constant , или __PACKAGE__ . В настоящее время он связан с использованием прагмы fields , а атрибуты обрабатываются с помощью прагмы атрибутов или, начиная с Perl 5.8.0, также с помощью модуля Attribute::Handlers . Подробнее см. в разделе «Частные переменные через my()» в perlsub .
Следующая команда похожа на next continue в C; он запускает следующую итерацию цикла:
LINE: while (<STDIN>) { next LINE if /^ }
Обратите внимание, что если бы в приведенном выше примере был блок continue , он выполнялся бы даже в отброшенных строках. Если LABEL опущен, команда относится к самому внутреннему охватывающему циклу. Следующая форма next EXPR , доступная начиная с Perl 5.18.0, позволяет вычислять имя метки во время выполнения, в остальном она идентична next LABEL .
next не может возвращать значение из блока, который обычно возвращает значение, например eval {} , sub {} или do {} . Он будет выполнять свое поведение управления потоком, которое исключает любое возвращаемое значение. Его не следует использовать для выхода из grep или map .
Обратите внимание, что блок сам по себе семантически идентичен циклу, который выполняется один раз. Таким образом next выйдет из такого блока раньше.
См. также continue для иллюстрации того, как работают last , next и redo .
В отличие от большинства именованных операторов, это имеет тот же приоритет, что и присваивание. На него также не распространяется правило «выглядит как функция», поэтому next ("foo")."bar" приведет к тому, что «bar» станет частью аргумента для next .
См. функцию use , противоположной которой no
Интерпретирует EXPR как восьмеричную строку и возвращает соответствующее значение. Восьмеричная строка состоит из восьмеричных цифр и, начиная с Perl 5.33.5, необязательного префикса 0o или o . Каждой восьмеричной цифре может предшествовать один знак подчеркивания, который будет проигнорирован. (Если EXPR начинается с 0x или x , интерпретируется как шестнадцатеричная строка. Если EXPR начинается с 0b или b , он интерпретируется как двоичная строка. Начальные пробелы игнорируются во всех трех случаях.) Следующее будет обрабатывать десятичные, двоичные, восьмеричные и шестнадцатеричные числа в стандартной нотации Perl:
$val = oct($val) if $val =~ /^0/;
Если EXPR опущен, используется $_ . Чтобы пойти другим путем (создать восьмеричное число), используйте sprintf или printf :
my $dec_perms = (stat("filename"))[2] & 07777; my $oct_perm_str = sprintf "%o", $perms;
Функция oct обычно используется, например, когда строку, такую как 644 , необходимо преобразовать в файловый режим. Хотя Perl автоматически преобразует строки в числа по мере необходимости, это автоматическое преобразование предполагает основание 10.
Начальный пробел игнорируется без предупреждения, как и любые завершающие нецифры, такие как десятичная точка ( oct обрабатывает только неотрицательные целые числа, а не отрицательные целые числа или числа с плавающей запятой).
Ассоциирует внутренний FILEHANDLE с внешним файлом,указанным EXPR.Этот файл-руководство впоследствии позволит вам выполнять операции ввода-вывода с этим файлом,такие как чтение из него или запись в него.
Вместо имени файла вы можете указать внешнюю команду (плюс необязательный список аргументов)или ссылку на скаляр,чтобы открыть файловые ручки на командах или скалярах в памяти,соответственно.
Подробная ссылка на open следует. Для более подробного ознакомления с основами open см. Также страницу руководства perlopentut .
- Работа с файлами
-
Чаще всего
openвызывается с тремя аргументами: требуемый FILEHANDLE (обычно пустая скалярная переменная), за которым следует MODE (обычно литерал, описывающий режим ввода-вывода, который будет использовать дескриптор файла), а затем имя файла, на которое будет ссылаться новый дескриптор файла. к.- Simple examples
-
Чтение из файла:
open(my $fh, "<", "input.txt") or die "Can't open < input.txt: $!"; while (my $line = <$fh>) { }
или написать одному из них:
open(my $fh, ">", "output.txt") or die "Can't open > output.txt: $!"; print $fh "This line gets printed into output.txt.n";
Для обзора общих операций с файлами, таких как эти, см. «Файлы и ввод-вывод» в perlintro .
- About filehandles
-
Первый аргумент для
open, помеченный в этой ссылке FILEHANDLE, обычно является скалярной переменной. (Существуют исключения, описанные ниже в разделе «Прочие соображения».) Если вызовopenзавершится успешно, то выражению, предоставленному как FILEHANDLE, будет назначен открытыйfilehandle. Этот дескриптор файла обеспечивает внутреннюю ссылку на указанный внешний файл, удобно хранящийся в переменной Perl и готовый для операций ввода-вывода, таких как чтение и запись. - About modes
-
При вызове
openс тремя или более аргументами второй аргумент, обозначенный здесь MODE, определяетopen mode. MODE обычно представляет собой буквальную строку, содержащую специальные символы, которые определяют предполагаемую роль ввода-вывода создаваемого дескриптора файла: только для чтения, для чтения и записи и т. Д.Если РЕЖИМ
<, файл открывается для ввода (только для чтения). Если MODE>, файл открывается для вывода, при этом существующие файлы сначала усекаются («затираются»), а несуществующие файлы создаются заново. Если MODE>>, файл открывается для добавления, при необходимости он создается снова.Вы можете поставить
+перед>или<, чтобы указать, что вы хотите иметь доступ как для чтения, так и для записи в файл; таким образом,+<почти всегда предпочтительнее для чтения/записи обновлений — режим+>сначала уничтожит файл. Обычно вы не можете использовать ни один из режимов чтения-записи для обновления текстовых файлов, поскольку они имеют записи переменной длины. См. ключ -i в perlrun для лучшего подхода. Файл создается с разрешениями0666,измененными значениемumaskпроцесса .Эти различные префиксы соответствуют режимам fopen (3)
r,r+,w,w+,aиa+.Больше примеров различных режимов в действии:
open(my $log, ">>", "/usr/spool/news/twitlog") or warn "Couldn't open log file; discarding input"; open(my $dbase, "+<", "dbase.mine") or die "Can't open 'dbase.mine' for update: $!";
- Проверка возвращаемого значения
-
Open возвращает ненулевое значение в случае успеха, в противном случае — неопределенное значение. Если
openсвязано с конвейером, возвращаемое значение оказывается pid подпроцесса.При открытии файла редко бывает целесообразно продолжать, если запрос не удался, поэтому
openчасто используется сdie. Даже если вы хотите, чтобы ваш код делал что-то другое, а неdieпри неудачном открытии, вы все равно должны всегда проверять возвращаемое значение при открытии файла.
- Указание уровней ввода/вывода в MODE
-
Вы можете использовать форму open с тремя аргументами, чтобы указать уровни ввода-вывода (иногда называемые «дисциплинами»), применяемые к новому дескриптору файла. Они влияют на то, как обрабатываются ввод и вывод (подробнее см. Open и PerlIO ). Например:
open(my $fh, "<:encoding(UTF-8)", $filename) || die "Can't open UTF-8 encoded $filename: $!";
Откроется файл в кодировке UTF8, содержащий символы Unicode; см. perluniintro . Обратите внимание, что если слои указаны в форме с тремя аргументами, то слои по умолчанию, хранящиеся в
${^OPEN}(обычно устанавливаемые-CioDopen или переключателем -CioD ), игнорируются. Эти слои также будут проигнорированы, если вы укажете двоеточие без имени после него. В этом случае используется уровень по умолчанию для операционной системы (: raw в Unix,: crlf в Windows).В некоторых системах (как правило, в системах на базе DOS и Windows)
binmodeнеобходим, когда вы не работаете с текстовым файлом. Ради мобильности рекомендуется всегда использовать его, когда это уместно, и никогда не использовать, когда это неуместно. Кроме того, люди могут установить для своего ввода-вывода по умолчанию Unicode в кодировке UTF8, а не байты. - Использование
undefдля временных файлов -
В качестве особого случая форма с тремя аргументами с режимом чтения/записи и третьим аргументом
undef:open(my $tmp, "+>", undef) or die ...
открывает дескриптор вновь созданного пустого анонимного временного файла. (Это происходит в любом режиме, что делает
+>единственным полезным и разумным режимом для использования.) Вам нужно будетseekвыполнить чтение. - Открытие файлового хэндла в скаляр в памяти
-
Вы можете открывать дескрипторы файлов непосредственно в скалярах Perl вместо файла или другого ресурса, внешнего по отношению к программе. Для этого укажите ссылку на этот скаляр в качестве третьего аргумента для
open, например:open(my $memory, ">", $var) or die "Can't open memory file: $!"; print $memory "foo!n";
Чтобы (повторно) открыть
STDOUTилиSTDERRкак файл в памяти, сначала закройте его:close STDOUT; open(STDOUT, ">", $variable) or die "Can't open STDOUT: $!";
Скаляры для файлов в памяти рассматриваются как октетные строки:если файл не открывается с усечением,скаляр не может содержать кодовых точек больше 0xFF.
Открытие файлов в памятиcanтерпят неудачу по разным причинам. Как и в случае с любым другим
open, проверьте возвращаемое значение на успех.Technical note: Эта функция работает только тогда, когда Perl собран с PerlIO — по умолчанию, за исключением старых (до 5.16) установок Perl, которые были настроены так, чтобы не включать его (например, через
Configure -Uuseperlio). Вы можете увидеть, был ли ваш Perl собран с PerlIO, запустивperl -V:useperlio. Если там написано'define', у вас есть PerlIO; в противном случае вы этого не сделаете.См. Perliol для получения подробной информации о PerlIO.
- Открытие файла в команде
-
Если РЕЖИМ равен
|-, то имя файла интерпретируется как команда, к которой должен быть передан вывод, а если РЕЖИМ-|, имя файла интерпретируется как команда, которая передает нам выходные данные. В форме с двумя аргументами (и с одним аргументом) следует заменить тире (-) на команду. Дополнительные примеры см. В разделе «Использование open () для IPC» в perlipc . (Вам не разрешеноopenкоманду, которая передает оба канала вandout, но см. IPC::Open2 , IPC::Open3 и «Двунаправленная связь с другим процессом» в perlipc для альтернатив.)open(my $article_fh, "-|", "caesar <$article") or die "Can't start caesar: $!"; open(my $article_fh, "caesar <$article |") or die "Can't start caesar: $!"; open(my $out_fh, "|-", "sort >Tmp$$") or die "Can't start sort: $!";
В форме канала открывается с тремя или более аргументами, если LIST указан (дополнительные аргументы после имени команды), тогда LIST становится аргументом для вызываемой команды, если платформа поддерживает его. Значение
openс более чем тремя аргументами для режимов без конвейера еще не определено, но экспериментальные «уровни» могут дать значение дополнительных аргументов LIST.Если вы открываете канал с помощью команды
-(то есть указываете|-или-|с формойopenс одним или двумя аргументами), выполняется неявнаяforkopenвозвращает дважды: в родительском процессе он возвращает pid дочернего процесса, и в дочернем процессе он возвращает (определенный)0. Используйтеdefined($pid)или//, чтобы определить, было ли открытие успешным.Например,использовать либо
my $child_pid = open(my $from_kid, "-|") // die "Can't fork: $!";
or
my $child_pid = open(my $to_kid, "|-") // die "Can't fork: $!";
followed by
if ($child_pid) { ... waitpid $child_pid, 0; } else { ... exit; }
Родительский процесс ведет себя нормально,но ввод/вывод к этому файловому процессу осуществляется из/в STDOUT/STDIN дочернего процесса.В дочернем процессе файловая папка не открывается-вход/выход происходит из/к новому STDOUT/STDIN.Обычно это используется как обычный открытый конвейер,когда вы хотите получить больше контроля над тем,как выполняется команда канала,например,при запуске setuid,и вам не нужно сканировать команды оболочки на наличие метасимволов.
Следующие блоки более или менее эквивалентны:
open(my $fh, "|tr '[a-z]' '[A-Z]'"); open(my $fh, "|-", "tr '[a-z]' '[A-Z]'"); open(my $fh, "|-") || exec 'tr', '[a-z]', '[A-Z]'; open(my $fh, "|-", "tr", '[a-z]', '[A-Z]'); open(my $fh, "cat -n '$file'|"); open(my $fh, "-|", "cat -n '$file'"); open(my $fh, "-|") || exec "cat", "-n", $file; open(my $fh, "-|", "cat", "-n", $file);
Последние два примера в каждом блоке показывают канал как «форму списка», которая пока не поддерживается на всех платформах. (Если ваша платформа имеет настоящую
fork, такую как Linux и macOS, вы можете использовать форму списка; она также работает в Windows с Perl 5.22 или более поздней версии.) Вы хотели бы использовать форму списка канала, чтобы вы могли передавать литерал аргументы команды без риска того, что оболочка интерпретирует содержащиеся в них метасимволы оболочки. Однако это также запрещает вам открывать каналы для команд, которые намеренно содержат метасимволы оболочки, например:open(my $fh, "|cat -n | expand -4 | lpr") || die "Can't open pipeline to lpr: $!";
См. «Safe Pipe Opens» в perlipc для получения дополнительных примеров.
- Duping filehandles
-
Вы также можете, в традиции оболочки Bourne, указать EXPR, начинающийся с
>&, и в этом случае остальная часть строки интерпретируется как имя дескриптора файла (или дескриптора файла, если числовой), который нужно дублировать (как в dup ( 2) ) и открыл. Вы можете использовать&после>,>>,<,+>,+>>и+<. Указанный вами режим должен соответствовать режиму исходного дескриптора файла. (При дублировании дескриптора файла не учитывается какое-либо существующее содержимое буферов ввода-вывода.) Если вы используете форму с тремя аргументами, вы можете передать либо число, либо имя дескриптора файла, либо обычную «ссылку на глобус».Вот сценарий, который сохраняет, перенаправляет и восстанавливает
STDOUTиSTDERRс помощью различных методов:open(my $oldout, ">&STDOUT") or die "Can't dup STDOUT: $!"; open(OLDERR, ">&", *STDERR) or die "Can't dup STDERR: $!"; open(STDOUT, '>', "foo.out") or die "Can't redirect STDOUT: $!"; open(STDERR, ">&STDOUT") or die "Can't dup STDOUT: $!"; select STDERR; $| = 1; select STDOUT; $| = 1; print STDOUT "stdout 1n"; print STDERR "stderr 1n"; open(STDOUT, ">&", $oldout) or die "Can't dup $oldout: $!"; open(STDERR, ">&OLDERR") or die "Can't dup OLDERR: $!"; print STDOUT "stdout 2n"; print STDERR "stderr 2n";
Если вы укажете
'<&=X', гдеX— номер дескриптора файла или дескриптор файла, тогда Perl выполнит эквивалент C fdopen (3) этого дескриптора файла (а не вызовет dup (2) ); это более экономный дескриптор файлов. Например:open(my $fh, "<&=", $fd)
or
open(my $fh, "<&=$fd")
or
open(my $fh, ">>&=", $oldfh)
Экономия файловых дескрипторов также полезна (помимо экономии), например, когда что-то зависит от файловых дескрипторов, например, блокировка с использованием
flock. Если вы простоopen(my $A, ">>&", $B), дескриптор файла$Aне будет иметь тот же файловый дескриптор, что и$B, и поэтомуflock($A)не будетflock($B)или наоборот. Но сopen(my $A, ">>&=", $B)дескрипторы файлов будут использовать один и тот же базовый файловый дескриптор.Обратите внимание, что в Perls старше 5.8.0 Perl использует fdopen (3) стандартной библиотеки C для реализации функциональности
=. Во многих системах Unix fdopen (3) не работает, когда дескрипторы файлов превышают определенное значение, обычно 255. Для Perls 5.8.0 и более поздних версий PerlIO (чаще всего) используется по умолчанию. - Legacy usage
-
В этом разделе описаны способы вызова
openза пределами лучших практик; вы можете встретить такое использование в старом коде. Perl точно не считает их использование устаревшим, но и не рекомендуется в новом коде для ясности и удобочитаемости.- Указание режима и имени файла в качестве одного аргумента
-
В формах вызова с одним и двумя аргументами режим и имя файла должны быть объединены (в указанном порядке), предпочтительно разделенными пробелом. Вы можете — но не должны — опускать режим в этих формах, когда этот режим
<. Безопасно использовать формуopenс двумя аргументами, если аргумент имени файла является известным литералом.open(my $dbase, "+<dbase.mine") or die "Can't open 'dbase.mine' for update: $!";
В форме с двумя аргументами (и с одним аргументом) открытие
<-или-открывает STDIN, а открытие>-открывает STDOUT.В новом коде следует отдавать предпочтение форме
openс тремя аргументами, а не старой форме. Объявление режима и имени файла как двух разных аргументов позволяет избежать путаницы между ними. - Вызов
openс одним аргументом через глобальные переменные -
В качестве сокращения,вызов с одним аргументом берет имя файла из глобальной скалярной переменной с тем же именем,что и filehandle:
$ARTICLE = 100; open(ARTICLE) or die "Can't find article $ARTICLE: $!n";
Здесь
$ARTICLEдолжна быть глобальной (пакетной) скалярной переменной, а не объявленной с помощьюmyилиstate. - Присвоение файлового манипулятора пустому слову
-
Старый стиль заключается в использовании голого слова в качестве ручки файла,а именно
open(FH, "<", "input.txt") or die "Can't open < input.txt: $!";
Затем вы можете использовать
FHв качестве дескриптора файла,close FHи<FH>и так далее. Обратите внимание, что это глобальная переменная, поэтому эта форма не рекомендуется при работе с дескрипторами файлов, отличными от встроенных в Perl (например, STDOUT и STDIN). На самом деле использование голого слова для дескриптора файла является ошибкой, если функцияbareword_filehandlesотключена. Эта функция отключена по умолчанию в рамкахuse v5.36.0или более поздней.
- Other considerations
-
- Автоматическое закрытие файловой ручки
-
Дескриптор файла будет закрыт, когда его счетчик ссылок достигнет нуля. Если это переменная с лексической областью видимости, объявленная с помощью
my, это обычно означает конец объемлющей области видимости. Однако это автоматическое закрытие не проверяет наличие ошибок, поэтому лучше явно закрывать дескрипторы файлов, особенно те, которые используются для записи:close($handle) || warn "close failed: $!";
- Автоматическая промывка труб
-
Perl попытается очистить все файлы, открытые для вывода, перед любой операцией, которая может выполнить форк, но это может не поддерживаться на некоторых платформах (см. Perlport ). На всякий случай вам может потребоваться установить
$|($AUTOFLUSHна английском языке ) или вызовите методautoflushIO::Handleдля любых открытых дескрипторов.В системах , которые поддерживают тесную-на-Exec флаг на файлах, флаг будет установлен для вновь открытого дескриптора файла , как определено значением
$^F. Смотрите «$ ^ F» в perlvar .Закрытие любого обработчика файла по конвейеру заставляет родительский процесс ждать завершения дочернего процесса, а затем возвращает значение статуса в
$?и${^CHILD_ERROR_NATIVE}. - Прямое и попутное назначение ссылок на файлы
-
Если FILEHANDLE — первый аргумент в вызове
open— является неопределенной скалярной переменной (или массивом, или хеш-элементом), новый дескриптор файла автоматически обновляется, что означает, что переменной назначается ссылка на вновь выделенный анонимный дескриптор файла. В противном случае, если FILEHANDLE является выражением, его значением является реальный дескриптор файла. (Это считается символической ссылкой, поэтомуuse strict "refs"должнаnot…будет в действии.) - Пробелы и специальные символы в аргументе имени файла
-
В имени файла, передаваемом в формы
openс одним и двумя аргументами , начальные и конечные пробелы будут удалены, а обычные символы перенаправления будут учтены. Это свойство, известное как «магическое открытие», часто можно использовать с хорошими результатами. Пользователь мог указать имя файла«rsh cat файл |», или вы можете изменить определенные имена файлов по мере необходимости:$filename =~ s/(.*.gz)s*$/gzip -dc < $1|/; open(my $fh, $filename) or die "Can't open $filename: $!";
Используйте трехпараметрическую форму,чтобы открыть файл с произвольными странными символами,
open(my $fh, "<", $file) || die "Can't open $file: $!";
в противном случае необходимо защищать любое ведущее и отстающее белое пространство:
$file =~ s open(my $fh, "< $file") || die "Can't open $file: $!";
(это может не работать в некоторых странных файловых системах). Следует сознательно выбирать междуmagicandthree-argumentформа
open:open(my $in, $ARGV[0]) || die "Can't open $ARGV[0]: $!";
позволит пользователю указать аргумент формы
"rsh cat file |", но не будет работать с именем файла, в котором есть конечный пробел, аopen(my $in, "<", $ARGV[0]) || die "Can't open $ARGV[0]: $!";
будут иметь прямо противоположные ограничения. (Однако некоторые оболочки поддерживают синтаксис
perl your_program.pl <( rsh cat file ), который создает имя файла, которое можно открыть в обычном режиме.) - Вызов C-style
open -
Если вам нужен «настоящий» C open (2) , тогда вам следует использовать функцию
sysopen, которая не включает в себя такой магии (но использует другие файловые режимы, чем Perlopen, что соответствует C fopen (3) ). Это еще один способ защитить ваши имена файлов от интерпретации. Например:use IO::Handle; sysopen(my $fh, $path, O_RDWR|O_CREAT|O_EXCL) or die "Can't open $path: $!"; $fh->autoflush(1); print $fh "stuff $$n"; seek($fh, 0, 0); print "File contains: ", readline($fh);
См.
seekнекоторых подробностей о смешивании чтения и письма. - Portability issues
-
См. «открыть» в perlport .
Открывает каталог с именем EXPR для обработки readdir , telldir , seekdir , rewinddir и closedir . Возвращает true в случае успеха. DIRHANDLE может быть выражением, значение которого может быть использовано в качестве косвенного дескриптора каталога, обычно реального имени дескриптора каталога. Если DIRHANDLE является неопределенной скалярной переменной (или массивом, или элементом хэша), переменной присваивается ссылка на новый анонимный дескриптор dir; то есть он автожививен. Дескрипторы каталогов — это те же объекты, что и дескрипторы файлов; объект ввода-вывода может быть открыт одновременно только как один из этих типов дескрипторов.
См. пример в readdir .
Возвращает числовое значение первого символа EXPR. Если EXPR — пустая строка, возвращает 0. Если EXPR опущено, используется $_ . (Примечаниеcharacter, а не байт.)
Обратную сторону см. в chr . См. perlunicode для получения дополнительной информации о Unicode.
our создает лексический псевдоним для пакетной (т.е. глобальной) переменной с тем же именем в текущем пакете для использования в текущей лексической области видимости.
our те же правила области видимости, что и у my или state , а это означает, что она действительна только в пределах лексической области видимости. В отличие от my и state , которые объявляют новые (лексические) переменные, our только создает псевдоним для существующей переменной: переменная пакета с тем же именем.
Это означает, что когда действует use strict 'vars' , our позволяет вам использовать переменную пакета, не уточняя ее именем пакета, но только в пределах лексической области действия объявления our . Это применяется немедленно — даже в рамках одного и того же заявления.
package Foo; use v5.36; $Foo::foo = 23; { our $foo; print $foo; } print $Foo::foo; print $foo;
Это работает,даже если переменная пакета ранее не использовалась,так как переменные пакета появляются при первом использовании.
package Foo; use v5.36; our $foo = 23; print $Foo::foo;
Поскольку переменная становится допустимой сразу после use strict 'vars' , до тех пор, пока в области нет переменной с таким именем, вы можете снова ссылаться на переменную пакета даже в том же операторе.
package Foo; use v5.36; my $foo = $foo; our $foo = $foo;
Если список содержит более одной переменной,он должен быть заключен в круглые скобки.
our($bar, $baz);
Наше объявление объявляет псевдоним для переменной пакета, который будет виден во всей его лексической области видимости, даже за пределами пакета our Пакет, в который вводится переменная, определяется в момент объявления, а не в момент использования. Это означает следующее поведение:
package Foo; our $bar; $bar = 20; package Bar; print $bar;
Несколько our объявлений с одним и тем же именем в одной и той же лексической области видимости разрешены, если они находятся в разных пакетах. Если они окажутся в одном пакете, Perl выдаст предупреждения, если вы их запросили, точно так же, как несколько my объявлений. В отличие от второго объявления my , которое привязывает имя к новой переменной, второе объявление our в том же пакете и в той же области видимости просто избыточно.
use warnings; package Foo; our $bar; $bar = 20; package Bar; our $bar = 30; print $bar; our $bar; print $bar;
our объявление также может иметь список связанных с ним атрибутов.
Точная семантика и интерфейс TYPE и ATTRS все еще развиваются. TYPE в настоящее время привязан к использованию директивы fields , а атрибуты обрабатываются с помощью директивы attributes или, начиная с Perl 5.8.0, также через модуль Attribute :: Handlers . См. Подробности в разделе «Частные переменные через my ()» в perlsub .
Обратите внимание, что со списком в скобках undef можно использовать в качестве фиктивного заполнителя, например, чтобы пропустить присвоение начальных значений:
our ( undef, $min, $hour ) = localtime;
our отличается от use vars тем, что позволяет использовать неполное имяonlyв пределах пораженной упаковки,но в пределах диапазона.
Берет СПИСОК значений и преобразует его в строку по правилам,заданным TEMPLATE.Полученная строка представляет собой конкатенцию преобразованных значений.Обычно каждое преобразованное значение выглядит как его машинное представление.Например,на 32-битных машинах целое число может быть представлено последовательностью из 4 байт,которая в Perl будет представлена в виде строки длиной 4 символа.
См. Perlpacktut для введения в эту функцию.
TEMPLATE представляет собой последовательность символов,которые дают порядок и тип значений,как показано ниже:
a A string with arbitrary binary data, will be null padded. A A text (ASCII) string, will be space padded. Z A null-terminated (ASCIZ) string, will be null padded. b A bit string (ascending bit order inside each byte, like vec()). B A bit string (descending bit order inside each byte). h A hex string (low nybble first). H A hex string (high nybble first). c A signed char (8-bit) value. C An unsigned char (octet) value. W An unsigned char value (can be greater than 255). s A signed short (16-bit) value. S An unsigned short value. l A signed long (32-bit) value. L An unsigned long value. q A signed quad (64-bit) value. Q An unsigned quad value. (Quads are available only if your system supports 64-bit integer values _and_ if Perl has been compiled to support those. Raises an exception otherwise.) i A signed integer value. I An unsigned integer value. (This size depends on what a local C compiler calls n An unsigned short (16-bit) in "network" (big-endian) order. N An unsigned long (32-bit) in "network" (big-endian) order. v An unsigned short (16-bit) in "VAX" (little-endian) order. V An unsigned long (32-bit) in "VAX" (little-endian) order. j A Perl internal signed integer value (IV). J A Perl internal unsigned integer value (UV). f A single-precision float in native format. d A double-precision float in native format. F A Perl internal floating-point value (NV) in native format D A float of long-double precision in native format. (Long doubles are available only if your system supports long double values. Raises an exception otherwise. Note that there are different long double formats.) p A pointer to a null-terminated string. P A pointer to a structure (fixed-length string). u A uuencoded string. U A Unicode character number. Encodes to a character in char- acter mode and UTF-8 (or UTF-EBCDIC in EBCDIC platforms) in byte mode. Also on EBCDIC platforms, the character number will be the native EBCDIC value for character numbers below 256. This allows most programs using this feature to not have to care which type of platform they are running on. w A BER compressed integer (not an ASN.1 BER, see perlpacktut for details). Its bytes represent an unsigned integer in base 128, most significant digit first, with as few digits as possible. Bit eight (the high bit) is set on each byte except the last. x A null byte (a.k.a ASCII NUL, "00", chr(0)) X Back up a byte. @ Null-fill or truncate to absolute position, counted from the start of the innermost ()-group. . Null-fill or truncate to absolute position specified by the value. ( Start of a ()-group.
Один или несколько модификаторов ниже могут по желанию следовать определенным буквам в TEMPLATE (во второй колонке перечислены буквы,для которых модификатор действителен):
! sSlLiI Forces native (short, long, int) sizes instead
of fixed (16-/32-bit) sizes.
! xX Make x and X act as alignment commands.
! nNvV Treat integers as signed instead of unsigned.
! @. Specify position as byte offset in the internal
representation of the packed string. Efficient
but dangerous.
> sSiIlLqQ Force big-endian byte-order on the type.
jJfFdDpP (The "big end" touches the construct.)
< sSiIlLqQ Force little-endian byte-order on the type.
jJfFdDpP (The "little end" touches the construct.)
> И < модификаторы также может быть использованы на () группах , чтобы заставить конкретный порядок байт на все компоненты в этой группе, включая всю ее подгруппу.
Применяются следующие правила:
-
За каждой буквой необязательно может следовать число, указывающее счетчик повторов. Число повторений может быть дополнительно заключено в скобки, как в
pack("C[80]", @arr). Число повторений проглатывает , что многие значения из списка , когда используются со всеми типами форматов , отличных от , ,Z,b,B,h,H,@,.,x,XиP, где это означает что-то еще, описанное ниже. Использование*для количества повторов вместо числа означает использование любого количества оставшихся элементов, за исключением:aA-
@,xиX, где он эквивалентен0. -
<.>, где это означает относительно начала строки.
-
u, где это эквивалентно 1 (или 45, что здесь эквивалентно).
Можно заменить числовой счетчик повторов на шаблонную букву,заключенную в скобки,чтобы использовать длину упакованного байта шаблона в скобках для счетчика повторов.
Например, шаблон
x[L]пропускает столько байтов, сколько в упакованном long, а шаблон"$t X[$t] $t"дважды распаковывает все, что распаковывает $ t (при расширении переменной). Если шаблон в скобках содержит команды выравнивания (например,x![d]), его упакованная длина рассчитывается так, как если бы начало шаблона имело максимально возможное выравнивание.При использовании с
Z, A*в качестве счетчика повторов гарантированно добавить завершающий нулевой байт, так что результирующая строка всегда один байт длиннее , чем длина байта самого элемента.При использовании с
@счетчик повторов представляет собой смещение от начала самой внутренней()группы.При использовании с
., счетчик повторов определяет начальную позицию для вычисления смещения значения следующим образом:-
Если счетчик повторов равен
0, он относительно текущей позиции. -
Если счетчик повторений
*, смещение отсчитывается относительно начала упакованной строки. -
А если это целое числоn, смещение относительно началаnth innermost
( )группа, или до начала строки, еслиnбольше,чем на групповом уровне.
Счетчик повторов для
uинтерпретируется как максимальное количество байтов для кодирования на строку вывода, при этом 0, 1 и 2 заменены на 45. Счетчик повторов не должен превышать 65. -
-
В
a, иZтипов проглатывают только одно значение, но упаковать его в виде строки подсчета длины, заполнение нулями или пробелами в случае необходимости. При распаковке, полоски конечные пробелы и нули,Zполосок все после первой нулевой, аaвозвращает данные без зачистки вообще.AAЕсли значение для упаковки слишком велико, результат обрезается. Если он слишком длинный и указан явный счетчик,
Zупаковывает только байтов$count-1, за которыми следует нулевой байт. Таким образом,Zвсегда упаковывает завершающий ноль, кроме случаев, когда счетчик равен 0. -
Точно так же форматы
bиBупаковывают строку длиной столько бит. Каждый такой формат генерирует 1 бит результата. Обычно за ними следует счетчик повторов, напримерB8илиB64.Каждый бит результата основан на
ord($char)%2соответствующего входного символа, т. Е. На ord ($ char)% 2 . В частности, символы"0"и"1"генерируют биты 0 и 1, как и символы"00"и"01".Начиная с начала входной строки, каждый кортеж из 8 символов преобразуется в 1 символ вывода. В формате
bпервый символ кортежа из 8 определяет младший бит символа; в форматеBон определяет самый старший бит символа.Если длина входной строки не делится равномерно на 8,то оставшаяся часть упаковывается так,как если бы входная строка была заполнена нулевыми символами в конце.Аналогично при распаковке игнорируются «лишние» биты.
Если входная строка длиннее,чем необходимо,оставшиеся символы игнорируются.
A
*для подсчета повторов использует все символы поля ввода. При распаковке биты преобразуются в строку из0с и1с. -
В
hиHформаты упаковки строку , что многие nybbles (4-битовых групп, представимых в виде шестнадцатеричных цифр,"0".."9""a".."f") долго.Для каждого такого формата
packгенерирует 4 бита результата. Для неалфавитных символов результат основан на 4 младших битах входного символа, т.ord($char)%16На ord ($ char)% 16 . В частности, символы"0"и"1"генерируют нибблы 0 и 1, как и байты"00"и"01". Для символов"a".."f"и"A".."F"результат совместим с обычными шестнадцатеричными цифрами, так что"a"и"A"оба генерируют0xA==10. Используйте только эти конкретные шестнадцатеричные символы с этим форматом.Начиная с начала шаблона для
pack, каждая пара символов преобразуется в 1 символ вывода. В форматеhпервый символ пары определяет наименее значимый nybble выходного символа; в форматеHопределяет наиболее значимый ниббл.Если длина входной строки не равномерна,то она ведет себя так,как будто в ее конце присутствует нулевой символ.Аналогично,»лишние» узлы игнорируются при распаковке.
Если входная строка длиннее,чем необходимо,лишние символы игнорируются.
A
*для подсчета повторов использует все символы поля ввода. Дляunpackполубайты преобразуются в строку шестнадцатеричных цифр. -
Формат
pупаковывает указатель на строку с завершающим нулем. Вы несете ответственность за то, чтобы строка не была временным значением, поскольку потенциально она может быть освобождена до того, как вы приступите к использованию упакованного результата. ФорматPупаковывает указатель на структуру, размер которой указан длиной. Нулевой указатель создается, если соответствующее значение дляpилиPравноundef; аналогично сunpack, где нулевой указатель распаковывается вundef.Если в вашей системе странный размер указателя,то есть указатель не настолько велик,как int,и не настолько велик,как long,то упаковать или распаковать указатели в большом или маленьком байтовом порядке невозможно.Попытка сделать это вызывает исключение.
-
Символ
/template позволяет упаковывать и распаковывать последовательность элементов, в которой упакованная структура содержит количество упакованных элементов, за которым следуют сами упакованные элементы. Это полезно, когда структура, которую вы распаковываете, закодировала размеры или количество повторов для некоторых своих полей внутри самой структуры как отдельные поля.Для
packвы пишетеlength-item/sequence-item, аlength-itemописывает способ упаковки значения длины. Наиболее часто используются форматы с целочисленной упаковкой, напримерnдля строк Java,wдля ASN.1 или SNMP иNдля Sun XDR.For
pack,sequence-itemможет иметь счетчик повторов,и в этом случае в качестве аргумента используется минимум и количество доступных элементов дляlength-item. Если в нем нет счетчика повторов или используется символ «*», используется количество доступных элементов.Для
unpackиспользуется внутренний стек целочисленных аргументов, распакованных до сих пор. Вы пишете/sequence-itemи счетчик повторов получается путем вытаскивания последнего элемента из стека.sequence-itemне должно быть повторного подсчета.Ifsequence-itemотносится к строковому типу (
"A","a"или"Z"),length-itemэто длина строки,а не количество строк.При явном подсчете количества повторений для пакета,упакованная строка подстраивается под эту длину.Например:This code: gives this result: unpack("W/a", "04Gurusamy") ("Guru") unpack("a3/A A*", "007 Bond J ") (" Bond", "J") unpack("a3 x2 /A A*", "007: Bond, J.") ("Bond, J", ".") pack("n/a* w/a","hello,","world") "0006hello,05world" pack("a/W2", ord("a") .. ord("z")) "2ab"
Thelength-itemне возвращается явным образом из
unpack.Полагая,чтоlength-itemФормат письмо полезно только с
A,aилиZ. Упаковка сlength-itemиз илиZможет ввести"00"символы, которые Perl не считает законным в числовых строк.a -
Целочисленные типы
s,S,lиLмогут сопровождаться символом!модификатор, чтобы указать родные короткие или длинные. Как показано в приведенном выше примере, пустойlозначает ровно 32 бита, хотя собственнаяlongвидимая локальным компилятором C, может быть больше. В основном это проблема на 64-битных платформах. Вы можете увидеть, пользуетесь ли вы!имеет значение таким образом:printf "format s is %d, s! is %dn", length pack("s"), length pack("s!"); printf "format l is %d, l! is %dn", length pack("l"), length pack("l!");
i!иI!также допускается, но только для полноты: они идентичныiиI.Реальные размеры (в байтах)нативных шортов,ints,longs и long long long на платформе,где был собран Perl,также доступны из командной строки:
$ perl -V:{short,int,long{,long}}size shortsize='2'; intsize='4'; longsize='4'; longlongsize='8';или программно через модуль
Config:use Config; print $Config{shortsize}, "n"; print $Config{intsize}, "n"; print $Config{longsize}, "n"; print $Config{longlongsize}, "n";
$Config{longlongsize}не определен в системах без длительной поддержки. -
Целочисленные форматы
s,S,i,I,l,L,jиJпо своей сути непереносимы между процессорами и операционными системами, потому что они подчиняются встроенному байтовому порядку и порядку байтов. Например, 4-байтовое целое число 0x12345678 (305419896 десятичное число) будет изначально упорядочено (упорядочено и обработано регистрами ЦП) в байтах как0x12 0x34 0x56 0x78 0x78 0x56 0x34 0x12
В основном,процессоры Intel и VAX являются little-endian,в то время как все остальные,включая Motorola m68k/88k,PPC,Sparc,HP PA,Power и Cray,являются big-endian.Альфа и MIPS тоже могут быть:Digital/Compaq использует (хорошо,используется)их в режиме little-endian,но SGI/Cray использует их в режиме big-endian.
The namesbig-endianandlittle-endianэто комические отсылки к привычкам поедания яиц у малолетних лилипутов и биг-ендийских блефускудцев из классической сатиры Джонатана Свифта,Gulliver’s Travels. Это вошло в компьютерный жаргон через статью Дэнни Коэна «О священных войнах и призыве к миру», USC / ISI IEN 137, 1 апреля 1980 года.
Некоторые системы могут иметь еще более странные порядки байтов,такие как
0x56 0x78 0x12 0x34 0x34 0x12 0x78 0x56
Они называются средне-endian,средне-endian,смешанные-endian,или просто странные.
С помощью этого заклинания вы можете определить эндианность вашего организма:
printf("%#02x ", $_) for unpack("W*", pack L=>0x12345678);
Байтердер на платформе, на которой был построен Perl, также доступен через Config :
use Config; print "$Config{byteorder}n";
или из командной строки:
$ perl -V:byteorder
Байтеры
"1234"и"12345678"имеют прямой порядок байтов;"4321"и"87654321"имеют прямой порядок байтов. Системы с бинарными файлами с многоархитектурой будут иметь"ffff", означающее, что статическая информация не работает, необходимо использовать зондирование во время выполнения.Для переносимых упакованных целых чисел используйте либо форматы
n,N,vиV, либо модификаторы>и<, описанные непосредственно ниже. См. Также perlport . -
Также числа с плавающей запятой имеют порядок байтов. Обычно (но не всегда) это согласуется с порядком байтов от целого числа. Несмотря на то, что большинство платформ в наши дни используют двоичный формат IEEE 754, есть различия, особенно если задействованы длинные двойники. Вы можете увидеть
Configпеременныеdoublekindиlongdblkind(такжеdoublesize,longdblsize): в «добрые» значения перечислений, в отличие отbyteorder.С точки зрения переносимости лучшим вариантом, вероятно, является соблюдение 64-битных двойников IEEE 754 и согласованного порядка байтов. Другая возможность —
"%a"форматprintf«% a» ) . -
Начиная с Perl 5.10.0, целочисленные форматы и форматы с плавающей запятой, а также форматы
pиPи группы()могут сопровождаться модификаторами>или<endianness, соответственно, для обеспечения порядка байтов с прямым или обратным порядком байтов. Эти модификаторы особенно полезны, учитывая, чтоn,N,vиVне охватывают целые числа со знаком, 64-битные целые числа или значения с плавающей запятой.Вот некоторые опасения,которые следует учитывать при использовании модификатора эндианности:
-
Обмен подписанными целыми числами между разными платформами работает только тогда,когда все платформы хранят их в одном формате.Большинство платформ хранят подписанные целые числа в нотации с двумя дополнениями,поэтому обычно это не является проблемой.
-
>Или<модификаторы могут быть использованы только на плавающей точкой форматов на big- или прямой порядок байтов машин. В противном случае при попытке их использования возникает исключение. -
Установление порядка байтов с прямым или обратным порядком байтов для значений с плавающей запятой для обмена данными может работать только в том случае, если все платформы используют одно и то же двоичное представление, такое как с плавающей запятой IEEE. Даже если все платформы используют IEEE, небольшие различия все равно могут быть. Возможность использовать
>или<для значений с плавающей запятой может быть полезной, но также опасной, если вы точно не знаете, что делаете. Это не общий способ переносимого хранения значений с плавающей запятой. -
При использовании
>или<в группе()это влияет на все типы внутри группы, которые принимают модификаторы порядка байтов, включая все подгруппы. Для всех остальных типов он молча игнорируется. Вам не разрешено переопределять порядок байтов в группе, которая уже имеет суффикс модификатора порядка байтов.
-
-
Действительные числа (числа с плавающей запятой и двойные) представлены только в машинном формате. Из-за множества форматов с плавающей запятой и отсутствия для них стандартного «сетевого» представления не было сделано никаких средств для обмена. Это означает, что упакованные данные с плавающей запятой, записанные на одной машине, могут быть недоступны для чтения на другой, даже если обе используют арифметику с плавающей запятой IEEE (поскольку порядок байтов представления памяти не является частью спецификации IEEE). См. Также perlport .
Если вы знаетеexactlyто, что вы делаете, вы можете использовать модификаторы
>или<для принудительного порядка байтов с прямым или обратным порядком байтов для значений с плавающей запятой.Поскольку Perl использует внутри себя числа типа double (или long double, если настроено) для всех числовых вычислений, преобразование из double в float, а затем в double снова теряет точность, поэтому
unpack("f", pack("f", $foo)) не будет в общем равно $ foo. -
Пакетирование и распаковка могут работать в двух режимах: символьный режим (режим
C0), где упакованная строка обрабатывается для каждого символа, и байтовый режим UTF-8 ( режимU0), где упакованная строка обрабатывается в форме Unicode в кодировке UTF-8 на на побайтовой основе. Символьный режим по умолчанию , если строка формата начинается сU. Вы всегда можете переключить режим среднего формата с явнымC0илиU0в формате. Этот режим остается в силе до следующего изменения режима или до конца группы(),к которой он (напрямую) применяется.Использование
C0для получения символов Unicode при использованииU0для полученияnon-Байты юникода не обязательно очевидны. Возможно, вам нужно только первое из них:$ perl -CS -E 'say "x{3B1}x{3C9}"' | perl -CS -ne 'printf "%v04Xn", $_ for unpack("C0A*", $_)' 03B1.03C9 $ perl -CS -E 'say "x{3B1}x{3C9}"' | perl -CS -ne 'printf "%v02Xn", $_ for unpack("U0A*", $_)' CE.B1.CF.89 $ perl -CS -E 'say "x{3B1}x{3C9}"' | perl -C0 -ne 'printf "%v02Xn", $_ for unpack("C0A*", $_)' CE.B1.CF.89 $ perl -CS -E 'say "x{3B1}x{3C9}"' | perl -C0 -ne 'printf "%v02Xn", $_ for unpack("U0A*", $_)' C3.8E.C2.B1.C3.8F.C2.89
Эти примеры также показывают, что вам не следует пытаться использовать
pack/unpackвместо модуля Encode . -
Вы должны сами выполнить выравнивание или заполнение, вставив, например, достаточное количество
"x"при упаковке. Уpackandunpackнет способа узнать, куда идут символы или откуда они, поэтому они обрабатывают свой вывод и ввод как плоские последовательности символов. -
Группа
()— это вложенный ШАБЛОН, заключенный в круглые скобки. Группа может вести подсчет повторов либо в качестве постфикса, либо дляunpack, также с помощью символа/template. В каждом повторении группы позиционирование с@начинается заново с 0. Следовательно, результатpack("@1A((@2A)@3A)", qw[X Y Z])
это строка
"XYZ". -
xиXпринимают!модификатор, чтобы действовать как команды выравнивания: они переходят вперед или назад к ближайшей позиции, выровненной по множеству символовcount. Например, чтобыpackилиunpackструктуру C, напримерstruct { char c; double d; char cc[2]; }
может потребоваться использовать шаблон
c x![d] d c[2]. Это предполагает, что двойные должны быть выровнены по размеру double.Для команд выравнивания
count0 эквивалентенcount1; оба не работают. -
n,N,vиVпринимают!модификатор для представления 16- / 32-разрядных целых чисел со знаком в порядке обратного / обратного порядка байтов. Это переносимо только тогда, когда все платформы, совместно использующие упакованные данные, используют одно и то же двоичное представление для целых чисел со знаком; например, когда все платформы используют представление с дополнением до двух. -
Комментарии могут быть вставлены в ШАБЛОН с помощью символа
#до конца строки. Пробел может отделять коды пакетов друг от друга, но модификаторы и счетчики повторов должны следовать немедленно. Разбиение сложных шаблонов на отдельные построчные компоненты, снабженные соответствующими аннотациями, может сделать столько же для улучшения читабельности и удобства обслуживания форматов упаковки / распаковки, сколько/xможет для сложных сопоставлений с образцом. -
Если ШАБЛОН требует больше аргументов , чем
packзадан,packпредполагает дополнительные""аргументы. Если для TEMPLATE требуется меньше аргументов, чем указано, дополнительные аргументы игнорируются. -
Попытка упаковать специальные значения с плавающей запятой
InfиNaN(бесконечность, также отрицательные и не числовые) в упакованные целочисленные значения (например,"L") является фатальной ошибкой. Причина этого в том, что для этих специальных значений просто не существует разумного преобразования в целые числа.
Examples:
$foo = pack("WWWW",65,66,67,68); $foo = pack("W4",65,66,67,68); $foo = pack("W4",0x24b6,0x24b7,0x24b8,0x24b9); $foo = pack("U4",0x24b6,0x24b7,0x24b8,0x24b9); $foo = pack("C0U4",0x24b6,0x24b7,0x24b8,0x24b9); $foo = pack("ccxxcc",65,66,67,68); $foo = pack("s2",1,2); $foo = pack("a4","abcd","x","y","z"); $foo = pack("aaaa","abcd","x","y","z"); $foo = pack("a14","abcdefg"); $foo = pack("i9pl", gmtime); $utmp_template = "Z8 Z8 Z16 L"; $utmp = pack($utmp_template, @utmp1); @utmp2 = unpack($utmp_template, $utmp); sub bintodec { unpack("N", pack("B32", substr("0" x 32 . shift, -32))); } $foo = pack('sx2l', 12, 34); $bar = pack('s@4l', 12, 34); $baz = pack('s.l', 12, 4, 34); $foo = pack('nN', 42, 4711); $foo = pack('S>L>', 42, 4711); $foo = pack('s<l<', -42, 4711); $foo = pack('(sl)<', -42, 4711);
Этот же шаблон обычно можно использовать и при unpack .
Объявляет BLOCK или остальную часть единицы компиляции как находящуюся в заданном пространстве имен. Областью действия объявления пакета является либо предоставленный код BLOCK, либо, при отсутствии BLOCK, от самого объявления до конца текущей области (окружающий блок, файл или eval ). То есть формы без BLOCK работают до конца текущей области, точно так же, как my , state и our операторы. Все неквалифицированные динамические идентификаторы в этой области будут находиться в заданном пространстве имен, за исключением случаев, когда они переопределены другим объявлением package или когда они являются одним из специальных идентификаторов, которые соответствуют main:: , например STDOUT , ARGV , ENV и переменные пунктуации.
Оператор package влияет только на динамические переменные, включая те, которые вы использовали local , ноnotпеременные с лексической областью видимости, которые создаются с помощью my , state или our . Обычно это будет первое объявление в файле, включенном с помощью require или use . Вы можете переключиться на пакет более чем в одном месте, так как это определяет только то, какую таблицу символов по умолчанию компилятор использует для остальной части этого блока. Вы можете ссылаться на идентификаторы в пакетах, отличных от текущего, добавляя к идентификатору имя пакета и двойное двоеточие, как в $SomePack::var или ThatPack::INPUT_HANDLE . Если имя пакета не указано, подразумевается main То есть $::sail эквивалентно $main::sail .(так же как и $main'sail , все еще встречающийся в древнем коде, в основном из Perl 4).
Если указана версия VERSION, package устанавливает переменную $VERSION в данном пространстве имен в объект версии с предоставленной версией VERSION. VERSION должен быть номером версии в «строгом» стиле, как определено модулем версии : положительное десятичное число (целое или десятичная дробь) без возведения в степень или же десятичная v-строка с точками с ведущим символом «v» и не менее трех составные части. Вы должны установить $VERSION только один раз для каждого пакета.
См. «Пакеты» в perlmod для получения дополнительной информации о пакетах, модулях и классах. См. Perlsub, чтобы узнать о других проблемах с областью видимости.
Специальный токен,возвращающий имя пакета,в котором он находится.
Открывает пару подключенных каналов, как соответствующий системный вызов. Обратите внимание, что если вы настроили цикл конвейерных процессов, может возникнуть взаимоблокировка, если вы не будете очень осторожны. Кроме того, обратите внимание, что каналы Perl используют буферизацию ввода-вывода, поэтому вам может потребоваться установить $| чтобы очищать WRITEHANDLE после каждой команды, в зависимости от приложения.
Возвращается к успеху.
См. IPC::Open2 , IPC::Open3 и «Двунаправленная связь с другим процессом» в perlipc для примеров таких вещей.
В системах, которые поддерживают флаг закрытия при выполнении для файлов, этот флаг устанавливается для всех недавно открытых файловых дескрипторов, у которых нет fileno higherчем текущее значение $^F (по умолчанию 2 для STDERR ). Смотрите «$ ^ F» в perlvar .
Всплывает и возвращает последнее значение массива,укорачивая массив на один элемент.
Возвращает неопределенное значение, если массив пуст, хотя это может произойти и в другое время. Если ARRAY опущен, извлекает массив @ARGV в основной программе, но массив @_ в подпрограммах, как и shift .
Начиная с Perl 5.14, экспериментальная функция позволяла pop принимать скалярное выражение. Этот эксперимент был признан неудачным и был удален с версии Perl 5.24.
Возвращает смещение того места, где последний поиск m//g остановился для рассматриваемой переменной ( $_ используется, когда переменная не указана). Это смещение указывается в символах, если только не действует прагма use bytes (больше не рекомендуется) , и в этом случае смещение указывается в байтах. Обратите внимание, что 0 является допустимым смещением совпадения. undef указывает, что позиция поиска сбрасывается (обычно из-за неудачного сопоставления, но также может быть связано с тем, что совпадение еще не выполнялось для скаляра).
pos напрямую обращается к местоположению, используемому механизмом регулярных выражений для хранения смещения, поэтому присвоение pos изменит это смещение и, таким образом, также повлияет наутверждение нулевой ширины G в регулярных выражениях.Оба эти эффекта действуют для следующего совпадения, поэтому вы не можете повлиять на позицию с помощью pos во время текущего совпадения, например, в (?{pos() = 5}) или s//pos() = 5/e .
Установка pos также сбрасываетс нулевой длинойфлаг, описанный в разделе «Повторяющиеся шаблоны, соответствующие подстроке нулевой длины» в perlre .
Поскольку неудачное совпадение m//gc не сбрасывает смещение, возврат от pos в этом случае также не изменится. См. perlre и perlop .
Выводит строку или список строк. Возвращает true в случае успеха. FILEHANDLE может быть скалярной переменной, содержащей имя или ссылку на дескриптор файла, таким образом вводя один уровень косвенности. (ПРИМЕЧАНИЕ. Если FILEHANDLE является переменной, а следующий токен является термином, он может быть неправильно истолкован как оператор, если вы не вставите + + не заключите аргументы в круглые скобки.) Если FILEHANDLE опущен, печатается до последнего выбранного (см. select ) выходной дескриптор. Если LIST не указан, выводит $_ в текущий выбранный дескриптор вывода. Чтобы использовать только FILEHANDLE для вывода содержимого $_ , вы должны использовать простой дескриптор файла, такой как FH , а не косвенный, такой как $fh . Чтобы установить дескриптор вывода по умолчанию на что-то отличное от STDOUT, используйте операцию выбора.
Текущее значение $, (если есть) печатается между каждым элементом LIST. Текущее значение $ (если оно есть) выводится после того, как будет напечатан весь список LIST. Поскольку print принимает LIST, все в LIST оценивается в контексте списка, включая любые подпрограммы, чьи списки возврата вы передаете в print . Будьте осторожны, чтобы не ставить после ключевого слова print левую круглую скобку, если вы не хотите, чтобы соответствующая правая круглая скобка завершала аргументы для печати; заключайте в круглые скобки все аргументы (или вставляйте + , но это выглядит не так хорошо).
Если вы храните дескрипторы в массиве или хэше,или вообще когда вы используете какое-либо выражение,более сложное,чем дескриптор пустого слова или простую,не подписанную скалярную переменную,чтобы получить ее,вам придется использовать блок,возвращающий значение дескриптора,и в этом случае СПИСОК не может быть опущен:
print { $files[$i] } "stuffn"; print { $OK ? *STDOUT : *STDERR } "stuffn";
Печать в закрытый канал или сокет генерирует сигнал SIGPIPE. См. Perlipc для получения дополнительной информации об обработке сигналов.
Эквивалентен print FILEHANDLE sprintf(FORMAT, LIST) , за исключением того, что $ (разделитель выходной записи) не добавляется. FORMAT и LIST фактически анализируются как единый список. Первый аргумент списка будет интерпретирован как формат printf . Это означает, что printf(@_) будет использовать $_[0] в качестве формата. См. Sprintf для объяснения аргумента формата. Если use locale (включая use locale ':not_characters' ) и был вызван POSIX::setlocale , символ, используемый для десятичного разделителя в форматированных числах с плавающей запятой, зависит от LC_NUMERIC настройка локали. См. Perllocale и POSIX .
По историческим причинам, если вы опускаете список, в качестве формата используется $_ ;чтобы использовать FILEHANDLE без списка, вы должны использовать простой дескриптор файла, такой как FH , а не косвенный, такой как $fh . Однако это редко будет делать то, что вы хотите; если $_ содержит коды форматирования, они будут заменены пустой строкой и будет выдано предупреждение, если предупреждения включены. Просто используйте print , если хотите распечатать содержимое $_ .
Не попадайтесь в ловушку использования printf, printf достаточно будет простой print Печать более эффективна и менее подвержена ошибкам print
Возвращает прототип функции в виде строки (или undef , если у функции нет прототипа). FUNCTION — это ссылка или имя функции, прототип которой вы хотите получить. Если ФУНКЦИЯ опущена, используется $_ .
Если FUNCTION — это строка, начинающаяся с CORE:: , оставшаяся часть используется как имя встроенной функции Perl. Если встроенные аргументы не могут быть адекватно выражены прототипом (таким как system ), prototype возвращает undef , потому что встроенная функция на самом деле не ведет себя как функция Perl. В противном случае возвращается строка, описывающая эквивалентный прототип.
Рассматривает ARRAY как стек,добавляя значения СПИСКА в конце ARRAY.Длина АРРЕЯ увеличивается на длину СПИСКА.Имеет тот же эффект,что и
for my $value (LIST) { $ARRAY[++$#ARRAY] = $value; }
но более эффективен. Возвращает количество элементов в массиве после завершения push .
Начиная с Perl 5.14, экспериментальная функция позволяла push принимать скалярное выражение. Этот эксперимент был признан неудачным и был удален в Perl 5.24.
Обобщенные цитаты. См. «Операторы, подобные кавычкам» в perlop .
Цитата, похожая на регулярное выражение. См. «Операторы, похожие на кавычки в регулярных выражениях» в perlop .
Возвращает значение EXPR со всеми символами ASCII, отличными от «слов», через обратную косую черту. (То есть, всем символам ASCII, не совпадающим с /[A-Za-z_0-9]/ , будет предшествовать обратная косая черта в возвращаемой строке, независимо от каких-либо настроек локали.) Это внутренняя функция, реализующая экранирование Q в двойном формате. строки в кавычках. (См. Ниже поведение в кодовых точках, отличных от ASCII.)
Если EXPR опущен, используется $_ .
quotemeta (и Q … E ) полезны при интерполяции строк в регулярные выражения, потому что по умолчанию интерполированная переменная будет считаться мини-регулярным выражением. Например:
my $sentence = 'The quick brown fox jumped over the lazy dog'; my $substring = 'quick.*?fox'; $sentence =~ s{$substring}{big bad wolf};
Превратит $sentence в 'The big bad wolf jumped over...' .
С другой стороны:
my $sentence = 'The quick brown fox jumped over the lazy dog'; my $substring = 'quick.*?fox'; $sentence =~ s{Q$substringE}{big bad wolf};
Or:
my $sentence = 'The quick brown fox jumped over the lazy dog'; my $substring = 'quick.*?fox'; my $quoted_substring = quotemeta($substring); $sentence =~ s{$quoted_substring}{big bad wolf};
Оба оставят предложение как есть. Обычно при приеме строкового ввода от пользователя необходимо использовать quotemeta или Q .
Помните, что если вы поместите буквальную обратную косую черту (те, которые не находятся внутри интерполированных переменных) между Q и E , интерполяция обратной косой черты в двойных кавычках может привести к запутанным результатам. если тыneedчтобы использовать обратную косую черту внутри Q...E , обратитесь к «Кровавым деталям разбора конструкций в кавычках» в perlop .
Поскольку в результате "Q STRING E" все метасимволы заключены в кавычки, нет возможности вставить литерал $ или @ внутри пары QE Если защищено , $ будет заключено в кавычки, чтобы стать "\$" ; в противном случае он интерпретируется как начало интерполированного скаляра.
В Perl v5.14 все не-ASCII-символы цитируются в строках,не кодированных в кодировке UTF-8,но не цитируются в строках в кодировке UTF-8.
Начиная с версии Perl v5.16,в Perl принята стратегия цитирования символов,не относящихся к ASCII;цитирование символов ASCII не изменяется.
Также неизменным является цитирование строк, отличных от UTF-8, когда они выходят за рамки функции use feature 'unicode_strings' , которая заключается в заключении в кавычки всех символов в верхнем диапазоне Latin1. Это обеспечивает полную обратную совместимость для старых программ, не использующих Unicode. (Обратите внимание, что unicode_strings автоматически включается в рамках use v5.12 или выше.)
В пределах области use locale все кодовые точки, отличные от ASCII Latin1, заключаются в кавычки, независимо от того, закодирована ли строка как UTF-8 или нет. Как упоминалось выше, языковой стандарт не влияет на цитирование символов диапазона ASCII. Это защищает от тех языков, в которых используются такие символы, как "|" считаются символами слова.
В противном случае Perl цитирует символы, отличные от ASCII, используя адаптацию Unicode (см. Https://www.unicode.org/reports/tr31/ ). В кавычках указаны только те кодовые точки, которые имеют любое из свойств Unicode: Pattern_Syntax, Pattern_White_Space, White_Space, Default_Ignorable_Code_Point или General_Category = Control.
Из этих свойств два важных-Pattern_Syntax и Pattern_White_Space.Они были установлены Unicode именно для этой цели,чтобы решить,какие символы в шаблоне регулярных выражений должны быть кавычками.Ни один символ,который может находиться в идентификаторе,не обладает этими свойствами.
Perl обещает, что если мы когда-нибудь добавим метасимволы шаблона регулярного выражения к дюжине уже определенных ( | ( ) [ { ^ $ * + ? . ), Мы будем использовать только те, которые имеют свойство Pattern_Syntax. Perl также обещает, что если мы когда-нибудь добавим символы, которые считаются пробелами в регулярных выражениях (в настоящее время в основном затрагиваются /x ), все они будут иметь свойство Pattern_White_Space.
Юникод обещает,что набор точек кода,которые имеют эти два свойства,никогда не изменится,поэтому то,что не цитируется в версии v5.16,никогда не нужно будет цитировать в любом будущем релизе Perl.(Не все точки кода,которые соответствуют синтаксису Pattern_Syntax,на самом деле имеют назначенные им символы;так что есть место для роста,но они цитируются независимо от того,назначены они или нет.Perl,конечно,никогда бы не использовал неприсвоенную кодовую точку в качестве фактического метахарафа).
Цитирование символов,которые имеют остальные 3 свойства,сделано для повышения читабельности регулярного выражения,а не потому,что их действительно нужно цитировать для целей регулярного выражения (символы со свойством White_Space,скорее всего,будут неотличимы на странице или экране от символов со свойством Pattern_White_Space;а два других свойства содержат непечатающиеся символы).
Возвращает случайное дробное число, большее или равное 0 и меньшее, чем значение EXPR. (EXPR должен быть положительным.) Если EXPR опущен, используется значение 1 .В настоящее время EXPR со значением 0 также используется в специальном регистре как 1 (это не было документировано до Perl 5.8.0 и может быть изменено в будущих версиях Perl). Автоматически вызывает srand , если srand еще не был вызван. См. также srand .
Примените int к значению, возвращаемому rand , если вам нужны случайные целые числа вместо случайных дробных чисел. Например,
int(rand(10))
возвращает случайное целое число от 0 до 9 включительно.
(Примечание: если ваша функция rand постоянно возвращает слишком большие или слишком маленькие числа, то ваша версия Perl, вероятно, была скомпилирована с неправильным числом RANDBITS.)
rand не является криптографически безопасным. Вы не должны полагаться на него в ситуациях, чувствительных к безопасности. На момент написания этой статьи ряд сторонних модулей CPAN предлагают генераторы случайных чисел, предназначенные их авторами для обеспечения криптографической безопасности, в том числе:Data::Entropy,Crypt::Random,Math::Random::SecureиMath:: Истиннослучайный.
Попытки прочитать ЛЕНГТcharactersданных в переменную SCALAR из указанного FILEHANDLE. Возвращает количество фактически прочитанных символов, 0 в конце файла или undef, если произошла ошибка (в последнем случае также устанавливается $! ). SCALAR будет увеличиваться или уменьшаться так, чтобы последний фактически прочитанный символ был последним символом скаляра после чтения.
СМЕЩЕНИЕ может быть указано для помещения считанных данных в какое-либо место в строке, кроме начала. Отрицательное СМЕЩЕНИЕ указывает размещение такого количества символов, считая в обратном порядке от конца строки. Положительное значение OFFSET, превышающее длину SCALAR, приводит к тому, что строка дополняется до требуемого размера байтами "" перед добавлением результата чтения.
Вызов реализован в терминах функции библиотеки fread (3) Perl или вашей системы через слои PerlIO, примененные к дескриптору. Чтобы получить системный вызов true read (2) , см. Sysread .
Note thecharacters: в зависимости от состояния дескриптора файла считываются (8-битные) байты или символы. По умолчанию все дескрипторы файлов работают с байтами, но, например, если дескриптор файла был открыт с помощью уровня ввода-вывода :utf8 (см. open и open ), ввод-вывод будет работать с символами Unicode в кодировке UTF8, а не с байтов. Аналогично для уровня :encoding : в этом случае можно прочитать практически любые символы.
Возвращает следующую запись каталога для каталога, открытого opendir . Если используется в контексте списка, возвращает все остальные записи в каталоге. Если записей больше нет, возвращает неопределенное значение в скалярном контексте и пустой список в контексте списка.
Если вы планируете тестировать возвращаемые значения из readdir readdir вам лучше добавить соответствующий каталог. В противном случае, из-за того, что мы не выполнили там chdir , тестировался бы не тот файл.
opendir(my $dh, $some_dir) || die "Can't opendir $some_dir: $!"; my @dots = grep { /^./ && -f "$some_dir/$_" } readdir($dh); closedir $dh;
Начиная с Perl 5.12 вы можете использовать голый readdir в цикле while , который будет устанавливать $_ на каждой итерации. Если либо выражение readdir , либо явное присвоение выражения readdir скаляру используется в качестве условия while / for , то условие фактически проверяет определенность значения выражения, а не его обычное значение истинности.
opendir(my $dh, $some_dir) || die "Can't open $some_dir: $!"; while (readdir $dh) { print "$some_dir/$_n"; } closedir $dh;
Чтобы избежать путаницы потенциальных пользователей вашего кода,которые работают с более ранними версиями Perl,с загадочными сбоями,поместите такие вещи в верхнюю часть файла,чтобы показать,что ваш код будет работать.onlyна Перлс недавнего винтажа:
use v5.12;
Читает из дескриптора файла, typeglob которого содержится в EXPR (или из *ARGV , если EXPR не указан). В скалярном контексте каждый вызов считывает и возвращает следующую строку до тех пор, пока не будет достигнут конец файла, после чего последующий вызов возвращает undef . В контексте списка читает до тех пор, пока не будет достигнут конец файла, и возвращает список строк. Обратите внимание, что используемое здесь понятие «строка» — это то, что вы, возможно, определили с помощью $/ (или $INPUT_RECORD_SEPARATOR на английском языке ). См. «$/» в perlvar .
Когда $/ установлено в undef , когда readline находится в скалярном контексте (т. е. в режиме файловой выборки) и когда читается пустой файл, он возвращает '' в первый раз, а затем undef .
Это внутренняя функция, реализующая оператор <EXPR> , но вы можете использовать ее напрямую. Оператор <EXPR> более подробно обсуждается в разделе «Операторы ввода-вывода» в perlop .
my $line = <STDIN>; my $line = readline(STDIN);
Если readline обнаруживает ошибку операционной системы, $! будет установлено с соответствующим сообщением об ошибке. Может быть полезно проверить $! когда вы читаете из дескрипторов файлов, которым не доверяете, таких как tty или сокет. Следующий пример использует операторную форму readline и умирает, если результат не определен.
while ( ! eof($fh) ) { defined( $_ = readline $fh ) or die "readline failed: $!"; ... }
Обратите внимание, что вы не можете обрабатывать ошибки readline таким образом с помощью файлового дескриптора ARGV . В этом случае вам придется открывать каждый элемент @ARGV самостоятельно, так как eof обрабатывает ARGV по-разному.
foreach my $arg (@ARGV) { open(my $fh, $arg) or warn "Can't open $arg: $!"; while ( ! eof($fh) ) { defined( $_ = readline $fh ) or die "readline failed for $arg: $!"; ... } }
Подобно оператору <EXPR> , если выражение readline используется как условие цикла while или for , то оно будет неявно присвоено $_ . Если в качестве условия while / for используется выражение readline или явное присвоение выражения readline скаляру , то условие фактически проверяет определенность значения выражения, а не его регулярное значение истинности.
Возвращает значение символической ссылки, если символические ссылки реализованы. В противном случае возникает исключение. В случае системной ошибки возвращает неопределенное значение и устанавливает $! (эррно). Если EXPR опущен, используется $_ .
Проблемы с переносимостью: «readlink» в perlport .
EXPR выполняется как системная команда. Возвращается собранный стандартный вывод команды. В скалярном контексте он возвращается как одна (потенциально многострочная) строка. В контексте списка возвращает список строк (однако вы определили строки с помощью $/ (или $INPUT_RECORD_SEPARATOR на английском языке )). Это внутренняя функция, реализующая оператор qx/EXPR/ , но вы можете использовать ее напрямую. Оператор qx/EXPR/ более подробно обсуждается в « qx/STRING/ » в perlop . Если EXPR опущен, используется $_ .
Получает сообщение о сокете. Пытается получить LENGTH символов данных в переменную SCALAR из указанного дескриптора файла SOCKET. SCALAR будет увеличиваться или уменьшаться до фактически считываемой длины. Принимает те же флаги, что и одноименный системный вызов. Возвращает адрес отправителя, если протокол СОКЕТА поддерживает это; в противном случае возвращает пустую строку. В случае ошибки возвращает неопределенное значение. Этот вызов фактически реализован в терминах системного вызова recvfrom (2) . См. «UDP: передача сообщений» в perlipc для примеров.
Обратите внимание, что если сокет был помечен как :utf8 , recv вызовет исключение. :encoding(...) слой неявно вводит :utf8 слой. См. binmode .
Команда redo перезапускает блок цикла без повторной оценки условного выражения. Блок continue , если он есть, не выполняется. Если LABEL опущен, команда относится к самому внутреннему охватывающему циклу. Форма redo EXPR , доступная, начиная с Perl 5.18.0, позволяет вычислять имя метки во время выполнения, в остальном она идентична redo LABEL . Программы, которые хотят солгать себе о том, что только что было введено, обычно используют эту команду:
LINE: while (<STDIN>) { while (s|({.*}.*){.*}|$1 |) {} s|{.*}| |; if (s|{.*| |) { my $front = $_; while (<STDIN>) { if (/}/) { s|^|$front{|; redo LINE; } } } print; }
redo не может возвращать значение из блока, который обычно возвращает значение, например eval {} , sub {} или do {} . Он будет выполнять свое поведение управления потоком, которое исключает любое возвращаемое значение. Его не следует использовать для выхода из grep или map .
Обратите внимание, что блок сам по себе семантически идентичен циклу, который выполняется один раз. Таким образом redo внутри такого блока фактически превратит его в циклическую конструкцию.
См. также continue для иллюстрации того, как работают last , next и redo .
В отличие от большинства именованных операторов, это имеет тот же приоритет, что и присваивание. На него также не распространяется правило похожести на функцию, поэтому redo ("foo")."bar" приведет к тому, что bar станет частью аргумента redo .
Проверяет значение EXPR, ожидая, что оно будет ссылкой, и возвращает строку, содержащую информацию о ссылке и типе референта. Если EXPR не указан, будет использоваться $_ .
Если операнд не является ссылкой, будет возвращена пустая строка. Только в этом случае будет возвращена пустая строка. ref часто бывает полезно просто проверить, является ли значение ссылкой, что можно сделать, сравнив результат с пустой строкой. Распространенная ошибка — использовать результат ref напрямую как значение истинности: это идет не так, потому что для ссылки может быть возвращен 0 (который является ложным).
Если операнд является ссылкой на благословенный объект, то будет возвращено имя класса, в который был благословлен референт. ref не заботится о физическом типе референта; благословение превалирует над такими заботами. Помните, что точное сравнение результатов ref с именем класса не выполняет тест на членство в классе: члены класса также включают объекты, благословленные в подклассы, для которых ref вернет имя подкласса. Также помните, что имена классов могут конфликтовать со встроенными именами типов (описанными ниже).
Если операнд является ссылкой на объект без благословения, то возвращаемое значение указывает тип объекта. Если нежелательный референт не является скаляром, то возвращаемое значение будет одной из строк ARRAY , HASH , CODE , FORMAT или IO , указывающей только, какой это тип объекта. Если референт без благословения является скаляром, то возвращаемое значение будет одной из строк SCALAR , VSTRING , REF , GLOB , LVALUE или REGEXP , в зависимости от типа значения, которое скаляр имеет в настоящее время. Но обратите внимание, что qr// скаляры созданы уже благословенными, поэтому ref qr/.../ скорее всего вернет Regexp . Помните, что эти встроенные имена типов также могут использоваться в качестве имен классов, поэтому ref , возвращающий одно из этих имен, не означает однозначно, что референт относится к тому типу, к которому относится имя.
Неоднозначность между именами встроенных типов и именами классов значительно ограничивает полезность ref . Для однозначной информации используйте Scalar::Util::blessed() для информации о благословении и Scalar::Util::reftype() для информации о физических типах. Используйте метод isa для проверки членства в классе, хотя перед попыткой вызова метода необходимо убедиться в благополучии. В качестве альтернативы, оператор может проверить членство в классе, не проверяя предварительно благословление.
См. Также perlref и perlobj .
Изменяет имя файла; существующий файл NEWNAME будет стерт. Возвращает истину в случае успеха; при неудаче возвращает false и устанавливает $! .
Поведение этой функции сильно варьируется в зависимости от реализации вашей системы.Например,она обычно не будет работать через границы файловой системы,даже если системаmvкоманда иногда компенсирует это. Другие ограничения включают, работает ли он с каталогами, открытыми файлами или уже существующими файлами. За подробностями обращайтесь к perlport и на странице руководства rename (2) или в эквивалентной системной документации.
Для независимой от платформы функции move посмотрите модуль File :: Copy .
Проблемы с переносимостью: «переименовать» в perlport .
Требует версию Perl, указанную в VERSION, или требует некоторой семантики, указанной в EXPR или $_ если EXPR не указан.
VERSION может быть либо литералом, например v5.24.1, который будет сравниваться с $^V (или $PERL_VERSION на английском ), либо числовым аргументом вида 5.024001, который будет сравниваться с $] . Исключение возникает, если VERSION больше, чем версия текущего интерпретатора Perl. Сравните с use , который может выполнять аналогичную проверку во время компиляции.
Указания VERSION в качестве числового аргумента вида 5.024001 следует избегать,так как это более старый и менее читабельный синтаксис по сравнению с v5.24.1.До версии perl 5.8.0 (выпущенной в 2002 году)более многословная числовая форма была единственным поддерживаемым синтаксисом,поэтому вы можете встретить ее в старом коде.
require v5.24.1; require 5.24.1; require 5.024_001; with perl 5.6
В противном случае require требует , чтобы файл библиотеки был включен, если он еще не был включен. Файл подключается с помощью механизма do-FILE, который, по сути, является разновидностью eval с той оговоркой, что лексические переменные в вызывающем скрипте будут невидимы для подключаемого кода. Если бы он был реализован на чистом Perl, его семантика была бы примерно такой:
use Carp 'croak'; use version; sub require { my ($filename) = @_; if ( my $version = eval { version->parse($filename) } ) { if ( $version > $^V ) { my $vn = $version->normal; croak "Perl $vn required--this is only $^V, stopped"; } return 1; } if (exists $INC{$filename}) { return 1 if $INC{$filename}; croak "Compilation failed in require"; } foreach $prefix (@INC) { if (ref($prefix)) { } my $realfilename = "$prefix/$filename"; next if ! -e $realfilename || -d _ || -b _; $INC{$filename} = $realfilename; my $result = do($realfilename); if (!defined $result) { $INC{$filename} = undef; croak $@ ? "$@Compilation failed in require" : "Can't locate $filename: $!n"; } if (!$result) { delete $INC{$filename}; croak "$filename did not return true value"; } $! = 0; return $result; } croak "Can't locate $filename in @INC ..."; }
Обратите внимание,что файл не будет включен дважды под одним и тем же именем.
Файл должен возвращать истину в качестве последнего оператора, чтобы указать на успешное выполнение любого кода инициализации, поэтому обычно такой файл завершается цифрой 1; если вы не уверены, что в противном случае он вернет true. Но лучше просто поставить 1; , на случай, если вы добавите больше заявлений.
Если EXPR — пустое слово, require предполагает, что.pmextension и заменяет :: на / в имени файла для вас, чтобы упростить загрузку стандартных модулей. Эта форма загрузки модулей не рискует изменить ваше пространство имен, однако автоматически оживит тайник для требуемого модуля.
Другими словами,если ты попробуешь это:
require Foo::Bar;
Функция require фактически будет искатьFoo/Bar.pmфайл в каталогах, указанных в массиве @INC , и он автоматически оживит Foo::Bar:: stash во время компиляции.
Но если ты попробуешь это:
my $class = 'Foo::Bar'; require $class; require "Foo::Bar";
Функция require будет искатьFoo::Barфайл в массиве @INC и будет жаловаться на то, что не нашелFoo::Barтам.В этом случае вы можете сделать:
eval "require $class";
или вы можете сделать
require "Foo/Bar.pm";
Ни одна из этих форм не будет автовивировать какие-либо тайники во время компиляции и будет иметь эффект только во время выполнения.
Теперь, когда вы понимаете, как require ищет файлы с аргументом bareword, за кулисами работает небольшая дополнительная функциональность. Прежде чем require ищет.pmрасширение,он сначала будет искать похожее имя файла с расширением.pmcрасширение.Если этот файл найден,он будет загружен вместо любого файла,заканчивающегося на.pmрасширение. Это относится как к явному require "Foo/Bar.pm"; form и require Foo::Bar; форма.
Вы также можете вставить перехватчики в средство импорта, поместив код Perl непосредственно в массив @INC . Есть три формы ловушек: ссылки на подпрограммы, ссылки на массивы и благословенные объекты.
Ссылки на подпрограммы — самый простой случай. Когда система включения проходит через @INC и встречает подпрограмму, эта подпрограмма вызывается с двумя параметрами: первый — это ссылка на себя, а второй — имя включаемого файла (например,Foo/Bar.pm). Подпрограмма должна либо ничего не возвращать, либо список до четырех значений в следующем порядке:
-
Ссылка на скаляр,содержащий любой исходный код для подготовки к выводу файла или генератора.
-
Ручка файлов,из которой будет читаться файл.
-
Ссылка на подпрограмму. Если нет дескриптора файла (предыдущий элемент), то ожидается, что эта подпрограмма будет генерировать одну строку исходного кода за вызов, записывая строку в
$_и возвращая 1, а затем, наконец, в конце файла, возвращая 0. Если есть дескриптор файла, затем будет вызвана подпрограмма, которая будет действовать как простой исходный фильтр, со строкой, прочитанной в$_. Опять же, возвращайте 1 для каждой допустимой строки и 0 после того, как были возвращены все строки. По историческим причинам подпрограмма получит бессмысленный аргумент (фактически всегда нулевое числовое значение) как$_[0]. -
Необязательное состояние подпрограммы. Состояние передается как
$_[1].
Если возвращается пустой список, undef или ничего, что соответствует первым трем приведенным выше значениям, то require просматривает оставшиеся элементы @INC . Обратите внимание, что этот дескриптор файла должен быть реальным дескриптором файла (строго typeglob или ссылкой на typeglob, благословенным или неблагословенным); связанные файловые дескрипторы будут игнорироваться, и обработка на этом остановится.
Если крюк является ссылкой на массив,то его первым элементом должна быть ссылка на подпрограмму.Эта подпрограмма вызывается,как описано выше,но первым параметром является ссылка на массив.Это позволяет косвенно передавать аргументы в подпрограмму.
Другими словами,ты можешь писать:
push @INC, &my_sub; sub my_sub { my ($coderef, $filename) = @_; ... }
or:
push @INC, [ &my_sub, $x, $y, ... ]; sub my_sub { my ($arrayref, $filename) = @_; my (undef, @parameters) = @$arrayref; ... }
Если ловушка является объектом, она должна предоставлять метод INC , который будет вызываться, как указано выше, причем первым параметром является сам объект. (Обратите внимание, что вы должны полностью указать имя подпрограммы, поскольку неквалифицированный INC всегда принудительно помещается в main пакета .) Вот типичный макет кода:
package Foo; sub new { ... } sub Foo::INC { my ($self, $filename) = @_; ... } push @INC, Foo->new(...);
Этим перехватчикам также разрешено устанавливать запись %INC соответствующую загруженным файлам. Смотрите «% INC» в perlvar .
Чтобы узнать о еще более мощных средствах импорта, смотрите use и perlmod .
Обычно используется в блоке continue в конце цикла для очистки переменных и сброса m?pattern? поиски, чтобы они снова работали. Выражение интерпретируется как список одиночных символов (дефисы разрешены для диапазонов). Все переменные (скаляры, массивы и хэши) в текущем пакете, начинающиеся с одной из этих букв, возвращаются в исходное состояние. Если выражение опущено, поиск с одним совпадением ( m?pattern? ) сбрасывается для повторного совпадения. Только сбрасывает переменные или выполняет поиск в текущем пакете. Всегда возвращает 1. Примеры:
reset 'X'; reset 'a-z'; reset;
Сброс "A-Z" не рекомендуется, потому что вы уничтожите свои @ARGV и @INC и хэш %ENV .
Сбрасывает только переменные пакета; лексические переменные не затрагиваются, но они все равно очищаются при выходе из области видимости, поэтому вы, вероятно, захотите использовать их вместо этого. Смотрите my .
Возвращает из подпрограммы, eval , do FILE , блока sort или блока eval регулярного выражения (но не блока grep , map или do BLOCK ) со значением, указанным в EXPR. Оценка EXPR может быть в контексте списка, скаляра или пустоты, в зависимости от того, как будет использоваться возвращаемое значение, и контекст может меняться от одного выполнения к другому (см. wantarray ). Если EXPR не задан, возвращает пустой список в контексте списка, неопределенное значение в скалярном контексте и (конечно) вообще ничего в пустом контексте.
(При отсутствии явного return подпрограмма eval или do FILE автоматически возвращает значение последнего вычисленного выражения.)
В отличие от большинства именованных операторов, это также освобождено от правила похожести на функцию, поэтому return ("foo")."bar" приведет к тому "bar" return аргумента .
В контексте списка возвращает значение списка,состоящего из элементов СПИСКА в обратном порядке.В скалярном контексте конкатенует элементы списка LIST и возвращает строковое значение со всеми символами в обратном порядке.
print join(", ", reverse "world", "Hello"); print scalar reverse "dlrow ,", "olleH";
Используется без аргументов в скалярном контексте, reverse переворачивает $_ .
$_ = "dlrow ,olleH"; print reverse; print scalar reverse;
Обратите внимание, что обращение массива к самому себе (как в @a = reverse @a ) по возможности сохраняет несуществующие элементы; т.е. для немагических массивов или для связанных массивов с методами EXISTS и DELETE .
Этот оператор также удобен для инвертирования хэша,хотя есть некоторые предостережения.Если значение дублируется в исходном хэше,то только одно из них может быть представлено в виде ключа в перевернутом хэше.Кроме того,необходимо развернуть один хэш и построить новый,что может занять некоторое время на большом хэше,например,из DBM файла.
my %by_name = reverse %by_address;
Устанавливает текущую позицию в начало каталога для подпрограммы readdir на DIRHANDLE.
Проблемы с переносимостью: «rewinddir» в perlport .
Работает так же, как index , за исключением того, что возвращает позициюlastпоявление СУБСТР в СТР.Если указана Позиция,возвращает последнее появление,начинающееся с этой позиции или до нее.
Удаляет каталог, указанный параметром FILENAME, если этот каталог пуст. В случае успеха возвращается истина; в противном случае возвращается false и устанавливается $! (эррно). Если FILENAME опущен, используется $_ .
Чтобы удалить дерево каталогов рекурсивно ( rm -rf в Unix), посмотрите на функцию rmtree модуля File :: Path .
Оператор подстановки. См. «Операторы, похожие на кавычки в регулярных выражениях» в perlop .
Точно так же, как print , но неявно добавляет новую строку в конец LIST вместо любого значения, которое может иметь $ .Чтобы использовать FILEHANDLE без LIST для вывода в него содержимого $_ , вы должны использовать простой дескриптор файла, такой как FH , а не косвенный, такой как $fh .
say доступен только в том случае, если функция включена или если она имеет префикс CORE:: . Функция "say" включается автоматически с use v5.10 или выше) в текущей области.
Заставляет интерпретировать EXPR в скалярном контексте и возвращает значение EXPR.
my @counts = ( scalar @a, scalar @b, scalar @c );
Не существует эквивалентного оператора для принудительной интерполяции выражения в контексте списка, потому что на практике это никогда не требуется. Однако, если вы действительно этого хотите, вы можете использовать конструкцию @{[ (some expression) ]} , но обычно достаточно простого (some expression) .
Поскольку scalar является унарным оператором, если вы случайно используете список в скобках для EXPR, он ведет себя как скалярное выражение с запятой, оценивая все элементы, кроме последнего, в пустом контексте и возвращая последний элемент, оцененный в скалярном контексте. Это редко то, что вы хотите.
Следующее единственное заявление:
print uc(scalar(foo(), $bar)), $baz;
это моральный эквивалент этих двух:
foo(); print(uc($bar), $baz);
См. Perlop для получения дополнительных сведений об унарных операторах и операторе запятой, а также perldata для получения подробной информации об оценке хэша в скалярном контексте.
Устанавливает позицию FILEHANDLE точно так же, как вызов fseek (3) C stdio . FILEHANDLE может быть выражением, значение которого дает имя дескриптора файла. Значения WHENCE равны 0 для установки новой позиции.in bytesв ПОЛОЖЕНИЕ; 1 , чтобы установить его в текущее положение плюс POSITION; и 2 , чтобы установить его на EOF plus POSITION, обычно отрицательное. Для WHENCE вы можете использовать константы SEEK_SET , SEEK_CUR и SEEK_END (начало файла, текущая позиция, конец файла) из модуля Fcntl . Возвращает 1 в случае успеха, в противном случае — false.
Обратите внимание на байты: даже если дескриптор файла настроен на работу с символами (например, с использованием уровня ввода-вывода : :encoding(UTF-8) ), семейства функций seek , tell и sysseek используют байтовые смещения, а не смещения символов, потому что поиск смещения символов будет очень медленным в файле UTF-8.
Если вы хотите разместить файл для sysread или syswrite , не используйте seek , потому что буферизация оказывает непредсказуемое и непереносимое влияние на позицию файла для чтения и записи . sysseek этого используйте sysseek .
Из-за правил и строгости ANSI C в некоторых системах вам нужно выполнять поиск всякий раз, когда вы переключаетесь между чтением и записью. Среди прочего, это может привести к вызову функции clearrr (3) stdio . WHENCE, равный 1 ( SEEK_CUR ), полезен, чтобы не перемещать позицию файла:
seek($fh, 0, 1);
Это также полезно для приложений, эмулирующих tail -f . После того, как вы нажмете EOF при чтении, а затем немного поспите, вам (вероятно) придется придерживаться фиктивного seek чтобы сбросить вещи. seek не изменить положение, но этоdoesочистить условие конца файла для дескриптора, так что следующая readline FILE чтения FILE заставит Perl снова попытаться что-то прочитать. (Мы надеемся.)
Если это не сработает (некоторые реализации ввода/вывода особенно кантанкерны),вам может понадобиться что-нибудь подобное:
for (;;) { for ($curpos = tell($fh); $_ = readline($fh); $curpos = tell($fh)) { } sleep($for_a_while); seek($fh, $curpos, 0); }
Устанавливает текущую позицию подпрограммы readdir в DIRHANDLE. POS должно быть значением, возвращаемым telldir . seekdir также имеет те же предостережения относительно возможного уплотнения каталогов, что и соответствующая процедура системной библиотеки.
Возвращает текущий выбранный дескриптор файла. Если указан FILEHANDLE, устанавливает новый текущий дескриптор файла по умолчанию для вывода. Это имеет два эффекта: во-первых, write или print без дескриптора файла по умолчанию для этого FILEHANDLE. Во-вторых, ссылки на переменные, связанные с выходом, будут относиться к этому выходному каналу.
Например,чтобы установить формат «top-of-form» для более чем одного выходного канала,вы можете сделать следующее:
select(REPORT1); $^ = 'report1_top'; select(REPORT2); $^ = 'report2_top';
FILEHANDLE может быть выражением,значение которого дает имя реального файла-обработчика.Таким образом:
my $oldfh = select(STDERR); $| = 1; select($oldfh);
Некоторые программисты могут предпочесть думать о файловых дескрипторах как об объектах с методами,предпочитая записать последний пример как:
STDERR->autoflush(1);
(До версии Perl 5.14 вы должны явно use IO::Handle; сначала.)
Проблемы с переносимостью: «выбрать» в perlport .
Это вызывает системный вызов select(2) с указанными битовыми масками, которые могут быть созданы с использованием fileno и vec , в следующих строках:
my $rin = my $win = my $ein = ''; vec($rin, fileno(STDIN), 1) = 1; vec($win, fileno(STDOUT), 1) = 1; $ein = $rin | $win;
Если вы хотите выбрать из множества файловых ручек,вы можете записать подпрограмму,подобную этой:
sub fhbits { my @fhlist = @_; my $bits = ""; for my $fh (@fhlist) { vec($bits, fileno($fh), 1) = 1; } return $bits; } my $rin = fhbits(*STDIN, $tty, $mysock);
Обычная идиома:
my ($nfound, $timeleft) = select(my $rout = $rin, my $wout = $win, my $eout = $ein, $timeout);
или блокировать,пока что-нибудь не будет готово,просто сделай это.
my $nfound = select(my $rout = $rin, my $wout = $win, my $eout = $ein, undef);
Большинство систем не заботятся о возврате чего-либо полезного в $timeleft , поэтому вызов select в скалярном контексте просто возвращает $nfound .
Любая из битовых масок также может быть undef . Тайм-аут, если он указан, указывается в секундах, которые могут быть дробными. Примечание: не все реализации способны возвращать $timeleft . Если нет, они всегда возвращают $timeleft , равный предоставленному $timeout .
Таким образом,вы можете спать 250 миллисекунд:
select(undef, undef, undef, 0.25);
Обратите внимание, что перезапуск select после сигналов (скажем, SIGALRM) зависит от реализации. См. Также perlport для заметок о переносимости select .
В случае ошибки select ведет себя так же, как select (2) : возвращает -1 и устанавливает $! .
В некоторых Unix-системах select (2) может сообщать о дескрипторе файла сокета как о «готовом к чтению», даже если данные недоступны, и, таким образом, любое последующее read будет блокироваться. Этого можно избежать, если вы всегда используете O_NONBLOCK для сокета. Смотрите select (2) и fcntl (2) для получения дополнительной информации.
Стандартный модуль IO::Select предоставляет более удобный интерфейс для select , в основном потому, что он выполняет всю работу с битовой маской за вас.
ПРЕДУПРЕЖДЕНИЕ : Не следует пытаться смешивать буферизованный ввод-вывод (например, read или readline ) с select , за исключением случаев, разрешенных POSIX, и даже в этом случае только в системах POSIX. Вместо этого вы должны использовать sysread .
Проблемы с переносимостью: «выбрать» в perlport .
Вызов функции System V IPC semctl (2) . Вам, вероятно, придется сказать
use IPC::SysV;
сначала получить правильные определения констант. Если CMD — IPC_STAT или GETALL, то ARG должна быть переменной, которая будет содержать возвращенную структуру semid_ds или массив значений семафора. Возвращает как ioctl : неопределенное значение для ошибки, « 0 but true » для нуля или фактическое возвращаемое значение в противном случае. ARG должен состоять из вектора собственных коротких целых чисел, которые могут быть созданы с помощью pack("s!",(0)x$nsem) . См. также «SysV IPC» в perlipc и документацию для IPC::SysV и IPC::Semaphore .
Проблемы с переносимостью: «semctl» в perlport .
Вызывает функцию System V IPC semget(2) . Возвращает идентификатор семафора или неопределенное значение в случае ошибки. См. также «SysV IPC» в perlipc и документацию для IPC::SysV и IPC::Semaphore .
Проблемы с переносимостью: «semget» в perlport .
Вызывает функцию semop (2) IPC System V для семафорных операций, таких как сигнализация и ожидание. OPSTRING должен быть упакованным массивом структур semop. Каждую структуру semop можно сгенерировать с помощью pack("s!3", $semnum, $semop, $semflag) . Длина OPSTRING подразумевает количество операций с семафором. Возвращает true в случае успеха и false в случае ошибки. В качестве примера следующий код ожидает семафор $ semnum идентификатора семафора $ semid:
my $semop = pack("s!3", $semnum, -1, 0); die "Semaphore trouble: $!n" unless semop($semid, $semop);
Чтобы сигнализировать семафору, замените -1 на 1 . См. также «SysV IPC» в perlipc и документацию для IPC::SysV и IPC::Semaphore .
Проблемы с переносимостью: «semop» в perlport .
Отправляет сообщение на розетку.Попытка отправить скаляр MSG в файловую оболочку SOCKET.Принимает те же самые флаги,что и системный вызов с тем же именем.На несвязанных сокетах,вы должны указать назначение наsend to, и в этом случае он выполняет системный вызов sendto (2) . Возвращает количество отправленных символов или неопределенное значение в случае ошибки. Sendmsg (2) системный вызов в настоящее время невыполненный. См. «UDP: передача сообщений» в perlipc для примеров.
Обратите внимание, что если сокет был помечен как :utf8 , send вызовет исключение. :encoding(...) слой неявно вводит :utf8 слой. См. binmode .
Устанавливает текущую группу процессов для указанного PID, 0 для текущего процесса. Вызывает исключение при использовании на машине, которая не реализует POSIX setpgid (2) или BSD setpgrp (2) . Если аргументы опущены, по умолчанию используется 0,0 . Обратите внимание, что версия setpgrp для BSD 4.2 не принимает никаких аргументов, поэтому setpgrp(0,0) является только setpgrp (0,0) . См. Также POSIX::setsid() .
Проблемы с переносимостью: «setpgrp» в perlport .
Устанавливает текущий приоритет для процесса, группы процессов или пользователя. (См. Setpriority (2) .) Вызывает исключение при использовании на машине, которая не реализует setpriority (2) .
WHICH может быть любым из PRIO_PROCESS , PRIO_PGRP или PRIO_USER , импортированным из «RESOURCE CONSTANTS» в POSIX .
Проблемы с переносимостью: «setpriority» в perlport .
Устанавливает запрошенный параметр сокета. Возвращает undef при ошибке. Используйте целочисленные константы, предоставленные модулем Socket для LEVEL и OPNAME. Значения для LEVEL также можно получить из getprotobyname. OPTVAL может быть упакованной строкой или целым числом. Целое число OPTVAL является сокращением от pack(«i», OPTVAL).
Пример отключения алгоритма Нейгла на разъеме:
use Socket qw(IPPROTO_TCP TCP_NODELAY); setsockopt($socket, IPPROTO_TCP, TCP_NODELAY, 1);
Проблемы с переносимостью: «setsockopt» в perlport .
Сдвигает первое значение массива и возвращает его, сокращая массив на 1 и перемещая все вниз. Если в массиве нет элементов, возвращает неопределенное значение. Если ARRAY опущен, сдвигает массив @_ в лексической области подпрограмм и форматов, а массив @ARGV за пределы подпрограммы, а также в лексические области, установленные eval STRING , BEGIN {} , INIT {} , CHECK {} , UNITCHECK {} и END {} .
Начиная с Perl 5.14, экспериментальная функция позволяла shift принимать скалярное выражение. Этот эксперимент был признан неудачным и был удален с версии Perl 5.24.
См. также unshift , push и pop . shift и unshift делают то же самое с левым концом массива, а pop и push — с правым концом.
Вызов функции System V IPC shmctl.Наверное,вам придется сказать.
use IPC::SysV;
сначала получить правильные определения констант. Если CMD — IPC_STAT , то ARG должна быть переменной, которая будет содержать возвращаемую структуру shmid_ds . Возвращает как ioctl: undef для ошибки; « 0 , но верно» для нуля; и фактическое возвращаемое значение в противном случае. См. также «SysV IPC» в perlipc и документацию для IPC::SysV .
Проблемы с переносимостью: «shmctl» в perlport .
Вызывает функцию shmget IPC System V. Возвращает идентификатор сегмента общей памяти или undef в случае ошибки. См. также «SysV IPC» в perlipc и документацию для IPC::SysV .
Проблемы с переносимостью: «shmget» в perlport .
Читает или записывает идентификатор сегмента разделяемой памяти System V, начиная с позиции POS для размера SIZE, присоединяя к нему, копируя в/из и отсоединяя от него. При чтении VAR должна быть переменной, которая будет хранить прочитанные данные. При записи, если STRING слишком длинное, используются только байты SIZE; если STRING слишком короткий, для заполнения SIZE байтов записываются нули. Возвращает true в случае успеха, false в случае ошибки. shmread портит переменную. См. также «SysV IPC» в perlipc и документацию по IPC::SysV и модулю IPC::Shareable из CPAN.
Проблемы с переносимостью: «shmread» в perlport и «shmwrite» в perlport .
Выключает гнездовое соединение способом,указанным в HOW,которое имеет такое же толкование,как и в одноименном syscall.
shutdown($socket, 0); shutdown($socket, 1); shutdown($socket, 2);
Это полезно при использовании разъемов,когда вы хотите сказать другой стороне,что вы закончили писать,но не закончили читать,или наоборот.Это также более настойчивая форма закрытия,потому что она также отключает дескриптор файла в любых вилочных копиях в других процессах.
Возвращает 1 в случае успеха; при ошибке возвращает undef , если первый аргумент не является допустимым дескриптором файла, или возвращает 0 и устанавливает $! за любую другую неудачу.
Возвращает синус выражения EXPR (выраженный в радианах). Если EXPR опущен, возвращает синус $_ .
Для операции обратного синуса вы можете использовать функцию Math::Trig::asin или использовать это отношение:
sub asin { atan2($_[0], sqrt(1 - $_[0] * $_[0])) }
Заставляет скрипт спать на (целые)EXPR секунды,или навсегда,если не задан ни один аргумент.Возвращает целое число фактически уснувших секунд.
EXPR должен быть положительным целым числом. При вызове с отрицательным целым числом sleep не засыпает, а вместо этого выдает предупреждение, устанавливает $! ( errno ) и возвращает ноль.
sleep 0 разрешен, но вызов функции базовой реализации платформы все еще происходит со всеми возможными побочными эффектами. Поэтому sleep 0 не совсем идентичен отсутствию сна.
Может быть прерван, если процесс получит сигнал, например SIGALRM .
eval { local $SIG{ALRM} = sub { die "Alarm!n" }; sleep; }; die $@ unless $@ eq "Alarm!n";
Вы, вероятно, не можете смешивать вызовы alarm и sleep , потому что sleep часто реализуется с помощью alarm .
На некоторых старых системах,он может спать до полной секунды меньше,чем вы просили,в зависимости от того,как он считает секунды.Большинство современных систем всегда спят полную сумму.Они могут показаться,чтобы спать дольше,чем это,однако,потому что ваш процесс может не быть запланирован сразу же в занятой многозадачности системы.
Для задержек с более мелкой детализацией, чем одна секунда, модуль Time :: HiRes (из CPAN и начиная с Perl 5.8, часть стандартного дистрибутива) предоставляет usleep . Вы также можете использовать Perl-версию select с четырьмя аргументами, оставив первые три аргумента неопределенными, или вы можете использовать интерфейс syscall для доступа к setitimer (2), если ваша система его поддерживает. Подробности смотрите в perlfaq8 .
См. Также функцию pause модуля POSIX .
Открывает сокет указанного типа и присоединяет его к дескриптору файла SOCKET. ДОМЕН, ТИП и ПРОТОКОЛ указываются так же, как и для одноименного системного вызова. Вы должны сначала use Socket чтобы импортировать правильные определения. См. Примеры в разделе «Сокеты: обмен данными между клиентом и сервером» в perlipc .
В системах , которые поддерживают тесную-на-Exec флаг на файлах, флаг будет установлен для вновь открытого дескриптора файла, как определено значением $^F . Смотрите «$ ^ F» в perlvar .
Создает безымянную пару сокетов в указанном домене,указанного типа.DOMAIN,TYPE и PROTOCOL указываются так же,как и для одноименного syscall.Если не выполняется,вызывает исключение.Возвращает true в случае успеха.
В системах , которые поддерживают тесную-на-Exec флаг на файлах, флаг будет установлен для вновь открытых дескрипторов файлов, как определено значением $^F . Смотрите «$ ^ F» в perlvar .
Некоторые системы определяют pipe в терминах socketpair , в которой вызов pipe($rdr, $wtr) по существу:
use Socket; socketpair(my $rdr, my $wtr, AF_UNIX, SOCK_STREAM, PF_UNSPEC); shutdown($rdr, 1); shutdown($wtr, 0);
См perlipc для примера socketpair использования. Perl 5.8 и более поздние версии будут эмулировать пару сокетов, используя IP-сокеты для localhost, если ваша система реализует сокеты, но не поддерживает пару сокетов.
Проблемы с переносимостью: «socketpair» в perlport .
В контексте списка это сортирует LIST и возвращает значение отсортированного списка. В скалярном контексте поведение sort не определено.
Если SUBNAME или BLOCK опущены, sort s в стандартном порядке сравнения строк. Если указано SUBNAME, оно дает имя подпрограммы, которая возвращает целое число, меньшее, равное или большее 0 , в зависимости от того, как элементы списка должны быть упорядочены. ( Операторы <=> и cmp чрезвычайно полезны в таких подпрограммах.) SUBNAME может быть именем скалярной переменной (без подписки), и в этом случае значение предоставляет имя (или ссылку) фактической используемой подпрограммы. Вместо SUBNAME вы можете указать BLOCK как анонимную встроенную подпрограмму сортировки.
Если прототип подпрограммы ($$) , сравниваемые элементы передаются по ссылке в @_ , как для обычной подпрограммы. Это медленнее, чем подпрограммы без прототипов, в которых сравниваемые элементы передаются в подпрограмму как глобальные переменные пакета $a и $b (см. Пример ниже).
Если подпрограмма является XSUB, сравниваемые элементы помещаются в стек, как обычно аргументы передаются в XSUB. $a и $b не установлены.
Сравниваемые значения всегда передаются по ссылке и не должны изменяться.
Вы также не можете выйти из блока сортировки или подпрограммы, используя любой из операторов управления циклом, описанных в perlsyn или с помощью goto .
Когда use locale ':not_characters' use locale (но не языкового стандарта ‘: not_characters’ ), sort LIST сортирует LIST в соответствии с текущим языковым стандартом сопоставления. Смотрите perllocale .
sort возвращает псевдонимы в исходный список, так же как индексная переменная цикла for присваивает псевдонимы элементам списка. То есть изменение элемента списка, возвращаемого sort (например, в foreach , map или grep ), фактически изменяет элемент в исходном списке. Обычно этого следует избегать при написании понятного кода.
Исторически Perl варьировался в зависимости от того, является ли сортировка по умолчанию стабильной. Если стабильность имеет значение, ею можно явно управлять с помощью прагмы sort .
Examples:
my @articles = sort @files; my @articles = sort {$a cmp $b} @files; my @articles = sort {fc($a) cmp fc($b)} @files; my @articles = sort {$b cmp $a} @files; my @articles = sort {$a <=> $b} @files; my @articles = sort {$b <=> $a} @files; my @eldest = sort { $age{$b} <=> $age{$a} } keys %age; sub byage { $age{$a} <=> $age{$b}; } my @sortedclass = sort byage @class; sub backwards { $b cmp $a } my @harry = qw(dog cat x Cain Abel); my @george = qw(gone chased yz Punished Axed); print sort @harry; print sort backwards @harry; print sort @george, 'to', @harry; my @new = sort { ($b =~ /=(d+)/)[0] <=> ($a =~ /=(d+)/)[0] || fc($a) cmp fc($b) } @old; my (@nums, @caps); for (@old) { push @nums, ( /=(d+)/ ? $1 : undef ); push @caps, fc($_); } my @new = @old[ sort { $nums[$b] <=> $nums[$a] || $caps[$a] cmp $caps[$b] } 0..$#old ]; my @new = map { $_->[0] } sort { $b->[1] <=> $a->[1] || $a->[2] cmp $b->[2] } map { [$_, /=(d+)/, fc($_)] } @old; package Other; sub backwards ($$) { $_[1] cmp $_[0]; } package main; my @new = sort Other::backwards @old; use feature 'signatures'; sub function_with_signature :prototype($$) ($one, $two) { return $one <=> $two } my @new = sort function_with_signature @old; use sort 'stable'; my @new = sort { substr($a, 3, 5) cmp substr($b, 3, 5) } @old;
Предупреждение: синтаксическая осторожность требуется при сортировке списка, возвращаемого функцией. Если вы хотите отсортировать список, возвращаемый вызовом функции find_records(@key) , вы можете использовать:
my @contact = sort { $a cmp $b } find_records @key; my @contact = sort +find_records(@key); my @contact = sort &find_records(@key); my @contact = sort(find_records(@key));
Если вместо этого вы хотите отсортировать массив @key с помощью процедуры сравнения find_records() вы можете использовать:
my @contact = sort { find_records() } @key; my @contact = sort find_records(@key); my @contact = sort(find_records @key); my @contact = sort(find_records (@key));
$a и $b устанавливаются как глобальные переменные пакета в пакете, из которого вызывается sort (). Это означает $main::a и $main::b (или $::a и $::b ) в main пакете, $FooPack::a и $FooPack::b в пакете FooPack и т. Д. сортировать блок в сфере действия my или state декларация $a и / или $b , выmustпропишите полное имя переменных в блоке сортировки :
package main; my $a = "C"; print sort { $a cmp $b } qw(A C E G B D F H); sub badlexi { $a cmp $b } print sort badlexi qw(A C E G B D F H); print sort { $::a cmp $::b } qw(A C E G B D F H); print sort { our $a cmp our $b } qw(A C E G B D F H); print sort { our ($a, $b); $a cmp $b } qw(A C E G B D F H); sub lexi { our $a cmp our $b } print sort lexi qw(A C E G B D F H);
При должном внимании вы можете смешать package и мои (или состояние) $a и / или $b :
my $a = { tiny => -2, small => -1, normal => 0, big => 1, huge => 2 }; say sort { $a->{our $a} <=> $a->{our $b} } qw{ huge normal tiny small big};
$a и $b неявно локальны для выполнения sort () и восстанавливают свои прежние значения после завершения сортировки.
Подпрограммы сортировки, написанные с использованием $a и $b , привязаны к своему вызывающему пакету. Возможно, но представляет ограниченный интерес, определить их в другом пакете, поскольку подпрограмма все еще должна ссылаться на $a и $b вызывающего пакета :
package Foo; sub lexi { $Bar::a cmp $Bar::b } package Bar; ... sort Foo::lexi ...
Используйте прототипированные версии (см.выше)для более общей альтернативы.
Функция сравнения должна работать. Если он возвращает противоречивые результаты (иногда говорят, что $x[1] меньше, чем $x[2] а иногда, например, говорят обратное), результаты не являются четко определенными.
Поскольку <=> возвращает undef , когда любой из операндов имеет NaN (не число), будьте осторожны при сортировке с помощью функции сравнения, такой как $a <=> $b любых списков, которые могут содержать NaN . В следующем примере используется преимущество NaN != NaN для исключения любых NaN из входного списка.
my @result = sort { $a <=> $b } grep { $_ == $_ } @input;
В этой версииperl, функция sort реализована с помощью алгоритма сортировки слиянием.
Удаляет элементы, обозначенные OFFSET и LENGTH, из массива и заменяет их элементами LIST, если они есть. В контексте списка возвращает элементы, удаленные из массива. В скалярном контексте возвращает последний удаленный элемент или undef , если элементы не удалены. Массив увеличивается или уменьшается по мере необходимости. Если OFFSET отрицательное, то оно начинается так далеко от конца массива. Если LENGTH не указан, удаляется все, начиная со OFFSET. Если LENGTH имеет отрицательное значение, удаляются элементы, начиная со OFFSET, за исключением элементов -LENGTH в конце массива. Если и OFFSET, и LENGTH опущены, удаляет все. Если OFFSET находится за концом массива и была предоставлена LENGTH, Perl выдает предупреждение и выполняет сращивание в конце массива.
Имеют место следующие эквивалентности (при условии, что $#a >= $i )
push(@a,$x,$y) splice(@a,@a,0,$x,$y) pop(@a) splice(@a,-1) shift(@a) splice(@a,0,1) unshift(@a,$x,$y) splice(@a,0,0,$x,$y) $a[$i] = $y splice(@a,$i,1,$y)
splice можно использовать, например, для реализации n-арной обработки очереди:
sub nary_print { my $n = shift; while (my @next_n = splice @_, 0, $n) { say join q{ -- }, @next_n; } } nary_print(3, qw(a b c d e f g h));
Начиная с Perl 5.14, экспериментальная функция позволяла splice принимать скалярное выражение. Этот эксперимент был признан неудачным и был удален в Perl 5.24.
Разбивает строку EXPR на список строк и возвращает список в контексте списка или размер списка в скалярном контексте. (До Perl 5.11 он также перезаписывал @_ списком в пустом и скалярном контексте. Будьте осторожны, если вы нацеливаетесь на старые Perl.)
Если задан только ШАБЛОН, по умолчанию EXPR равен $_ .
Все в EXPR,что соответствует ДАТЧИКЕ,считается разделителем,который разделяет EXPR на подстроки (называется «fields«), которые не включают разделитель. Обратите внимание, что разделитель может быть длиннее одного символа или даже не содержать символов (пустая строка, которая соответствует нулевой ширине).
ДАТЧЕРН не обязательно должен быть константным;выражение может быть использовано для указания шаблона,который изменяется во время выполнения.
Если PATTERN совпадает с пустой строкой,то EXPR разбивается на позицию совпадения (между символами).В качестве примера можно привести следующее:
my @x = split(/b/, "abc");
использует b в 'abc' в качестве разделителя для создания списка («a», «c»). Однако это:
my @x = split(//, "abc");
использует совпадения пустых строк в качестве разделителей;таким образом,пустая строка может быть использована для разбиения EXPR на список составляющих его символов.
В качестве особого случая для split пустой шаблон, указанный в синтаксисе оператора сопоставления ( // ), конкретно соответствует пустой строке, что противоречит его обычной интерпретации как последнее успешное сопоставление.
Если ШАБЛОН — /^/ , то он обрабатывается так, как если бы он использовал многострочный модификатор ( /^/m ), поскольку в противном случае он мало используется.
/m и любые другие модификаторы шаблона, допустимые для qr (суммированные в «qr / STRING / msixpodualn» в perlop ), могут быть указаны явно.
В качестве другого особого случая split имитирует поведение по умолчанию инструмента командной строки awk, когда ШАБЛОН либо опущен, либо строка состоит из одного символа пробела (например, ' ' или "x20" , но не, например, / / ). В этом случае все начальные пробелы в EXPR удаляются до того, как произойдет разделение, и вместо этого ШАБЛОН обрабатывается так, как если бы он был /s+/ ; в частности, это означает, чтоanyВ качестве разделителя используется непрерывный пробел (а не один символ пробела).
my @x = split(" ", " Quick brown foxn"); # ("Quick", "brown", "fox") my @x = split(" ", "REDtGREENtBLUE"); # ("RED", "GREEN", "BLUE")
Использование split таким образом очень похоже на то, как работает qw// .
Однако этой специальной обработки можно избежать, указав шаблон / / вместо строки " " , что позволяет использовать только один пробел в качестве разделителя. В более ранних версиях Perls этот особый случай ограничивался использованием простого " " в качестве аргумента шаблона для split; в Perl 5.18.0 и более поздних версиях этот особый случай запускается любым выражением, результатом которого является простая строка " " .
Начиная с Perl 5.28, это разделение на пробелы в специальном регистре работает, как и ожидалось, в области "use feature 'unicode_strings'" . В предыдущих версиях и за пределами этой функции в perlunicode проявлялась «ошибка Unicode» : символы, которые являются пробелами в соответствии с правилами Unicode, но не в соответствии с правилами ASCII, могут рассматриваться как часть полей, а не как разделители полей. , в зависимости от внутренней кодировки строки.
Если опущено, ШАБЛОН по умолчанию использует один пробел, " " , вызывая ранее описанныйawkemulation.
Если указано положительное значение LIMIT, оно представляет максимальное количество полей, на которые можно разбить EXPR; другими словами, LIMIT на единицу больше, чем максимальное количество раз, которое может быть разделено EXPR. Таким образом, значение LIMIT 1 означает, что EXPR может быть разделен максимум ноль раз, создавая максимум одно поле (а именно, все значение EXPR). Например:
my @x = split(//, "abc", 1); my @x = split(//, "abc", 2); my @x = split(//, "abc", 3); my @x = split(//, "abc", 4);
Если LIMIT отрицательный,то к нему относятся как к произвольно большому количеству месторождений;добывается как можно больше месторождений.
Если LIMIT опущен (или,эквивалентно,равен нулю),то он обычно считается отрицательным,но за исключением того,что пустые поля в трейлинге удаляются (пустые ведущие поля всегда сохраняются);если все поля пустые,то все поля считаются пустыми (и,таким образом,в данном случае удаляются).Таким образом,следующее:
my @x = split(/,/, "a,b,c,,,");
выдает только трехэлементный список.
my @x = split(/,/, "a,b,c,,,", -1); # ("a", "b", "c", "", "", "")
выдает список из шести элементов.
В приложениях,критически важных с точки зрения времени,стоит избегать разбиения на большее количество полей,чем необходимо.Таким образом,при присвоении списку,если LIMIT опущен (или равен нулю),то LIMIT рассматривается,как если бы он был на одну переменную больше,чем количество переменных в списке;для следующего,LIMIT неявно 3:
my ($login, $passwd) = split(/:/);
Обратите внимание,что разделение EXPR,который оценивает пустую строку,всегда приводит к появлению нулевых полей,независимо от указанного LIMIT.
Пустое опережающее поле создается,когда в начале EXPR появляется матч положительной ширины.Например:
my @x = split(/ /, " abc");
разделяется на два элемента.Однако,совпадение нулевой ширины в начале EXPR никогда не дает пустого поля,так что:
my @x = split(//, " abc");
распадается на четыре элемента вместо пяти.
Пустое трейлинговое поле,с другой стороны,создается при наличии матча в конце EXPR,независимо от длины матча (конечно,если ненулевой LIMIT не указан явно,такие поля,как в последнем примере,удаляются).Таким образом:
my @x = split(//, " abc", -1); # (" ", "a", "b", "c", "")
Если ШАБЛОН содержит группы захвата , то для каждого разделителя создается дополнительное поле для каждой подстроки, захваченной группой (в порядке, в котором указаны группы, согласно обратным ссылкам ); если какая-либо группа не совпадает, то вместо подстроки захватывается значение undef .Кроме того, обратите внимание, что любое такое дополнительное поле создается всякий раз, когда есть разделитель (то есть всякий раз, когда происходит разделение), и такое дополнительное поле не учитывается при расчете LIMIT. Рассмотрим следующие выражения, оцениваемые в контексте списка (каждый возвращаемый список предоставляется в соответствующем комментарии):
my @x = split(/-|,/ , "1-10,20", 3); # ("1", "10", "20") my @x = split(/(-|,)/ , "1-10,20", 3); # ("1", "-", "10", ",", "20") my @x = split(/-|(,)/ , "1-10,20", 3); # ("1", undef, "10", ",", "20") my @x = split(/(-)|,/ , "1-10,20", 3); # ("1", "-", "10", undef, "20") my @x = split(/(-)|(,)/, "1-10,20", 3); # ("1", "-", undef, "10", undef, ",", "20")
Возвращает строку, отформатированную в соответствии с обычными соглашениями о printf библиотечной функции C sprintf . См. Ниже для получения дополнительных сведений и см. Sprintf (3) или printf (3) в вашей системе для объяснения общих принципов.
For example:
my $result = sprintf("%08d", $number); my $rounded = sprintf("%.3f", $number);
Perl выполняет собственное форматирование sprintf : он эмулирует C-функцию sprintf (3) , но не использует ее, за исключением чисел с плавающей запятой, и даже в этом случае разрешены только стандартные модификаторы. Поэтому нестандартные расширения в вашем локальном sprintf (3) недоступны в Perl.
В отличие от printf , sprintf не делает того, что вы, вероятно, имеете в виду, когда вы передаете ему массив в качестве первого аргумента. Массиву задается скалярный контекст, и вместо использования 0-го элемента массива в качестве формата Perl будет использовать количество элементов в массиве в качестве формата, что почти никогда не бывает полезным.
Perl sprintf допускает следующие общеизвестные преобразования:
%% a percent sign %c a character with the given number %s a string %d a signed integer, in decimal %u an unsigned integer, in decimal %o an unsigned integer, in octal %x an unsigned integer, in hexadecimal %e a floating-point number, in scientific notation %f a floating-point number, in fixed decimal notation %g a floating-point number, in %e or %f notation
Кроме того,Perl допускает следующие широко поддерживаемые преобразования:
%X like %x, but using upper-case letters %E like %e, but using an upper-case "E" %G like %g, but with an upper-case "E" (if applicable) %b an unsigned integer, in binary %B like %b, but using an upper-case "B" with the # flag %p a pointer (outputs the Perl value %n special: *stores* the number of characters output so far into the next argument in the parameter list %a hexadecimal floating point %A like %a, but using upper-case letters
Наконец,для обратной (а мы действительно имеем в виду «обратную»)совместимости Perl допускает эти ненужные,но широко поддерживаемые преобразования:
%i a synonym for %d %D a synonym for %ld %U a synonym for %lu %O a synonym for %lo %F a synonym for %f
Обратите внимание, что количество цифр экспоненты в экспоненциальной нотации, создаваемой %e , %E , %g и %G для чисел с модулем экспоненты меньше 100, зависит от системы: оно может быть три или меньше (с дополнением нулями как нужно). Другими словами, 1,23 умноженное на десять до 99-го числа может быть либо «1,23e99», либо «1,23e099». Аналогично для %a и %A : показатель степени или шестнадцатеричные цифры могут плавать: особенно опция конфигурации Perl «длинные удвоения» может вызвать сюрпризы.
Между % и буквой формата вы можете указать несколько дополнительных атрибутов, управляющих интерпретацией формата. По порядку это:
- индекс форматных параметров
-
Явный индекс параметра формата, например
2$. По умолчанию sprintf отформатирует следующий неиспользуемый аргумент в списке, но это позволяет вам выносить аргументы не по порядку:printf '%2$d %1$d', 12, 34; printf '%3$d %d %1$d', 1, 2, 3;
- flags
-
один или несколько:
space prefix non-negative number with a space + prefix non-negative number with a plus sign - left-justify within the field 0 use zeros, not spaces, to right-justify # ensure the leading "0" for any octal, prefix non-zero hexadecimal with "0x" or "0X", prefix non-zero binary with "0b" or "0B"
For example:
printf '<% d>', 12; # prints "< 12>" printf '<% d>', 0; # prints "< 0>" printf '<% d>', -12; # prints "<-12>" printf '<%+d>', 12; # prints "<+12>" printf '<%+d>', 0; # prints "<+0>" printf '<%+d>', -12; # prints "<-12>" printf '<%6s>', 12; # prints "< 12>" printf '<%-6s>', 12; # prints "<12 >" printf '<%06s>', 12; # prints "<000012>" printf '<%#o>', 12; # prints "<014>" printf '<%#x>', 12; # prints "<0xc>" printf '<%#X>', 12; # prints "<0XC>" printf '<%#b>', 12; # prints "<0b1100>" printf '<%#B>', 12; # prints "<0B1100>"
Если в качестве флагов одновременно указаны пробел и знак плюс,пробел игнорируется.
printf '<%+ d>', 12; printf '<% +d>', 12;
Когда при преобразовании в %o задаются флаг#и точность,точность увеличивается,если это необходимо для ведущего «0».
printf '<%#.5o>', 012; printf '<%#.5o>', 012345; printf '<%#.0o>', 0;
- vector flag
-
Этот флаг указывает Perl интерпретировать предоставленную строку как вектор целых чисел, по одному на каждый символ в строке. Perl применяется формат для каждого целого , в свою очередь, затем присоединяется результирующие строки с разделителем (точкой
.По умолчанию). Это может быть полезно для отображения порядковых значений символов в произвольных строках:printf "%vd", "ABx{100}"; printf "version is v%vdn", $^V;
Поставьте звездочку
*передv, чтобы переопределить строку, используемую для разделения чисел:printf "address is %*vXn", ":", $addr; printf "bits are %0*v8bn", " ", $bits;
Вы также можете явно указать номер аргумента, который будет использоваться для строки соединения, используя что-то вроде
*2$v; например:printf '%*4$vX %*4$vX %*4$vX', @addr[1..3], ":";
- (minimum) width
-
Аргументы обычно форматируются так, чтобы иметь ширину, необходимую для отображения данного значения. Вы можете переопределить ширину, поместив здесь число, или получить ширину из следующего аргумента (с
*) или из указанного аргумента (например, с*2$):printf "<%s>", "a"; printf "<%6s>", "a"; printf "<%*s>", 6, "a"; printf '<%*2$s>', "a", 6; printf "<%2s>", "long";
Если ширина поля, полученная с помощью
*, отрицательна, она имеет тот же эффект, что и флаг-: выравнивание по левому краю. - точность или максимальная ширина
-
Вы можете указать точность (для числовых преобразований) или максимальную ширину (для преобразований строк), указав
.за которым следует номер. Для форматов с плавающей запятой, за исключениемgиG, это указывает, сколько разрядов справа от десятичной точки отображать (по умолчанию 6). Например:printf '<%f>', 1; printf '<%.1f>', 1; printf '<%.0f>', 1; printf '<%e>', 10; printf '<%.1e>', 10;
Для «g» и «G» это указывает максимальное количество значащих цифр,которые нужно показать;например:
# These examples are subject to system-specific variation. printf '<%g>', 1; # prints "<1>" printf '<%.10g>', 1; # prints "<1>" printf '<%g>', 100; # prints "<100>" printf '<%.1g>', 100; # prints "<1e+02>" printf '<%.2g>', 100.01; # prints "<1e+02>" printf '<%.5g>', 100.01; # prints "<100.01>" printf '<%.4g>', 100.01; # prints "<100>" printf '<%.1g>', 0.0111; # prints "<0.01>" printf '<%.2g>', 0.0111; # prints "<0.011>" printf '<%.3g>', 0.0111; # prints "<0.0111>"
Для целочисленных преобразований указание точности подразумевает,что вывод самого числа должен быть с нулевой шириной,где флаг 0 игнорируется:
printf '<%.6d>', 1; # prints "<000001>" printf '<%+.6d>', 1; # prints "<+000001>" printf '<%-10.6d>', 1; # prints "<000001 >" printf '<%10.6d>', 1; # prints "< 000001>" printf '<%010.6d>', 1; # prints "< 000001>" printf '<%+10.6d>', 1; # prints "< +000001>" printf '<%.6x>', 1; # prints "<000001>" printf '<%#.6x>', 1; # prints "<0x000001>" printf '<%-10.6x>', 1; # prints "<000001 >" printf '<%10.6x>', 1; # prints "< 000001>" printf '<%010.6x>', 1; # prints "< 000001>" printf '<%#10.6x>', 1; # prints "< 0x000001>"
При преобразовании строк указание точности усекает строку до заданной ширины:
printf '<%.5s>', "truncated"; printf '<%10.5s>', "truncated";
Вы также можете получить точность из следующего аргумента, используя
.*, Или из указанного аргумента (например, с помощью.*2$):printf '<%.6x>', 1; printf '<%.*x>', 6, 1; printf '<%.*2$x>', 1, 6; printf '<%6.*2$x>', 1, 4;
Если точность, полученная с помощью
*, отрицательна, она считается не имеющей точности вообще.printf '<%.*s>', 7, "string"; printf '<%.*s>', 3, "string"; printf '<%.*s>', 0, "string"; printf '<%.*s>', -1, "string"; printf '<%.*d>', 1, 0; printf '<%.*d>', 0, 0; printf '<%.*d>', -1, 0;
- size
-
Для числовых преобразований вы можете указать размер для интерпретации числа как
l,h,V,q,Lилиll. Для целочисленных преобразований (d u o x X b i D U O) обычно предполагается, что числа соответствуют размеру целого числа по умолчанию на вашей платформе (обычно 32 или 64 бита), но вы можете переопределить это, чтобы использовать вместо этого один из стандартных типов C, как поддерживается компилятором, использованным для сборки Perl:hh interpret integer as C type "char" or "unsigned char" on Perl 5.14 or later h interpret integer as C type "short" or "unsigned short" j interpret integer as C type "intmax_t" on Perl 5.14 or later; and prior to Perl 5.30, only with a C99 compiler (unportable) l interpret integer as C type "long" or "unsigned long" q, L, or ll interpret integer as C type "long long", "unsigned long long", or "quad" (typically 64-bit integers) t interpret integer as C type "ptrdiff_t" on Perl 5.14 or later z interpret integer as C types "size_t" or "ssize_t" on Perl 5.14 or later
Обратите внимание, что в общем случае использование модификатора
l(например, при написании"%ld"или"%lu"вместо"%d"и"%u") не требуется при использовании из кода Perl. Более того, это может быть вредно, например, в 64-битной Windows, где long — это 32-бит.Начиная с версии 5.14, ни один из них не вызывает исключения, если они не поддерживаются на вашей платформе. Однако, если предупреждения включены, предупреждение класса предупреждений
printfвыдается при неподдерживаемом флаге преобразования. Если вы предпочитаете исключение, сделайте следующее:use warnings FATAL => "printf";
Если вы хотите узнать о зависимости от версии до того,как вы начнете запускать программу,положите что-нибудь подобное наверх:
use v5.14;
Вы можете узнать, поддерживает ли ваш Perl квадроциклы через Config :
use Config; if ($Config{use64bitint} eq "define" || $Config{longsize} >= 8) { print "Nice quads!n"; }
Для преобразований с плавающей запятой (
e f g E F G) обычно предполагается, что числа являются размером с плавающей запятой по умолчанию на вашей платформе (double или long double), но вы можете принудительно использовать «long double» с помощьюq,Lилиll, если ваша платформа поддерживает их. Вы можете узнать, поддерживает ли ваш Perl длинные двойники, через Config :use Config; print "long doublesn" if $Config{d_longdbl} eq "define";
Вы можете узнать, считает ли Perl «long double» размером с плавающей запятой по умолчанию для использования на вашей платформе через Config :
use Config; if ($Config{uselongdouble} eq "define") { print "long doubles by defaultn"; }
Также может быть,что длинные удвоения и удвоения-это одно и то же:
use Config; ($Config{doublesize} == $Config{longdblsize}) && print "doubles are long doublesn";
Спецификатор размера
Vне влияет на код Perl, но поддерживается для совместимости с кодом XS. Это означает «использовать стандартный размер для целого числа Perl или числа с плавающей запятой», который является значением по умолчанию. - порядок аргументов
-
Обычно
sprintfпринимает следующий неиспользуемый аргумент в качестве значения для форматирования для каждой спецификации формата. Если в спецификации формата используется*, чтобы требовать дополнительных аргументов, они используются из списка аргументов в том порядке, в котором они появляются в спецификации формата.beforeзначение для форматирования.Если аргумент указан явным указателем,это не влияет на обычный порядок аргументов,даже если явным указателем был бы следующий аргумент.So:
printf "<%*.*s>", $a, $b, $c;
использует
$aдля ширины,$bдля точности и$cкак значение для форматирования; пока:printf '<%*1$.*s>', $a, $b;
будет использовать
$aдля ширины и точности и$bв качестве значения для форматирования.Вот еще несколько примеров; имейте в виду, что при использовании явного индекса может потребоваться экранирование
$:printf "%2$d %dn", 12, 34; printf "%2$d %d %dn", 12, 34; printf "%3$d %d %dn", 12, 34, 56; printf "%2$*3$d %dn", 12, 34, 3; printf "%*1$.*fn", 4, 5, 10;
Если use locale (включая use locale ':not_characters' ) и был вызван POSIX::setlocale , символ, используемый для десятичного разделителя в форматированных числах с плавающей запятой, зависит от языкового стандарта LC_NUMERIC . См. Perllocale и POSIX .
Вернуть положительный квадратный корень из EXPR. Если EXPR опущен, используется $_ . Работает только для неотрицательных операндов, если вы не загрузили модуль Math::Complex .
use Math::Complex; print sqrt(-4);
Задает и возвращает начальное значение случайного числа для оператора rand .
Смысл этой функции в том, чтобы «запустить» функцию rand , чтобы rand мог создавать разные последовательности каждый раз, когда вы запускаете свою программу. При вызове с параметром srand использует его в качестве начального значения; в противном случае он (полу-)случайно выбирает семя. В любом случае, начиная с Perl 5.14, он возвращает начальное значение. Чтобы сигнализировать, что ваш код будет работатьonlyна Перлс недавнего винтажа:
use v5.14;
Если srand не вызывается явно, он вызывается неявно без параметра при первом использовании оператора rand . Однако есть несколько ситуаций, когда программы, скорее всего, захотят вызвать srand . Один предназначен для получения предсказуемых результатов, как правило, для тестирования или отладки. Там вы используете srand($seed) каждый раз с одним и тем же $seed .В другом случае вы можете вызвать srand после fork , чтобы избежать того, чтобы дочерние процессы использовали то же начальное значение, что и родительский (и, следовательно, друг друга).
Не вызывайте srand() (т. е. без аргумента) более одного раза для каждого процесса. Внутреннее состояние генератора случайных чисел должно содержать больше энтропии, чем может быть обеспечено любым начальным числом, поэтому повторный вызов srand фактическиlosesrandomness.
Большинство реализаций srand принимают целое число и молча обрезают десятичные числа. Это означает, что srand(42) обычно дает те же результаты, что и srand(42.1) . На всякий случай всегда передавайте srand целое число.
Обычно возвращаемый посевной материал используется для программы тестирования,которая имеет слишком много комбинаций для всестороннего тестирования за доступное ей время при каждом прогоне.Она может каждый раз тестировать случайное подмножество,и в случае сбоя регистрировать семя,использованное для этого запуска,чтобы впоследствии использовать его для воспроизведения одних и тех же результатов.
rand не является криптографически безопасным. Вы не должны полагаться на него в ситуациях, чувствительных к безопасности. На момент написания этой статьи ряд сторонних модулей CPAN предлагают генераторы случайных чисел, предназначенные их авторами для обеспечения криптографической безопасности, в том числе:Data::Entropy,Crypt::Random,Math::Random::SecureиMath:: Истиннослучайный.
Возвращает список из 13 элементов, предоставляющий информацию о состоянии файла, будь то файл, открытый через FILEHANDLE или DIRHANDLE, или названный EXPR. Если EXPR опущен, это статистика $_ (не _ !). Возвращает пустой список, если stat не удалась. Обычно используется следующим образом:
my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size, $atime,$mtime,$ctime,$blksize,$blocks) = stat($filename);
Не все поля поддерживаются на всех типах файловых систем.Вот значения полей:
0 dev device number of filesystem 1 ino inode number 2 mode file mode (type and permissions) 3 nlink number of (hard) links to the file 4 uid numeric user ID of file's owner 5 gid numeric group ID of file's owner 6 rdev the device identifier (special files only) 7 size total size of file, in bytes 8 atime last access time in seconds since the epoch 9 mtime last modify time in seconds since the epoch 10 ctime inode change time in seconds since the epoch (*) 11 blksize preferred I/O size in bytes for interacting with the file (may vary from file to file) 12 blocks actual number of system-specific blocks allocated on disk (often, but not always, 512 bytes each)
(Эпоха была в 00:00 1 января 1970 г. по Гринвичу.)
(*) Не все поля поддерживаются во всех типах файловых систем. Примечательно, что поле ctime не является переносимым. В частности, вы не можете ожидать, что это будет «время творения»; подробности см. в разделе «Файлы и файловые системы» в perlport .
Если stat передается специальный дескриптор файла, состоящий из подчеркивания, stat не выполняется, но возвращается текущее содержимое структуры stat из последнего stat , lstat или filetest.Пример:
if (-x $file && (($d) = stat(_)) && $d < 0) { print "$file is executable NFS filen"; }
(Это работает только на машинах, у которых номер устройства отрицательный под NFS.)
На некоторых платформах номера inode имеют больший тип, чем Perl умеет обрабатывать как целые числовые значения. При необходимости номер inode будет возвращен в виде десятичной строки, чтобы сохранить все значение. Если используется в числовом контексте, это будет преобразовано в числовое значение с плавающей запятой с округлением, чего лучше избегать. Следовательно, вы должны предпочесть сравнивать номера inode, используя eq , а не == . eq отлично работает с номерами inode, которые представлены в числовом виде, а также с номерами, представленными в виде строк.
Поскольку режим содержит как тип файла, так и его разрешения, вы должны замаскировать часть типа файла и (-ы) printf, используя "%o" если вы хотите увидеть реальные разрешения.
my $mode = (stat($filename))[2]; printf "Permissions are %04on", $mode & 07777;
В скалярном контексте stat возвращает логическое значение, указывающее на успех или неудачу, и, в случае успеха, устанавливает информацию, связанную со специальным дескриптором файла _ .
Модуль File :: stat предоставляет удобный механизм доступа по имени:
use File::stat; my $sb = stat($filename); printf "File is %s, size is %s, perm %04o, mtime %sn", $filename, $sb->size, $sb->mode & 07777, scalar localtime $sb->mtime;
Вы можете импортировать константы символьного режима ( S_IF* ) и функции ( S_IS* ) из модуля Fcntl :
use Fcntl ':mode'; my $mode = (stat($filename))[2]; my $user_rwx = ($mode & S_IRWXU) >> 6; my $group_read = ($mode & S_IRGRP) >> 3; my $other_execute = $mode & S_IXOTH; printf "Permissions are %04on", S_IMODE($mode), "n"; my $is_setuid = $mode & S_ISUID; my $is_directory = S_ISDIR($mode);
Вы можете написать последние два, используя операторы -u и -d . Обычно доступные константы S_IF* :
S_IRWXU S_IRUSR S_IWUSR S_IXUSR S_IRWXG S_IRGRP S_IWGRP S_IXGRP S_IRWXO S_IROTH S_IWOTH S_IXOTH S_ISUID S_ISGID S_ISVTX S_ISTXT S_IFREG S_IFDIR S_IFLNK S_IFBLK S_IFCHR S_IFIFO S_IFSOCK S_IFWHT S_ENFMT S_IREAD S_IWRITE S_IEXEC
и S_IF* функции
S_IMODE($mode) the part of $mode containing the permission bits and the setuid/setgid/sticky bits S_IFMT($mode) the part of $mode containing the file type which can be bit-anded with (for example) S_IFREG or with the following functions S_ISREG($mode) S_ISDIR($mode) S_ISLNK($mode) S_ISBLK($mode) S_ISCHR($mode) S_ISFIFO($mode) S_ISSOCK($mode) S_ISENFMT($mode) S_ISWHT($mode)
См. документацию по chmod(2) и stat(2) для более подробной информации о константах S_* . Чтобы получить информацию о статусе для символической ссылки вместо целевого файла за ссылкой, используйте функцию lstat .
Проблемы с переносимостью: «stat» в perlport .
state объявляет переменную с лексической областью видимости, как и my . Однако эти переменные никогда не будут повторно инициализированы, в отличие от лексических переменных, которые повторно инициализируются каждый раз при вводе окружающего их блока. Подробнеесм. в разделе «Постоянные частные переменные» в perlsub .
Если указано более одной переменной, список должен быть заключен в круглые скобки. Со списком в скобках undef можно использовать в качестве фиктивного заполнителя. Однако, поскольку инициализация переменных состояния в таких списках в настоящее время невозможна, это бесполезно.
Повторное объявление переменной в той же области или операторе «затеняет» предыдущее объявление, создавая новый экземпляр и предотвращая доступ к предыдущему. Обычно это нежелательно и, если включены предупреждения, приведет к предупреждению в shadow категории.
state доступно только в том случае, если функция включена или если она имеет префикс CORE:: . Функция "state" включается автоматически с use v5.10 выше) в текущей области.
В настоящее время study ничего не делает. Это может измениться в будущем.
До версии Perl 5.16 он создавал инвертированный индекс всех символов, которые встречались в данном SCALAR (или $_ если не указано). При сопоставлении с шаблоном в этом индексе будет искать самый редкий символ из шаблона. Редкость была основана на некоторых статических таблицах частот, построенных из некоторых программ на языке C и текста на английском языке.
Это подпрограммное определение,а не реальная функция.per se. Без БЛОКА это просто предварительное объявление. Без NAME это объявление анонимной функции, поэтому оно возвращает значение: CODE ref только что созданного закрытия.
См. Perlsub и perlref для получения подробной информации о подпрограммах и ссылках; см. атрибуты и Attribute :: Handlers для получения дополнительной информации об атрибутах.
Специальный токен, который возвращает ссылку на текущую подпрограмму или undef вне подпрограммы.
Поведение __SUB__ в блоке кода регулярного выражения (например, /(?{...})/ ) может быть изменено.
Этот маркер доступен только при use v5.16 или "current_sub" особенности . См. Особенность .
Извлекает подстроку из EXPR и возвращает ее.Первый символ находится в нулевом смещении.Если OFFSET отрицательный,начинается так далеко от конца строки.Если LENGTH опущен,возвращает все через конец строки.Если LENGTH отрицательный,оставляет так много символов вне конца строки.
my $s = "The black cat climbed the green tree"; my $color = substr $s, 4, 5; my $middle = substr $s, 4, -11; my $end = substr $s, 14; my $tail = substr $s, -4; my $z = substr $s, -4, 2;
Вы можете использовать функцию substr как lvalue, и в этом случае EXPR сам должен быть lvalue. Если вы назначите что-то короче LENGTH, строка будет сокращаться, а если вы назначите что-то длиннее, чем LENGTH, строка будет расти, чтобы вместить это. Чтобы строка оставалась одинаковой длины, вам может потребоваться дополнить или нарезать ваше значение с помощью sprintf .
Если OFFSET и LENGTH указывают подстроку, которая частично находится за пределами строки, возвращается только часть внутри строки. Если подстрока находится за пределами любого конца строки, substr возвращает неопределенное значение и выдает предупреждение. При использовании в качестве lvalue указание подстроки, полностью находящейся за пределами строки, вызывает исключение. Вот пример, показывающий поведение для граничных случаев:
my $name = 'fred'; substr($name, 4) = 'dy'; my $null = substr $name, 6, 2; my $oops = substr $name, 7; substr($name, 7) = 'gap';
Альтернативой использованию substr в качестве lvalue является указание строки замены в качестве 4-го аргумента. Это позволяет вам заменять части EXPR и возвращать то, что было раньше, за одну операцию, так же, как вы можете со splice .
my $s = "The black cat climbed the green tree"; my $z = substr $s, 14, 7, "jumped from";
Обратите внимание, что lvalue, возвращаемое версией substr с тремя аргументами, действует как «волшебная пуля»; каждый раз, когда он назначается, он запоминает, какая часть исходной строки изменяется; Например:
my $x = '1234'; for (substr($x,1,2)) { $_ = 'a'; print $x,"n"; $_ = 'xyz'; print $x,"n"; $x = '56789'; $_ = 'pq'; print $x,"n"; }
При отрицательном смещении запоминает свою позицию с конца строки,когда изменяется целевая строка:
my $x = '1234'; for (substr($x, -3, 2)) { $_ = 'a'; print $x,"n"; $x = 'abcdefg'; print $_,"n"; }
До версии Perl 5.10 результат многократного использования значения l был неуказан.До версии 5.16 результат с отрицательными смещениями был неуказан.
Создает новое имя файла, символически связанное со старым именем файла. Возвращает 1 в случае успеха, 0 в противном случае. В системах, которые не поддерживают символические ссылки, возникает исключение. Чтобы проверить это, используйте eval:
my $symlink_exists = eval { symlink("",""); 1 };
Проблемы с переносимостью: «симлинк» в perlport .
Вызывает системный вызов, указанный как первый элемент списка, передавая оставшиеся элементы в качестве аргументов системному вызову. Если не реализовано, вызывает исключение. Аргументы интерпретируются следующим образом: если данный аргумент числовой, аргумент передается как int. В противном случае передается указатель на строковое значение. Вы несете ответственность за то, чтобы строка была предварительно расширена достаточно длинной, чтобы получить любой результат, который может быть записан в строку. Вы не можете использовать строковый литерал (или другую строку, syscall только для чтения) в качестве аргумента для системного вызова, потому что Perl должен предполагать, что любой строковый указатель может быть записан. Если ваши целочисленные аргументы не являются литералами и никогда не интерпретировались в числовом контексте, вам может потребоваться добавить 0 им, чтобы заставить их выглядеть как числа. Это имитирует функцию syswrite (или наоборот):
require 'syscall.ph'; my $s = "hi theren"; syscall(SYS_write(), fileno(STDOUT), $s, length $s);
Обратите внимание,что Perl поддерживает передачу до 14 аргументов в ваш системный звонок,чего на практике должно (обычно)быть достаточно.
Системный вызов возвращает любое значение, возвращаемое системным вызовом, который он вызывает. В случае сбоя системного вызова syscall возвращает -1 и устанавливает $! (эррно). Обратите внимание, что некоторые системные вызовыcanзаконно вернуть -1 . Правильный способ обработки таких вызовов — присвоить $! = 0 перед вызовом, затем проверьте значение $! если syscall возвращает -1 .
Есть проблема с syscall(SYS_pipe()) : он возвращает номер файла на прочитанном конце канала, который он создает, но нет способа получить номер файла на другом конце. Вы можете избежать этой проблемы, используя вместо этого pipe .
Проблемы с переносимостью: «syscall» в perlport .
Открывает файл, имя файла которого задано FILENAME, и связывает его с FILEHANDLE. Если FILEHANDLE является выражением, его значение используется как реальный дескриптор файла; неопределенный скаляр будет соответствующим образом автовивитирован. Эта функция вызывает функцию open (2) базовой операционной системы с параметрами FILENAME, MODE и PERMS.
Возвращает true в случае успеха и undef в противном случае.
Слои PerlIO будут применены к дескриптору так же, как при вызове open , который не определяет слои. То есть текущее значение ${^OPEN} установленное PERL_UNICODE open в лексической области, параметром командной строки -C или переменной среды PERL_UNICODE в области основной программы, возвращается к значениям платформы по умолчанию, как описано в разделе «Значения по умолчанию. и как их переопределить »в PerlIO . Если вы хотите удалить любые слои, которые могут преобразовывать поток байтов, используйте binmode после его открытия.
Возможные значения и биты флагов параметра MODE зависят от системы; они доступны через стандартный модуль Fcntl . См. Документацию по системному вызову open (2) вашей операционной системы, чтобы узнать, какие значения и биты флагов доступны. Вы можете комбинировать несколько флагов, используя | -оператор.
Некоторые из наиболее распространенных значений: O_RDONLY для открытия файла в режиме только для чтения, O_WRONLY для открытия файла в режиме только для записи и O_RDWR для открытия файла в режиме чтения-записи.
По историческим причинам,некоторые значения работают почти на каждой системе,поддерживаемой Perl:0 означает только чтение,1-только запись и 2-чтение/запись.Мы знаем,что эти значенияnotработа под OS/390; вы, вероятно, не хотите использовать их в новом коде.
Если файл с именем FILENAME не существует, а вызов open создает его (обычно из-за того, что MODE включает флаг O_CREAT ), то значение PERMS указывает разрешения вновь созданного файла. Если вы опустите аргумент PERMS для sysopen , Perl использует восьмеричное значение 0666 . Эти значения разрешений должны быть в восьмеричном формате и изменены текущим umask вашего процесса .
Во многих системах флаг O_EXCL доступен для открытия файлов в монопольном режиме. Это не блокировка: исключительность означает, что, если файл уже существует, sysopen не работает. O_EXCL может не работать в сетевых файловых системах и не действует, если также не O_CREAT флаг O_CREAT . Установка O_CREAT|O_EXCL предотвращает открытие файла, если это символическая ссылка. Он не защищает от символических ссылок в пути к файлу.
Иногда вам может потребоваться обрезать уже существующий файл. Это можно сделать с помощью флага O_TRUNC . Поведение O_TRUNC с O_RDONLY не определено.
Вы должны редко, если вообще когда-либо, использовать 0644 в качестве аргумента для sysopen , потому что это лишает пользователя возможности иметь более разрешающую umask. Лучше пропустить. Подробнее об этом см. на umask .
Эта функция не имеет прямого отношения к использованию sysread , syswrite или sysseek . Дескриптор, открытый с помощью этой функции, может использоваться с буферизованным вводом-выводом, так же как дескриптор, открытый с помощью open , может использоваться с небуферизованным вводом-выводом.
Обратите внимание, что в Perls старше 5.8.0 sysopen зависит от библиотечной функции fdopen (3) C. Известно, что во многих системах Unix fdopen (3) завершается ошибкой, когда файловые дескрипторы превышают определенное значение, обычно 255. Если вам нужно больше файловых дескрипторов, рассмотрите возможность использования функции POSIX::open . Для Perls 5.8.0 и новее PerlIO (чаще всего) используется по умолчанию.
См. Perlopentut для более доброго и мягкого объяснения открытия файлов.
Проблемы с переносимостью: «sysopen» в perlport .
Пытается прочитать LENGTH байтов данных в переменную SCALAR из указанного FILEHANDLE, используя read(2) . Он обходит все уровни PerlIO, включая буферизованный ввод-вывод (но на него влияет наличие слоя :utf8 , как описано ниже), поэтому смешивание этого с другими видами чтения, print , write , seek , tell или eof может вызвать путаницу, потому что :perlio Слои или :crlf обычно буферизируют данные.Возвращает количество фактически прочитанных байтов, 0 в конце файла или undef в случае ошибки (в последнем случае $! также установлено). SCALAR будет увеличиваться или уменьшаться, так что последний фактически прочитанный байт будет последним байтом скаляра после чтения.
СМЕЩЕНИЕ может быть указано для помещения считанных данных в какое-либо место в строке, кроме начала. Отрицательное СМЕЩЕНИЕ указывает размещение такого количества символов, считая в обратном порядке от конца строки. Положительное значение OFFSET, превышающее длину SCALAR, приводит к тому, что строка дополняется до требуемого размера байтами "" перед добавлением результата чтения.
Функция syseof() отсутствует, и это нормально, поскольку eof в любом случае плохо работает с файлами устройств (такими как ttys). Используйте sysread и проверьте возвращаемое значение 0, чтобы решить, закончили ли вы.
Обратите внимание, что если дескриптор файла был помечен как :utf8 , sysread выдаст исключение. :encoding(...) слой неявно вводит :utf8 слой. См. binmode , open и open pragma.
Устанавливает системную позицию FILEHANDLEin bytesиспользуя lseek (2) . FILEHANDLE может быть выражением, значение которого дает имя дескриптора файла. Значения WHENCE равны 0 , чтобы установить новую позицию в POSITION; 1 , чтобы установить его в текущее положение плюс POSITION; и 2 , чтобы установить его на EOF plus POSITION, обычно отрицательное.
Обратите внимание на байты: даже если дескриптор файла настроен на работу с символами (например, с использованием уровня ввода-вывода : :encoding(UTF-8) ), семейства функций seek , tell и sysseek используют байтовые смещения, а не смещения символов, потому что поиск смещения символов будет очень медленным в файле UTF-8.
sysseek обходит обычный буферизованный ввод-вывод, поэтому смешивание его с чтением, отличным от sysread (например, readline или read ), print , write , seek , tell или eof может вызвать путаницу.
Для WHENCE вы также можете использовать константы SEEK_SET , SEEK_CUR и SEEK_END (начало файла, текущая позиция, конец файла) из модуля Fcntl . Использование констант также более переносимо, чем использование 0, 1 и 2. Например, для определения функции «systell»:
use Fcntl 'SEEK_CUR'; sub systell { sysseek($_[0], 0, SEEK_CUR) }
Возвращает новую позицию или неопределенное значение в случае ошибки. Позиция нуля возвращается как строка "0 but true" ; таким образом, sysseek возвращает true в случае успеха и false в случае неудачи, но вы все равно можете легко определить новую позицию.
Делает то же самое, что и exec , за исключением того, что сначала выполняется ответвление, а родительский процесс ожидает завершения дочернего процесса. Обратите внимание, что обработка аргументов зависит от количества аргументов. Если в LIST имеется более одного аргумента или если LIST является массивом с более чем одним значением, запускает программу, заданную первым элементом списка, с аргументами, заданными остальной частью списка. Если есть только один скалярный аргумент, аргумент проверяется на метасимволы оболочки, и если они есть, весь аргумент передается в командную оболочку системы для анализа (это /bin/sh -c на платформах Unix, но /bin/sh -c от другие платформы). Если в аргументе нет метасимволов оболочки, он разбивается на слова и передается непосредственно в execvp ., что более эффективно. В Windows только system PROGRAM LIST надежно избегает использования оболочки; system LIST , даже с более чем одним элементом, вернется к оболочке, если первое создание не удастся.
Perl попытается очистить все файлы, открытые для вывода, перед любой операцией, которая может выполнить форк, но это может не поддерживаться на некоторых платформах (см. Perlport ). На всякий случай вам может потребоваться установить $| ( $AUTOFLUSH на английском языке ) или вызовите метод autoflush IO::Handle для любых открытых дескрипторов.
Возвращаемое значение — это статус выхода программы, возвращаемый вызовом wait . Чтобы получить фактическое значение выхода, сдвиньте вправо на восемь (см. ниже). См. также exec . Этоnotчто вы хотите использовать для захвата вывода команды; для этого вы должны использовать просто обратные кавычки или qx// , как описано в «STRING» в perlop . Возвращаемое значение -1 указывает на сбой при запуске программы или ошибку системного вызова wait (2) (проверьте причину $! ).
Если вы хотите, чтобы system (и многие другие части Perl) умирали при ошибке, взгляните на прагму autodie .
Подобно exec , system позволяет вам солгать программе о ее имени, если вы используете system PROGRAM LIST . Опять же, см. exec .
Поскольку SIGINT и SIGQUIT игнорируются во время выполнения system , если вы ожидаете, что ваша программа завершится при получении этих сигналов, вам нужно будет сделать это самостоятельно на основе возвращаемого значения.
my @args = ("command", "arg1", "arg2"); system(@args) == 0 or die "system @args failed: $?";
Если вы хотите вручную проверить сбой system , вы можете проверить все возможные режимы сбоя, проверив $? как это:
if ($? == -1) { print "failed to execute: $!n"; } elsif ($? & 127) { printf "child died with signal %d, %s coredumpn", ($? & 127), ($? & 128) ? 'with' : 'without'; } else { printf "child exited with value %dn", $? >> 8; }
В качестве альтернативы вы можете проверить значение ${^CHILD_ERROR_NATIVE} с помощью вызовов W*() из модуля POSIX .
Когда system аргументы выполняются оболочкой косвенно, результаты и коды возврата зависят от ее особенностей. Подробнее см. «STRING» в perlop и exec .
Поскольку system делает fork и wait , это может повлиять на обработчик SIGCHLD . Подробности смотрите в Perlipc .
Проблемы переносимости: «система» в perlport .
Пытается записать LENGTH байтов данных из переменной SCALAR в указанный FILEHANDLE, используя write(2) . Если ДЛИНА не указана, записывает весь СКАЛЯР. Он обходит все уровни PerlIO, включая буферизованный ввод-вывод (но на него влияет наличие слоя :utf8 , как описано ниже), поэтому смешивание этого с операциями чтения (кроме sysread) ), print , write , seek , tell или eof может вызвать путаницу. потому что слои :perlio и :crlf обычно буферизируют данные. Возвращает количество фактически записанных байтов или undef если произошла ошибка (в этом случае также устанавливается переменная errno $! ).Если LENGTH больше, чем данные, доступные в SCALAR после OFFSET, будет записано столько данных, сколько доступно.
Для записи данных из какой-то части строки,отличной от начала,может быть задан OFFSET.Отрицательный OFFSET указывает на запись,при которой многие символы отсчитываются от конца строки.Если SCALAR имеет нулевую длину,можно использовать только OFFSET,равный 0.
ВНИМАНИЕ : Если дескриптор файла отмечен :utf8 , syswrite вызовет исключение. :encoding(...) слой неявно вводит :utf8 слой. В качестве альтернативы, если дескриптор не помечен кодировкой, но вы пытаетесь записать символы с кодовыми точками более 255, возникает исключение. См. binmode , open и open pragma.
Возвращает текущую позициюin bytesдля FILEHANDLE,или -1 по ошибке.FILEHANDLE может быть выражением,значение которого дает имя реального файла-обработчика.Если FILEHANDLE опущена,предполагает,что файл был прочитан последним.
Обратите внимание на байты: даже если дескриптор файла настроен на работу с символами (например, с использованием уровня ввода-вывода : :encoding(UTF-8) ), семейства функций seek , tell и sysseek используют байтовые смещения, а не смещения символов, потому что поиск смещения символов будет очень медленным в файле UTF-8.
Возвращаемое значение tell для стандартных потоков, таких как STDIN, зависит от операционной системы: оно может возвращать -1 или что-то еще. tell на каналах, fifos и сокетах обычно возвращает -1.
Там нет systell функции. Используйте для этого sysseek($fh, 0, 1) .
Не используйте tell (или другие буферизованные операции ввода-вывода) для дескриптора файла, которым управляли sysread , syswrite или sysseek . Эти функции игнорируют буферизацию, а tell — нет.
Возвращает текущую позицию подпрограмм readdir в DIRHANDLE. seekdir может быть присвоено для доступа к определенному местоположению в каталоге. telldir содержит те же предупреждения о возможном сжатии каталогов, что и соответствующая процедура системной библиотеки.
Эта функция связывает переменную с классом пакета, который обеспечивает реализацию переменной. ПЕРЕМЕННАЯ — это имя зачаровываемой переменной. CLASSNAME — это имя класса, реализующего объекты правильного типа. Любые дополнительные аргументы передаются соответствующему методу конструктора класса (имеется в виду TIESCALAR , TIEHANDLE , TIEARRAY или TIEHASH ). Обычно эти аргументы , такие как может быть переданы в dbm_open (3) функцию С. Объект , возвращаемый конструктор также возвращенный tie функции, которая была бы полезна , если вы хотите получить доступ к другим методам в Classname.
Обратите внимание, что такие функции, как keys и values , могут возвращать огромные списки при использовании с большими объектами, такими как файлы DBM. Вы можете предпочесть использовать функцию each для перебора таких элементов. Пример:
use NDBM_File; tie(my %HIST, 'NDBM_File', '/usr/lib/news/history', 1, 0); while (my ($key,$val) = each %HIST) { print $key, ' = ', unpack('L', $val), "n"; }
Класс,реализующий хэш,должен иметь следующие методы:
TIEHASH classname, LIST FETCH this, key STORE this, key, value DELETE this, key CLEAR this EXISTS this, key FIRSTKEY this NEXTKEY this, lastkey SCALAR this DESTROY this UNTIE this
Класс,реализующий обычный массив,должен иметь следующие методы:
TIEARRAY classname, LIST FETCH this, key STORE this, key, value FETCHSIZE this STORESIZE this, count CLEAR this PUSH this, LIST POP this SHIFT this UNSHIFT this, LIST SPLICE this, offset, length, LIST EXTEND this, count DELETE this, key EXISTS this, key DESTROY this UNTIE this
Класс,реализующий файловую обработку,должен иметь следующие методы:
TIEHANDLE classname, LIST READ this, scalar, length, offset READLINE this GETC this WRITE this, scalar, length, offset PRINT this, LIST PRINTF this, format, LIST BINMODE this EOF this FILENO this SEEK this, position, whence TELL this OPEN this, mode, LIST CLOSE this DESTROY this UNTIE this
Класс,реализующий скаляр,должен иметь следующие методы:
TIESCALAR classname, LIST FETCH this, STORE this, value DESTROY this UNTIE this
Не все методы, указанные выше, должны быть реализованы. См. Perltie , Tie :: Hash , Tie :: Array , Tie :: Scalar и Tie :: Handle .
В отличие от dbmopen , функция tie не будет use require для вас; вам нужно сделать это явно самостоятельно. См. DB_File или модуль Config для интересных реализаций tie .
Для получения дополнительной информации см. perltie , tied .
Возвращает ссылку на объект , лежащий в основе переменной (то же самое значение , которое было первоначально возвращаемой tie вызова, связанного переменную к пакету.) Возвращает неопределенное значение , если переменная не связана с пакетом.
Возвращает количество невисокосных секунд с любого времени, которое система считает эпохой, подходящей для передачи в gmtime и localtime . В большинстве систем эпоха — 00:00:00 UTC, 1 января 1970 года; заметным исключением является Mac OS Classic, в которой используется 00:00:00 1 января 1904 года в текущем местном часовом поясе для своей эпохи.
Для измерения времени с большей степенью детализации, чем одна секунда, используйте модуль Time :: HiRes начиная с Perl 5.8 (или из CPAN до этого), или, если у вас есть gettimeofday (2) , вы можете использовать интерфейс syscall Perl . Подробности смотрите в perlfaq8 .
Для обработки даты и времени просмотрите множество связанных модулей на CPAN. Для полного представления даты и времени посмотрите модуль DateTime .
Возвращает четырехэлементный список с указанием времени пользователя и системы в секундах для этого процесса и любых покинутых детей этого процесса.
my ($user,$system,$cuser,$csystem) = times;
В скалярном контексте times возвращает $user .
Детское время учитывается только для уволенных детей.
Проблемы с переносимостью: «times» в perlport .
Оператор транслитерации. То же, что y/// . См. «Операторы, подобные кавычкам» в perlop .
Усекает файл, открытый в FILEHANDLE или названный EXPR, до указанной длины. Вызывает исключение, если усечение не реализовано в вашей системе. Возвращает true в случае успеха, undef в случае ошибки.
Поведение не определено,если LENGTH больше длины файла.
Позиция в файле FILEHANDLE остается неизменной. Вы можете вызвать функцию seek перед записью в файл.
Проблемы с переносимостью: «усечение» в perlport .
Возвращает версию EXPR в верхнем регистре. Если EXPR опущен, используется $_ .
my $str = uc("Perl is GREAT");
Эта функция ведет себя одинаково с различными прагмами, например, в локали, как это делает lc .
Если вы хотите, чтобы заглавные буквы отображались на начальных буквах, см. вместо этого ucfirst .
Примечание. Это внутренняя функция, реализующая экранирование U в строках с двойными кавычками.
my $str = "Perl is UgreatE";
Возвращает значение EXPR с первым символом в верхнем регистре (регистр заголовка в Юникоде). Это внутренняя функция, реализующая экранирование u в строках, заключенных в двойные кавычки.
Если EXPR опущен, используется $_ .
Эта функция ведет себя одинаково с различными прагмами, например, в локали, как это делает lc .
Устанавливает маску процесса в EXPR и возвращает предыдущее значение.Если EXPR опущен,просто возвращает текущую маску.
Разрешение Unix rwxr-x--- представлено в виде трех наборов из трех битов или трех восьмеричных цифр: 0750 (начальный 0 указывает восьмеричное число и не является одной из цифр). Значение umask — это число, представляющее биты отключенных разрешений. Значения разрешения (или «режима»), которые вы передаете mkdir или sysopen , изменяются вашим umask, поэтому, даже если вы скажете sysopen создать файл с разрешениями 0777 , если ваш umask равен 0022 , то файл будет фактически создан с разрешениями 0755 . . Если бы ваш umask был 0027 (группа не может писать; другие не могут читать, писать или выполнять), то передача sysopen 0666 создаст файл с режимом 0640 (поскольку 0666 &~ 027 равно 0640 ).
Вот несколько советов: sysopen режим создания 0666 для обычных файлов (в sysopen ) и один из 0777 для каталогов (в mkdir ) и исполняемых файлов. Это дает пользователям свободу выбора: если им нужны защищенные файлы, они могут выбрать umasks процесса 022 , 027 или даже особенно антисоциальную маску 077 . Программы должны редко, если вообще когда-либо, принимать политические решения, лучше оставляя их на усмотрение пользователя. Исключением является запись файлов, которые должны оставаться конфиденциальными: почтовые файлы, файлы cookie веб-браузера,.rhostsфайлы и так далее.
Если umask (2) не реализован в вашей системе, и вы пытаетесь ограничить доступ дляyourself(т. е. (EXPR & 0700) > 0 ) вызывает исключение. Если umask(2) не реализован и вы не пытаетесь ограничить доступ для себя, возвращает undef .
Помните,что маска-это число,обычно заданное восьмеричным числом;этоnotстрока восьмеричных цифр. См. также oct , если все, что у вас есть, это строка.
Проблемы с переносимостью: «umask» в perlport .
Отменяет определение значения EXPR, которое должно быть lvalue. Используйте только скалярное значение, массив (используя @ ), хэш (используя % ), подпрограмму (используя & ) или typeglob (используя * ). Выражение undef $hash{$key} , вероятно, не будет делать то, что вы ожидаете от большинства предопределенных переменных или значений списка DBM, поэтому не делайте этого; см delete . Всегда возвращает неопределенное значение. Вы можете опустить EXPR, и в этом случае ничего не будет неопределенным, но вы все равно получите неопределенное значение, которое вы можете, например, вернуть из подпрограммы, присвоить переменной или передать в качестве параметра. Примеры:
undef $foo; undef $bar{'blurfl'}; undef @ary; undef %hash; undef &mysub; undef *xyz; return (wantarray ? (undef, $errmsg) : undef) if $they_blew_it; select undef, undef, undef, 0.25; my ($x, $y, undef, $z) = foo();
Обратите внимание,что это унарный оператор,а не оператор списка.
Удаляет список файлов. В случае успеха он возвращает количество успешно удаленных файлов. В случае неудачи возвращает false и устанавливает $! (ошибка):
my $unlinked = unlink 'a', 'b', 'c'; unlink @goners; unlink glob "*.bak";
В случае ошибки unlink не сообщит вам, какие файлы не удалось удалить. Если вы хотите узнать, какие файлы вы не смогли удалить, попробуйте их по одному:
foreach my $file ( @goners ) { unlink $file or warn "Could not unlink $file: $!"; }
Примечание: unlink не будет пытаться удалить каталоги, если вы не являетесь суперпользователем и в Perl не указан флаг -U . Даже если эти условия соблюдены, имейте в виду, что удаление каталога может нанести ущерб вашей файловой системе. Наконец, использование unlink на каталоги не поддерживается во многих операционных системах. Вместо этого используйте rmdir .
Если LIST опущен, unlink используется $_ .
unpack делает обратное pack : берет строку и разворачивает ее в список значений. (В скалярном контексте он возвращает только первое полученное значение.)
Если EXPR не указан, распаковывает строку $_ . См. Perlpacktut для ознакомления с этой функцией.
Строка разбита на части, описанные ШАБЛОНОМ. Каждый фрагмент отдельно преобразуется в значение. Обычно либо строка является результатом pack , либо символы строки представляют собой какую-либо структуру C.
ШАБЛОН имеет тот же формат, что и функция pack . Вот подпрограмма, которая выполняет подстроку:
sub substr { my ($what, $where, $howmuch) = @_; unpack("x$where a$howmuch", $what); }
и вот
sub ordinal { unpack("W",$_[0]); }
В дополнение к полям, разрешенным в pack , вы можете добавить к полю префикс% <number>, чтобы указать, что вам нужна <number> -битовая контрольная сумма элементов вместо самих элементов. По умолчанию — 16-битная контрольная сумма. Контрольная сумма вычисляется путем суммирования числовых значений развернутых значений (для строковых полей берется сумма ord($char) ; для битовых полей сумма нулей и единиц).
Например,ниже вычисляется то же число,что и программа System V sum:
my $checksum = do { local $/; unpack("%32W*", readline) % 65535; };
Ниже эффективно подсчитывается количество заданных битов в битовом векторе:
my $setbits = unpack("%32b*", $selectmask);
В p и P форматы следует использовать с осторожностью. Поскольку Perl не имеет возможности проверить, соответствует ли значение, переданное для unpack , допустимому месту в памяти, передача неизвестного значения указателя может иметь катастрофические последствия.
Если имеется больше кодов упаковки или если количество повторов поля или группы больше, чем позволяет оставшаяся часть входной строки, результат не определен должным образом: количество повторов может быть уменьшено, или unpack может привести к пустым строкам или нули, или это может вызвать исключение. Если входная строка длиннее, чем та, что описана в ШАБЛОНЕ, оставшаяся часть этой входной строки игнорируется.
См. pack для дополнительных примеров и примечаний.
Делает противоположное shift . Или наоборот push push в зависимости от того, как вы на это смотрите. Добавляет список в начало массива и возвращает новое количество элементов в массиве.
unshift(@ARGV, '-e') unless $ARGV[0] =~ /^-/;
Обратите внимание, что СПИСОК добавляется целиком, а не по одному элементу за раз, поэтому предшествующие элементы остаются в том же порядке. Используйте reverse , чтобы сделать обратное.
Начиная с Perl 5.14, экспериментальная функция позволяла unshift принимать скалярное выражение. Этот эксперимент был признан неудачным и был удален в Perl 5.24.
Разрывает связь между переменной и пакетом. (См. Связь .) Не действует, если переменная не привязана.
Импортирует некоторую семантику в текущий пакет из модуля с именем,как правило,с помощью наложения псевдонимов на определенные имена подпрограмм или переменных в вашем пакете.Это в точности эквивалентно
BEGIN { require Module; Module->import( LIST ); }
кроме того,что Модульmustбыть голым словом. Импорт можно сделать условным с помощью модуля if .
BEGIN заставляет require и import BEGIN компиляции. Требование гарантирует, что модуль загружен в память, если это еще не было сделано require Импорт не является встроенным import это просто вызов обычного статического метода в пакете Module , чтобы указать модулю импортировать список функций обратно в текущий пакет. Модуль может реализовать свой метод import любым удобным для него способом, хотя большинство модулей просто выбирают получение своего метода import через наследование от класса Exporter , который определен в модуле Exporter . См. Экспортер . Если нет import , то вызов пропускается, даже если есть метод AUTOLOAD.
Если вы не хотите вызывать метод import пакета (например, чтобы предотвратить изменение вашего пространства имен), явно укажите пустой список:
use Module ();
Это в точности эквивалентно
BEGIN { require Module }
Если аргумент VERSION присутствует между Module и LIST, то использование use метод VERSION в классе Module с данной версией в качестве аргумента:
use Module 12.34;
эквивалентно:
BEGIN { require Module; Module->VERSION(12.34) }
По умолчанию VERSION метод , унаследованные от UNIVERSAL класса, хрипит , если данная версия больше , чем значение переменных $Module::VERSION .
Аргумент VERSION не может быть произвольным выражением. Он считается аргументом ВЕРСИЯ, только если это литерал номера версии, начинающийся либо с цифры, либо с v , за которым следует цифра. Все, что не похоже на литерал версии, будет анализироваться как начало СПИСКА. Тем не менее, многие попытки использовать произвольное выражение в качестве аргумента VERSION будет появляться на работу, потому что экспортер «s import метод обрабатывает числовые аргументы специально, выполняя проверки версий , а не рассматривать их как вещи для экспорта.
Опять же, существует различие между пропуском СПИСКА ( import вызывается без аргументов) и явным пустым СПИСКОМ () ( import не вызывается). Обратите внимание, что после ВЕРСИИ запятая не ставится!
Поскольку это широко открытый интерфейс,прагмы (директивы компилятора)также реализованы таким образом.В настоящее время реализованы следующие прагмы:
use constant; use diagnostics; use integer; use sigtrap qw(SEGV BUS); use strict qw(subs vars refs); use subs qw(afunc blurfl); use warnings qw(all); use sort qw(stable);
Некоторые из этих псевдомодулей импортируют семантику в текущую область видимости блока (например, strict или integer , в отличие от обычных модулей, которые импортируют символы в текущий пакет (которые действуют до конца файла).
Поскольку use вступает в силу во время компиляции, оно не учитывает обычное управление потоком компилируемого кода. В частности, помещение use в ложную ветвь условного оператора не препятствует его обработке. Если модуль или прагму нужно загрузить только условно, это можно сделать с помощью прагмы if :
use if $] < 5.008, "utf8"; use if WANT_WARNINGS, warnings => qw(all);
Существует соответствующее объявление no , которое отменяет импорт значений, импортированных с помощью use , т. е. вызывает Module->unimport(LIST) вместо import . Он ведет себя так же, как import с VERSION, пропущенным или пустым LIST или не найденным методом unimport.
no integer; no strict 'refs'; no warnings;
См. список стандартных модулей и прагм в perlmodlib . См. Perlrun для параметров командной строки -M и -m для Perl,которые позволяют use функциональные возможности из командной строки.
Лексически включает все функции, доступные в запрошенной версии, как определено прагмой feature , отключая все функции, не входящие в набор функций запрошенной версии. См. особенность .
VERSION может быть либо v-строкой, такой как v5.24.1, которая будет сравниваться с $^V (она же $PERL_VERSION), либо числовым аргументом вида 5.024001, который будет сравниваться с $] . Исключение возникает, если VERSION больше, чем версия текущего интерпретатора Perl; Perl не будет пытаться анализировать остальную часть файла. Сравните с require , который может выполнять аналогичную проверку во время выполнения.
Если указана версия Perl 5.12 или выше, ограничения включаются лексически, как и при use strict . Точно так же, если указана версия Perl 5.35.0 или выше, предупреждения включены. Последующее использование use VERSION переопределит все поведение предыдущего use VERSION , возможно, удалив strict , warnings и добавленную им feature use VERSION не загружаетfeature.pm,strict.pm, orwarnings.pmfiles.
В текущей реализации любое явное использование переопределений use strict или no strict use VERSION , даже если оно предшествует ему. Однако это может быть изменено в будущем выпуске Perl, поэтому новый код не должен полагаться на этот факт. Рекомендуется, чтобы объявление use VERSION было первым значимым оператором в файле (возможно, после оператора package или любого количества пробелов или комментариев), чтобы его эффекты срабатывали первыми, а другие прагмы применялись после него.
Как правило, следует избегать указания ВЕРСИИ в качестве числового аргумента формы 5.024001, так как синтаксис более старый и менее читаемый по сравнению с версией 5.24.1. До Perl 5.8.0, выпущенного в 2002 году, единственным поддерживаемым синтаксисом была более подробная числовая форма, поэтому вы могли видеть ее в старом коде.
use v5.24.1; use 5.24.1; use 5.024_001;
Это часто бывает полезно, если вам нужно проверить текущую версию Perl перед use библиотечных модулей, которые не будут работать со старыми версиями Perl. (Мы стараемся не делать этого больше, чем необходимо.)
Симметрично, no VERSION позволяет вам указать, что вам нужна версия Perl старше указанной. Исторически это было добавлено во время ранних разработок языка Raku (ранее «Perl 6»), так что программа Perl 5 могла начаться.
no 6;
объявить, что это не программа Perl 6. Поскольку эти два языка имеют разные реализации, соглашения об именах файлов и другую инфраструктуру, эта функция в настоящее время мало используется на практике, и ее следует избегать в новом коде.
Следует соблюдать осторожность при использовании формы no VERSION , так как онаonlyпредназначенный для того,чтобы утверждать,что запущенный Perl имеет более раннюю версию,чем его аргумент иnotчтобы отменить побочные эффекты включения функции use VERSION .
Изменяет время доступа и модификации для каждого файла в списке файлов. Первые два элемента списка должны быть ЧИСЛОМ времени доступа и модификации в указанном порядке. Возвращает количество успешно измененных файлов. Время изменения inode каждого файла устанавливается на текущее время. Например, этот код имеет тот же эффект, что и команда Touch (1) Unix, когда файлыalready existи принадлежат пользователю,выполняющему программу:
my $atime = my $mtime = time; utime $atime, $mtime, @ARGV;
Начиная с Perl 5.8.0, если первые два элемента списка равны undef , системный вызов utime(2) из вашей библиотеки C вызывается с нулевым аргументом секунды. В большинстве систем это установит время доступа и модификации файла к текущему времени (т. е. эквивалентно приведенному выше примеру) и будет работать даже с файлами, которыми вы не владеете, если у вас есть разрешение на запись:
for my $file (@ARGV) { utime(undef, undef, $file) || warn "Couldn't touch $file: $!"; }
В NFS будет использоваться время сервера NFS, а не время локальной машины. Если есть проблема синхронизации времени, сервер NFS и локальный компьютер будут иметь разное время. На самом деле команда Unix touch (1) обычно использует эту форму вместо формы, показанной в первом примере.
Передача только одного из первых двух элементов как undef эквивалентна передаче 0 и не будет иметь описанного эффекта, когда оба являются undef . Это также вызывает неинициализированное предупреждение.
В системах, поддерживающих futimes (2) , вы можете передавать дескрипторы файлов между файлами. В системах, которые не поддерживают futimes (2) , передача дескрипторов файлов вызывает исключение. Для распознавания дескрипторы файлов должны передаваться как глобусы или ссылки на глобусы; голые слова считаются именами файлов.
Проблемы с переносимостью: «utime» в perlport .
В контексте списка возвращает список,состоящий из всех значений именованного хэша.Только в версии Perl 5.12 или более поздней,также возвращается список значений массива;до этого выпуска попытка использовать аргумент массива приведет к синтаксической ошибке.В скалярном контексте возвращает количество значений.
Записи хеша возвращаются в случайном порядке. Фактический случайный порядок зависит от данного хэша; одна и та же последовательность операций над двумя хэшами может привести к различному порядку для каждого хеша. Любая вставка в хэш может изменить порядок, как и любое удаление, за исключением того, что самый последний ключ, возвращаемый каждым each ключами keys может быть удален без изменения порядка. Пока данный хэш не изменен, вы можете полагаться на keys , values и each , чтобы многократно возвращать тот же порядок, что и друг друга. См. «Атаки алгоритмической сложности» в perlsec.для получения подробной информации о том, почему порядок хэширования рандомизирован. Помимо приведенных здесь гарантий, точные детали алгоритма хеширования Perl и порядок обхода хэша могут быть изменены в любом выпуске Perl. Связанные хэши могут вести себя иначе, чем хэши Perl, в отношении изменения порядка вставки и удаления элементов.
В качестве побочного эффекта вызов values сбрасывает внутренний итератор HASH или ARRAY (см. each ) перед получением значений. В частности, вызов values в пустом контексте сбрасывает итератор без дополнительных затрат.
Помимо сброса итератора, values @array в контексте списка совпадают с обычным @array . (Мы рекомендуем вам использовать для этого keys @array контекстные ключи @array , но рассудили, что получение values @array из массива потребует больше документации, чем оставление его внутри.)
Обратите внимание,что значения не копируются,что означает,что их изменение приведет к изменению содержимого хэша:
for (values %hash) { s/foo/bar/g } for (@hash{keys %hash}) { s/foo/bar/g }
Начиная с Perl 5.14, экспериментальная функция позволяла values принимать скалярное выражение. Этот эксперимент был признан неудачным и был удален с версии Perl 5.24.
Чтобы избежать путаницы потенциальных пользователей вашего кода,которые работают с более ранними версиями Perl,с загадочными синтаксическими ошибками,поместите такие вещи в верхнюю часть файла,чтобы показать,что ваш код будет работать.onlyна Перлс недавнего винтажа:
use v5.12;
См. также keys , each и sort .
Рассматривает строку в EXPR как битовый вектор,состоящий из элементов ширины BITS и возвращает значение элемента,заданного OFFSET как беззнаковое целое число.Следовательно,BITS определяет количество бит,которое зарезервировано для каждого элемента в битовом векторе.Это должно быть два значения от 1 до 32 (или 64,если ваша платформа это поддерживает).
Если BITS равен 8,то «элементы» совпадают с байтами входной строки.
Если BITS составляет 16 или более, байты входной строки группируются в блоки размером BITS / 8, и каждая группа преобразуется в число, как при pack / unpack с прямым порядком байтов n / N (и аналогично для BITS == 64). См. Подробности в pack .
Если битов 4 или меньше, строка разбивается на байты, затем биты каждого байта разбиваются на группы 8 / BITS. Биты байта нумеруются с 0x08 байтов, как в 0x01 , 0x02 , 0x04 , 0x08 , 0x10 , 0x20 , 0x40 , 0x80 . Например, chr(0x36) одного входного байта chr (0x36) на две группы дает список (0x6, 0x3) ; разбив его на 4 группы, вы (0x2, 0x1, 0x3, 0x0) .
vec также может быть назначено, и в этом случае скобки необходимы, чтобы дать выражению правильный приоритет, как в
vec($image, $max_x * $x + $y, 8) = 3;
Если выбранный элемент находится вне строки,возвращается значение 0.Если элемент,находящийся вне конца строки,записан,то Perl сначала расширит строку на достаточное количество нулевых байт.Ошибкой является попытка списания начала строки (т.е.отрицательный OFFSET).
Если строка внутренне закодирована как UTF-8 (и, следовательно, имеет установленный флаг UTF8), vec пытается преобразовать ее, чтобы использовать внутреннее представление с одним байтом на символ. Однако, если строка содержит символы со значениями 256 или выше, произойдет фатальная ошибка.
Строками, созданными с помощью vec , также можно манипулировать с помощью логических операторов | , & , ^ и ~ . Эти операторы предполагают, что операция с битовым вектором желательна, когда оба операнда являются строками. См. «Побитовые строковые операторы» в perlop .
Следующий код создаст строку ASCII с надписью 'PerlPerlPerl' . В комментариях отображается строка после каждого шага. Обратите внимание, что этот код работает одинаково на машинах с прямым или обратным порядком байтов.
my $foo = ''; vec($foo, 0, 32) = 0x5065726C; print vec($foo, 0, 8); vec($foo, 2, 16) = 0x5065; vec($foo, 3, 16) = 0x726C; vec($foo, 8, 8) = 0x50; vec($foo, 9, 8) = 0x65; vec($foo, 20, 4) = 2; vec($foo, 21, 4) = 7; vec($foo, 45, 2) = 3; vec($foo, 93, 1) = 1; vec($foo, 94, 1) = 1;
Чтобы преобразовать битовый вектор в строку или список 0 и 1,используйте эти:
my $bits = unpack("b*", $vector); my @bits = split(//, unpack("b*", $vector));
Если вам известна точная длина в битах, ее можно использовать вместо * .
Вот пример,чтобы проиллюстрировать,как биты на самом деле падают на место:
print <<'EOT'; 0 1 2 3 unpack("V",$_) 01234567890123456789012345678901 ------------------------------------------------------------------ EOT for $w (0..3) { $width = 2**$w; for ($shift=0; $shift < $width; ++$shift) { for ($off=0; $off < 32/$width; ++$off) { $str = pack("B*", "0"x32); $bits = (1<<$shift); vec($str, $off, $width) = $bits; $res = unpack("b*",$str); $val = unpack("V", $str); write; } } } format STDOUT = vec($_,@#,@#) = @<< == @# $off, $width, $bits, $val, $res . __END__
Независимо от архитектуры машины,на которой он работает,пример выше должен печатать следующую таблицу:
0 1 2 3 unpack("V",$_) 01234567890123456789012345678901 ------------------------------------------------------------------ vec($_, 0, 1) = 1 == 1 10000000000000000000000000000000 vec($_, 1, 1) = 1 == 2 01000000000000000000000000000000 vec($_, 2, 1) = 1 == 4 00100000000000000000000000000000 vec($_, 3, 1) = 1 == 8 00010000000000000000000000000000 vec($_, 4, 1) = 1 == 16 00001000000000000000000000000000 vec($_, 5, 1) = 1 == 32 00000100000000000000000000000000 vec($_, 6, 1) = 1 == 64 00000010000000000000000000000000 vec($_, 7, 1) = 1 == 128 00000001000000000000000000000000 vec($_, 8, 1) = 1 == 256 00000000100000000000000000000000 vec($_, 9, 1) = 1 == 512 00000000010000000000000000000000 vec($_,10, 1) = 1 == 1024 00000000001000000000000000000000 vec($_,11, 1) = 1 == 2048 00000000000100000000000000000000 vec($_,12, 1) = 1 == 4096 00000000000010000000000000000000 vec($_,13, 1) = 1 == 8192 00000000000001000000000000000000 vec($_,14, 1) = 1 == 16384 00000000000000100000000000000000 vec($_,15, 1) = 1 == 32768 00000000000000010000000000000000 vec($_,16, 1) = 1 == 65536 00000000000000001000000000000000 vec($_,17, 1) = 1 == 131072 00000000000000000100000000000000 vec($_,18, 1) = 1 == 262144 00000000000000000010000000000000 vec($_,19, 1) = 1 == 524288 00000000000000000001000000000000 vec($_,20, 1) = 1 == 1048576 00000000000000000000100000000000 vec($_,21, 1) = 1 == 2097152 00000000000000000000010000000000 vec($_,22, 1) = 1 == 4194304 00000000000000000000001000000000 vec($_,23, 1) = 1 == 8388608 00000000000000000000000100000000 vec($_,24, 1) = 1 == 16777216 00000000000000000000000010000000 vec($_,25, 1) = 1 == 33554432 00000000000000000000000001000000 vec($_,26, 1) = 1 == 67108864 00000000000000000000000000100000 vec($_,27, 1) = 1 == 134217728 00000000000000000000000000010000 vec($_,28, 1) = 1 == 268435456 00000000000000000000000000001000 vec($_,29, 1) = 1 == 536870912 00000000000000000000000000000100 vec($_,30, 1) = 1 == 1073741824 00000000000000000000000000000010 vec($_,31, 1) = 1 == 2147483648 00000000000000000000000000000001 vec($_, 0, 2) = 1 == 1 10000000000000000000000000000000 vec($_, 1, 2) = 1 == 4 00100000000000000000000000000000 vec($_, 2, 2) = 1 == 16 00001000000000000000000000000000 vec($_, 3, 2) = 1 == 64 00000010000000000000000000000000 vec($_, 4, 2) = 1 == 256 00000000100000000000000000000000 vec($_, 5, 2) = 1 == 1024 00000000001000000000000000000000 vec($_, 6, 2) = 1 == 4096 00000000000010000000000000000000 vec($_, 7, 2) = 1 == 16384 00000000000000100000000000000000 vec($_, 8, 2) = 1 == 65536 00000000000000001000000000000000 vec($_, 9, 2) = 1 == 262144 00000000000000000010000000000000 vec($_,10, 2) = 1 == 1048576 00000000000000000000100000000000 vec($_,11, 2) = 1 == 4194304 00000000000000000000001000000000 vec($_,12, 2) = 1 == 16777216 00000000000000000000000010000000 vec($_,13, 2) = 1 == 67108864 00000000000000000000000000100000 vec($_,14, 2) = 1 == 268435456 00000000000000000000000000001000 vec($_,15, 2) = 1 == 1073741824 00000000000000000000000000000010 vec($_, 0, 2) = 2 == 2 01000000000000000000000000000000 vec($_, 1, 2) = 2 == 8 00010000000000000000000000000000 vec($_, 2, 2) = 2 == 32 00000100000000000000000000000000 vec($_, 3, 2) = 2 == 128 00000001000000000000000000000000 vec($_, 4, 2) = 2 == 512 00000000010000000000000000000000 vec($_, 5, 2) = 2 == 2048 00000000000100000000000000000000 vec($_, 6, 2) = 2 == 8192 00000000000001000000000000000000 vec($_, 7, 2) = 2 == 32768 00000000000000010000000000000000 vec($_, 8, 2) = 2 == 131072 00000000000000000100000000000000 vec($_, 9, 2) = 2 == 524288 00000000000000000001000000000000 vec($_,10, 2) = 2 == 2097152 00000000000000000000010000000000 vec($_,11, 2) = 2 == 8388608 00000000000000000000000100000000 vec($_,12, 2) = 2 == 33554432 00000000000000000000000001000000 vec($_,13, 2) = 2 == 134217728 00000000000000000000000000010000 vec($_,14, 2) = 2 == 536870912 00000000000000000000000000000100 vec($_,15, 2) = 2 == 2147483648 00000000000000000000000000000001 vec($_, 0, 4) = 1 == 1 10000000000000000000000000000000 vec($_, 1, 4) = 1 == 16 00001000000000000000000000000000 vec($_, 2, 4) = 1 == 256 00000000100000000000000000000000 vec($_, 3, 4) = 1 == 4096 00000000000010000000000000000000 vec($_, 4, 4) = 1 == 65536 00000000000000001000000000000000 vec($_, 5, 4) = 1 == 1048576 00000000000000000000100000000000 vec($_, 6, 4) = 1 == 16777216 00000000000000000000000010000000 vec($_, 7, 4) = 1 == 268435456 00000000000000000000000000001000 vec($_, 0, 4) = 2 == 2 01000000000000000000000000000000 vec($_, 1, 4) = 2 == 32 00000100000000000000000000000000 vec($_, 2, 4) = 2 == 512 00000000010000000000000000000000 vec($_, 3, 4) = 2 == 8192 00000000000001000000000000000000 vec($_, 4, 4) = 2 == 131072 00000000000000000100000000000000 vec($_, 5, 4) = 2 == 2097152 00000000000000000000010000000000 vec($_, 6, 4) = 2 == 33554432 00000000000000000000000001000000 vec($_, 7, 4) = 2 == 536870912 00000000000000000000000000000100 vec($_, 0, 4) = 4 == 4 00100000000000000000000000000000 vec($_, 1, 4) = 4 == 64 00000010000000000000000000000000 vec($_, 2, 4) = 4 == 1024 00000000001000000000000000000000 vec($_, 3, 4) = 4 == 16384 00000000000000100000000000000000 vec($_, 4, 4) = 4 == 262144 00000000000000000010000000000000 vec($_, 5, 4) = 4 == 4194304 00000000000000000000001000000000 vec($_, 6, 4) = 4 == 67108864 00000000000000000000000000100000 vec($_, 7, 4) = 4 == 1073741824 00000000000000000000000000000010 vec($_, 0, 4) = 8 == 8 00010000000000000000000000000000 vec($_, 1, 4) = 8 == 128 00000001000000000000000000000000 vec($_, 2, 4) = 8 == 2048 00000000000100000000000000000000 vec($_, 3, 4) = 8 == 32768 00000000000000010000000000000000 vec($_, 4, 4) = 8 == 524288 00000000000000000001000000000000 vec($_, 5, 4) = 8 == 8388608 00000000000000000000000100000000 vec($_, 6, 4) = 8 == 134217728 00000000000000000000000000010000 vec($_, 7, 4) = 8 == 2147483648 00000000000000000000000000000001 vec($_, 0, 8) = 1 == 1 10000000000000000000000000000000 vec($_, 1, 8) = 1 == 256 00000000100000000000000000000000 vec($_, 2, 8) = 1 == 65536 00000000000000001000000000000000 vec($_, 3, 8) = 1 == 16777216 00000000000000000000000010000000 vec($_, 0, 8) = 2 == 2 01000000000000000000000000000000 vec($_, 1, 8) = 2 == 512 00000000010000000000000000000000 vec($_, 2, 8) = 2 == 131072 00000000000000000100000000000000 vec($_, 3, 8) = 2 == 33554432 00000000000000000000000001000000 vec($_, 0, 8) = 4 == 4 00100000000000000000000000000000 vec($_, 1, 8) = 4 == 1024 00000000001000000000000000000000 vec($_, 2, 8) = 4 == 262144 00000000000000000010000000000000 vec($_, 3, 8) = 4 == 67108864 00000000000000000000000000100000 vec($_, 0, 8) = 8 == 8 00010000000000000000000000000000 vec($_, 1, 8) = 8 == 2048 00000000000100000000000000000000 vec($_, 2, 8) = 8 == 524288 00000000000000000001000000000000 vec($_, 3, 8) = 8 == 134217728 00000000000000000000000000010000 vec($_, 0, 8) = 16 == 16 00001000000000000000000000000000 vec($_, 1, 8) = 16 == 4096 00000000000010000000000000000000 vec($_, 2, 8) = 16 == 1048576 00000000000000000000100000000000 vec($_, 3, 8) = 16 == 268435456 00000000000000000000000000001000 vec($_, 0, 8) = 32 == 32 00000100000000000000000000000000 vec($_, 1, 8) = 32 == 8192 00000000000001000000000000000000 vec($_, 2, 8) = 32 == 2097152 00000000000000000000010000000000 vec($_, 3, 8) = 32 == 536870912 00000000000000000000000000000100 vec($_, 0, 8) = 64 == 64 00000010000000000000000000000000 vec($_, 1, 8) = 64 == 16384 00000000000000100000000000000000 vec($_, 2, 8) = 64 == 4194304 00000000000000000000001000000000 vec($_, 3, 8) = 64 == 1073741824 00000000000000000000000000000010 vec($_, 0, 8) = 128 == 128 00000001000000000000000000000000 vec($_, 1, 8) = 128 == 32768 00000000000000010000000000000000 vec($_, 2, 8) = 128 == 8388608 00000000000000000000000100000000 vec($_, 3, 8) = 128 == 2147483648 00000000000000000000000000000001
В вашей системе ведет себя как wait (2) : он ожидает завершения дочернего процесса и возвращает pid умершего процесса или -1 , если дочерних процессов нет. Статус возвращается в $? и ${^CHILD_ERROR_NATIVE} . Обратите внимание, что возвращаемое значение -1 может означать, что дочерние процессы выполняются автоматически, как описано в perlipc .
Если вы используете wait в своем обработчике для $SIG{CHLD} , он может случайно дождаться дочернего элемента, созданного qx или system . Подробности смотрите в Perlipc .
Проблемы с переносимостью: «подождите» в perlport .
Ожидает завершения определенного дочернего процесса и возвращает pid умершего процесса или -1 , если такого дочернего процесса нет. Неблокирующее ожидание (с WNOHANG в FLAGS) может вернуть 0, если есть дочерние процессы, соответствующие PID, но ни один из них еще не завершился. Статус возвращается в $? и ${^CHILD_ERROR_NATIVE} .
PID, равный 0 , указывает на ожидание любого дочернего процесса, идентификатор группы процессов которого совпадает с идентификатором текущего процесса. PID меньше -1 указывает на ожидание любого дочернего процесса, идентификатор группы процессов которого равен -PID. PID, равный -1 , указывает на ожидание любого дочернего процесса.
Если вы скажете
use POSIX ":sys_wait_h"; my $kid; do { $kid = waitpid(-1, WNOHANG); } while $kid > 0;
or
1 while waitpid(-1, WNOHANG) > 0;
тогда вы можете выполнить неблокирующее ожидание для всех ожидающих зомби-процессов (см. «WAIT» в POSIX ). Неблокирующее ожидание доступно на машинах, поддерживающих системные вызовы waitpid (2) или wait4 (2) . Однако ожидание определенного pid с флагами 0 реализовано везде. (Perl эмулирует системный вызов, запоминая значения состояния процессов, которые завершились, но еще не были собраны сценарием Perl.)
Обратите внимание, что в некоторых системах возвращаемое значение -1 может означать, что дочерние процессы выполняются автоматически. См. Подробности в perlipc и другие примеры.
Проблемы с переносимостью: «waitpid» в perlport .
Возвращает true, если контекст выполняемой в данный момент подпрограммы или eval ищет значение списка. Возвращает false, если контекст ищет скаляр. Возвращает неопределенное значение, если контекст не ищет значения (недействительный контекст).
return unless defined wantarray; my @a = complex_calculation(); return wantarray ? @a : "@a";
wantarray не указан на верхнем уровне файла, в BEGIN , UNITCHECK , CHECK , INIT или END или в DESTROY .
Эту функцию следовало бы назвать wantlist().
Выдает предупреждение, обычно путем его STDERR в STDERR . warn интерпретирует свой операнд LIST так же, как die , но немного отличается от того, что он принимает по умолчанию, когда LIST пуст или создает пустую строку. Если он пуст и $@ уже содержит значение исключения, то это значение используется после добавления "t...caught" . Если он пуст и $@ также пуст, то используется строка "Warning: Something's wrong" .
По умолчанию исключение, полученное из операнда LIST, преобразуется в строку и печатается в STDERR . Это поведение можно изменить, установив обработчик $SIG{__WARN__} . Если такой обработчик есть, то сообщение автоматически не печатается; обработчик отвечает за обработку исключения по своему усмотрению (например, преобразование его в кубик die . Поэтому большинству обработчиков приходится организовывать фактическое отображение предупреждений, с которыми они не готовы работать, путем повторного вызова warn в обработчике. Обратите внимание, что это совершенно безопасно и не приведет к бесконечному циклу, так как хуки __WARN__ не вызываются изнутри одного.
Вы обнаружите, что это поведение немного отличается от поведения обработчиков $SIG{__DIE__} (которые не подавляют текст ошибки, но вместо этого могут снова вызвать die , чтобы изменить его).
Использование обработчика __WARN__ обеспечивает мощный способ заглушить все предупреждения (даже так называемые обязательные). Пример:
BEGIN { $SIG{'__WARN__'} = sub { warn $_[0] if $DOWARN } }
my $foo = 10;
my $foo = 20;
$DOWARN = 1;
warn "$foo is alive and $foo!";
См. Perlvar для получения подробной информации о настройке записей %SIG и других примеров. См. Модуль » Карп » для получения информации о других видах предупреждений, использующих его функции » carp и » cluck .
Записывает отформатированную запись (возможно, многострочную) в указанный FILEHANDLE, используя формат, связанный с этим файлом. По умолчанию формат файла имеет то же имя, что и дескриптор файла, но формат для текущего выходного канала (см. функцию select ) можно задать явно, назначив имя формата переменной $~ .
Обработка начала формы обрабатывается автоматически: если на текущей странице недостаточно места для форматированной записи, страница продвигается вперед путем написания канала формы, а специальный формат верхней части страницы используется для форматирования нового заголовка страницы перед запись написана. По умолчанию формат верхней части страницы — это имя дескриптора файла с добавленным _TOP или top в текущем пакете, если первого не существует. Это было бы проблемой с автоактивизированными дескрипторами файлов, но для него можно динамически установить формат по вашему выбору, присвоив имя переменной $^ когда этот дескриптор файла выбран. Количество строк, оставшихся на текущей странице, находится в переменной $- , которая может быть установлена в 0 , чтобы принудительно открыть новую страницу.
Если FILEHANDLE не указан, вывод идет на текущий выходной канал по умолчанию, который начинается как STDOUT, но может быть изменен оператором select . Если FILEHANDLE является EXPR, выражение оценивается, и результирующая строка используется для поиска имени FILEHANDLE во время выполнения. Дополнительные сведения о форматах см. в разделе perlform .
Обратите внимание,что записьnotпротивоположность read . К несчастью.
Оператор транслитерации. То же, что tr/// . См. «Операторы, подобные кавычкам» в perlop .