假設我有一個檔案 main.pl 和一個包 package.pm
在 main.pl 我得到了這個功能
sub GetTimestampFromDateStr {
my $date_str = shift;
$logger->debug("[GetTimestampFromDateStr]:(Checking date \"$date_str\"\n"); # Here
my $unix_timestamp;
if ( $date_str =~ /^\d{8}\.\d{6}$/ ) { # Here
$unix_timestamp =
Time::Piece->strptime( $date_str, '%Y%m%d.%H%M%S' )->epoch();
}
else {
$logger->error( # Here
"[GetTimestampFromDateStr]:(Invalid date format for \"$date_str\", must be \"%Y%m%d.%H%M%S\" i.e. \"20170125.123500\"\n"
);
}
return $unix_timestamp;
}
被呼叫
sub DATESORT {
my $TYPE = shift;
my $ts_a = GetTimestampFromDateStr($a);
my $ts_b = GetTimestampFromDateStr($b);
if ( lc($TYPE) eq "desc" ) {
$ts_b <=> $ts_a;
}
else {
$ts_a <=> $ts_b;
}
}
用作排序功能并通過呼叫
sort { DATESORT('ASC') } @tran_dates_to_load
當函式和函式呼叫在同一個檔案中時,一切正常。當將函式按原樣移動到 package.pm 時,它會突然引發一堆未初始化值的錯誤。
使用 perl 5.16.3。
uj5u.com熱心網友回復:
$a并且$b是包變數,因此不能輕易地跨包邊界訪問。示范:
use v5.12;
package Foo {
sub bar {
say "[$a]";
say "[$b]";
1;
}
}
package main {
my @x = sort { Foo::bar() } 1 .. 2;
}
您可以通過完全參考變數來解決這個問題:
use v5.12;
package Foo {
sub bar {
say "[$main::a]";
say "[$main::b]";
1;
}
}
package main {
my @x = sort { Foo::bar() } 1 .. 2;
}
但是,這會將一個假設硬編碼到Foo::bar()- 它現在假設它將始終從main.
由于 ,您可以消除硬編碼caller,盡管它有點難看:
use v5.12;
package Foo {
sub bar {
no strict 'refs';
my ( $x, $y ) = map ${ caller . '::' . $_ }, qw( a b );
say "[$x]";
say "[$y]";
1;
}
}
package main {
my @x = sort { Foo::bar() } 1 .. 2;
}
更好的解決方案是將$a和$b作為函式引數傳遞。
use v5.12;
package Foo {
sub bar {
my ( $x, $y ) = @_;
say "[$x]";
say "[$y]";
1;
}
}
package main {
my @x = sort { Foo::bar( $a, $b ) } 1 .. 2;
}
uj5u.com熱心網友回復:
當您只有n 個日期時,您正在呼叫有點昂貴的GetTimestampFromDateStr 2*n*log2(n)次。這意味著 16 個日期會導致 128 次日期轉換。這是一個巨大的浪費。
我推薦使用Sort::Key來解決這個問題。
當只需要執行一次時,您正在執行lc($TYPE) eq "desc"檢查2*n*log2(n)次。
我建議將結帳移出比較功能以解決此問題。
use Sort::Key qw( ikeysort rikeysort );
my $sorter =
( lc($TYPE) eq "desc"
? sub { rikeysort { GetTimestampFromDateStr( $_ ) } @_ }
: sub { ikeysort { GetTimestampFromDateStr( $_ ) } @_ }
);
my @sorted = $sorter->( @unsorted );
也就是說,考慮到它們使用的格式,根本沒有理由轉換日期!
my $sorter =
( lc($TYPE) eq "desc"
? sub { sort { $b cmp $a } @_ }
: sub { sort { $a cmp $b } @_ }
);
my @sorted = $sorter->( @unsorted );
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/513179.html
標籤:排序perlperl 模块子程序
