sub do_stuff_with_a_hash (&\%) {
my ( $block_of_code, $hash_ref ) = @_;
while ( my ( $k, $v ) = each %$hash_ref ) {
$block_of_code->( $k, $v );
}
}
You can then call it in the body like so
use Data::Dumper;
do_stuff_with_a_hash {
local $Data::Dumper::Terse = 1;
my ( $k, $v ) = @_;
say qq(Hey, the key is "$k"!);
say sprintf qq(Hey, the value is "%v"!), Dumper( $v );
} %stuff_for
;
(Data::Dumper::Dumper is another semi-hidden gem.) Notice how you don't need the sub keyword in front of the block, or the comma before the hash. It ends up looking a lot like: map { } @list
Source Filters
Also, there are source filters. Where Perl will pass you the code so you can manipulate it. Both this, and the block operations, are pretty much don't-try-this-at-home type of things.
I have done some neat things with source filters, for example like creating a very simple language to check the time, allowing short Perl one-liners for some decision making:
perl -MLib::DB -MLib::TL -e 'run_expensive_database_delete() if $hour_of_day < AM_7';
my $var = q#some string where the pound is the final escape.#;
my $var2 = q{A more pleasant way of escaping.};
my $var3 = q(Others prefer parens as the quote mechanism.);
sub MyRegexCheck {
my ($string, $regex) = @_;
if ($string)
{
return ($string =~ $regex);
}
return; # returns 'null' or 'empty' in every context
}
my $regex = qr{http://[\w]\.com/([\w]+/)+};
@results = MyRegexCheck(q{http://myurl.com/subpath1/subpath2/}, $regex);
my @allowed = qw(A B C D E F G H I J K L M N O P Q R S T U V W X Y Z { });
my @badwords = qw(WORD1 word2 word3 word4);
my @numbers = qw(one two three four 5 six seven); # works with numbers too
my @list = ('string with space', qw(eight nine), "a $var"); # works in other lists
my $arrayref = [ qw(and it works in arrays too) ];
s{
^ # make sure to get whole filename
(
[^'] + # at least one non-quote
\. # extension dot
(?: # now either suffix
gz
| Z
)
)
\z # through the end
}{gzcat '$1' |}xs for @ARGV;
/* perl4's way of mixing documentation and code
(before the invention of POD) was based on a
trick to mix nroff and perl code. The trick was
built upon these three nroff macros being used in
void context. The pink camel has the details in
the script wrapman near page 319. */
const char * const maybe_macro = SvPVX_const(sv);
if (strnEQ(maybe_macro, "di", 2) ||
strnEQ(maybe_macro, "ds", 2) ||
strnEQ(maybe_macro, "ig", 2))
useless = NULL;
这意味着 'di';不产生警告,但是 'die';'did you get that thing I sentcha?';或 'ignore this line';也不产生警告。
此外,数字常量 0和 1也有例外,它们允许使用裸 .00;。代码声称这是为了更一般的目的。
/* the constants 0 and 1 are permitted as they are
conventionally used as dummies in constructs like
1 while some_condition_with_side_effects; */
else if (SvNIOK(sv) && (SvNV(sv) == 0.0 || SvNV(sv) == 1.0))
useless = NULL;
Global symbol "$var" requires explicit package name at - line 4.
Execution of - aborted due to compilation errors (#1)
(F) You've said "use strict vars", which indicates that all variables
must either be lexically scoped (using "my"), declared beforehand using
"our", or explicitly qualified to say which package the global variable
is in (using "::").
Uncaught exception from user code:
Global symbol "$var" requires explicit package name at - line 4.
Execution of - aborted due to compilation errors.
at - line 5
use diagnostics;
use strict;
sub myname {
print { " Some Error " };
};
你会看到一大段有用的文字:
syntax error at - line 5, near "};"
Execution of - aborted due to compilation errors (#1)
(F) Probably means you had a syntax error. Common reasons include:
A keyword is misspelled.
A semicolon is missing.
A comma is missing.
An opening or closing parenthesis is missing.
An opening or closing brace is missing.
A closing quote is missing.
Often there will be another error message associated with the syntax
error giving more information. (Sometimes it helps to turn on -w.)
The error message itself often tells you where it was in the line when
it decided to give up. Sometimes the actual error is several tokens
before this, because Perl is good at understanding random input.
Occasionally the line number may be misleading, and once in a blue moon
the only way to figure out what's triggering the error is to call
perl -c repeatedly, chopping away half the program each time to see
if the error went away. Sort of the cybernetic version of S.
Uncaught exception from user code:
syntax error at - line 5, near "};"
Execution of - aborted due to compilation errors.
at - line 7
my @strings = ('one', 'two', 'three', 'four');
my $md5sorted_strings =
map { $_->[0] } # 4) map back to the original value
sort { $a->[1] cmp $b->[1] } # 3) sort by the correct element of the list
map { [$_, md5sum_func($_)] } # 2) create a list of anonymous lists
@strings # 1) take strings
# MyUsefulRoutines.pl
sub doSomethingUseful {
my @args = @_;
# ...
}
if ($0 =~ /MyUsefulRoutines.pl/) {
# someone is running perl MyUsefulRoutines.pl [args] from the command line
&doSomethingUseful (@ARGV);
} else {
# someone is calling require "MyUsefulRoutines.pl" from another script
1;
}
print 'the meaning of ', join ' ' =>
'life,' x!! $self->alive,
'the universe,' x!! ($location ~~ Universe),
('and', 'everything.') x!! 42; # this is added as a list
> perl -e "say 'hello"" # does not work
String found where operator expected at -e line 1, near "say 'hello'"
(Do you need to predeclare say?)
syntax error at -e line 1, near "say 'hello'"
Execution of -e aborted due to compilation errors.
> perl -E "say 'hello'"
hello
my $interpolation = "We will interpolated variables";
print <<"END";
With double quotes, $interpolation, just like normal HEREDOCS.
END
print <<'END';
With single quotes, the variable $foo will *not* be interpolated.
(You have probably seen this in other languages.)
END
## this is the fun and "hidden" one
my $shell_output = <<`END`;
echo With backticks, these commands will be executed in shell.
echo The output is returned.
ls | wc -l
END
print "shell output: $shell_output\n";