sub foo($$$$) { }
Так хочется вместо, например,
foo(1, $foo{1}, $foo{3}, $foo{5});
Написать
foo(1, @foo{qw(1 3 5)});
Но нельзя, так как Perl ругается, что недостаточно аргументов. :-(
Заметки программиста, в основном, о perl. Название блога происходит от трех главных добродетелей программиста: Лень, Нетерпение и Высокомерие. К некоторым статьям следует относиться с определенной долей юмора. Содержание.
sub foo($$$$) { }
foo(1, $foo{1}, $foo{3}, $foo{5});
foo(1, @foo{qw(1 3 5)});
use strict;
use warnings;
use List::Rmap qw(reduce rmap hmap);
my @a = (1, 2, 3);
my @b = (4, 5, 6);
print reduce { $a + $b } @a;
# Бyдет напечатано 6
# Это в Perl6 эквивалентно [+] @x
print "\n";
# reduced map
print join " ", rmap { $a + $b } @a;
# Бyдет напечатано 1 3 6
# Это в Perl6 эквивалентно [\+] @x
print "\n";
# hyper map
print join " ", hmap { $a + $b } @a, @b;
# Бyдет напечатано 5 7 9
# Это в Perl6 эквивалентно @x >>+<< @y
# Reduced map
package List::Rmap;
use strict;
use warnings;
no strict qw(refs);
use Exporter;
our @EXPORT_OK = qw(reduce rmap hmap);
sub import {
# Avoid "Name "..." used only once" warnings for $a and $b.
my $caller = caller;
local *{"${caller}::a"};
local *{"${caller}::b"};
goto &Exporter::import
}
sub reduce (&@) {
my $code = shift;
my $caller = caller;
local *{"${caller}::a"} = \ my $a;
local *{"${caller}::b"} = \ my $b;
$a = shift;
foreach (@_) {
$b = $_;
$a = &{$code}();
}
return $a;
}
sub rmap (&@) {
my $code = shift;
my $caller = caller;
local *{"${caller}::a"} = \ my $a;
local *{"${caller}::b"} = \ my $b;
my @r = ($a = shift);
foreach (@_) {
$b = $_;
push @r, $a = &{$code}();
}
return @r;
}
sub hmap (&\@\@) {
my $code = shift;
my ($ra, $rb) = @_;
@$ra == @$rb or die "Different length of lists.";
my $caller = caller;
local *{"${caller}::a"} = \ my $a;
local *{"${caller}::b"} = \ my $b;
my @r = ();
foreach ($[ .. $#$ra) {
$a = $$ra[$_];
$b = $$rb[$_];
push @r, &{$code}();
}
return @r;
}
1;
use strict;
use warnings;
use List::Util;
use Benchmark qw(cmpthese);
my $foo = [1 .. 10000];
use vars qw($a $b);
cmpthese(1000, {
'manual' => sub {
my $s = 0;
$s += $_ foreach @$foo;
},
'List::Util::sum' => sub {
List::Util::sum(@$foo);
},
'List::Util::reduce' => sub {
List::Util::reduce { $a + $b } @$foo;
},
});
__END__
Rate manual List::Util::reduce List::Util::sum
manual 153/s -- -11% -91%
List::Util::reduce 171/s 12% -- -90%
List::Util::sum 1662/s 987% 871% --
package Foo::C::Too;
use base qw(Foo::C);
sub foo : Handler(foo) { '...' }
sub too { '...' }
sub baz : Handler(abc) { '...' }
package Foo::C;
sub MODIFY_CODE_ATTRIBUTES {
my ($package, $sub, @attr) = @_;
foreach (@attr) {
if (m/^Handler\((.+)\)$/) {
# Регистрация в таблице диспетчеризации
# подпрограммы $sub для команды $1.
# ...
last;
}
}
return ();
}
no strict "refs";
foreach (keys %INC) {
if (m/(Foo\/C\/.+)\.pm$/) {
my $p = $1;
$p =~ s/\//::/g;
while (my ($key, $val) = each(%{*{"$p\::"}})) {
if ($key =~ m/^h_(.+)/ and my $sub = *$val{CODE}) {
# Регистрация в таблице диспетчеризации
# подпрограммы $sub для команды $1.
# ...
}
}
}
}
package Foo::C::Too;
sub h_foo { '...' }
sub too { '...' }
sub h_baz { '...' }