我对perl中的代码块有疑问.给出以下代码:
my @newArr = sort { $a <=> $b } @oldArr;
Run Code Online (Sandbox Code Playgroud)
使用代码块作为参数.
我可以把它重写为:
sub sortFunc {
return $a <=> $b;
}
my @newArr = sort sortFunc @oldArr;
Run Code Online (Sandbox Code Playgroud)
我试图弄清楚这种机制是如何工作的.目前我需要实现一种在代码块中看起来很乱的复杂排序函数,但它依赖于一些局部变量.例如:
foreach my $val (@values){
my @newArr = sort { $hash{$a}{$val}<=> $hash{$b}{$val} } @oldArr;
...
}
Run Code Online (Sandbox Code Playgroud)
但我们假设sort函数更复杂,因此它不能完全适合上面的代码.
如果我尝试使用一个函数(在for循环的范围内本地定义),我不断得到"在hash元素中使用未初始化的值".
我假设这是因为sub被解析一次,而不是为for循环的evry迭代重新创建.我试图了解如何实现每次迭代将重新解释的代码块,或者可能如何传递参数
我有一个非常大的表(数百万条记录),包含大约8个字段作为主键.为了简单起见,让我们说这个表看起来像这样:
key_1 | key_2 | key_3 | ... | key_8 | value
Run Code Online (Sandbox Code Playgroud)
给定key_1的值,我需要获取key_2,key_3,...,key_8的所有可能值,如下所示:
SELECT DISTINCT key_2 FROM table1 WHERE key_1 = 123;
SELECT DISTINCT key_3 FROM table1 WHERE key_1 = 123;
...
SELECT DISTINCT key_8 FROM table1 WHERE key_1 = 123;
Run Code Online (Sandbox Code Playgroud)
我的问题是这个查询明显慢于我的性能需求,并且该表中的数据相当稳定并且很少更新(每隔几天一次).table_1也可能是一个缓慢的子查询.如果没有在数据库中创建额外的表并在每次更新数据库时手动更新它,是否有另一种解决方案可以为我提供快速结果.我需要它跨多个MySQL会话.
我有一些看起来像这样的东西:
my $report = new ReportGenerator; #custom object
my $dbh = $dbc->prepare('SELECT * FROM some_table WHERE some_condition'); #DBI handle
$dbh->execute();
while(my $href = $dbh->fetchrow_hashref){
$report->process_record($href);
}
$dbh->finish();
print $report->printReport();
Run Code Online (Sandbox Code Playgroud)
我的问题是循环的每次迭代都很慢.问题是MySQL.我想知道是否有可能在while循环中放置某种包装器以使其一次获取多个记录,同时将所有记录提取到内存中也是不实际的.我并不担心代码的效率(hashref vs arrayref等).相反,我有兴趣获取让我们一次说10000条记录.
该数据库有大约500万条记录.我无法更改/升级服务器.
谢谢
我正在尝试编写持久/缓存脚本.代码看起来像这样:
...
Memoize('process_fille');
print process_file($ARGV[0]);
...
sub process_file{
my $filename = shift;
my ($a, $b, $c) = extract_values_from_file($filename);
if (exists $my_hash{$a}{$b}{$c}){
return $my_hash{$a}{$b}{$c};
}
return $default;
}
Run Code Online (Sandbox Code Playgroud)
这将从循环中的shell脚本调用,如下所示
value=`perl my_script.pl`;
Run Code Online (Sandbox Code Playgroud)
有没有办法可以调用这个脚本,以保持其状态.从打电话到打电话.让我们假设初始化'%my_hash'和调用extract_values_from_file都是一项昂贵的操作.
谢谢
我正在尝试使用IO :: Event来检测何时将新文件添加到目录中.我是IO :: Event库的新手,想知道它是否可以轻松实现.
我尝试了下面的代码,看看我是否可以让它做一些没有运气的事情.当我试图用opendir而不是时,它崩溃了open.
我只是想看看这个图书馆能否为我提供我想要的东西.我不需要普通Perl的解决方案,因为我可以自己编写代码.我看这个的唯一原因是因为我想使用Proc :: JobQueue :: EventQueue.我可以使用Proc :: JobQueue编写解决方案,但认为这可能更清晰.
#!perl
use warnings;
use strict;
use IO::Event;
open my $dirhandle,'/some/path/here/';
my $event = IO::Event->new($dirhandle);
Event::loop();
close $dirhandle;
sub ie_input{
print "ie_input called\n";
}
sub ie_read_ready{
print "ie_read_ready called\n";
}
sub ie_werror{
print "ie_werrory called\n";
}
sub ie_output{
print "ie_output called\n";
}
Run Code Online (Sandbox Code Playgroud) 我想弄清楚Perl中的Event Loops?
目前我的程序是这样的:
while(my $event = wait_for_event()){
handle_event($event);
try_to_do_something();
}
Run Code Online (Sandbox Code Playgroud)
wait_for_event阻塞的地方.
我想弄清楚我是否可以使用EV,或AnyEvent(AE)或其他东西来添加另一个事件观察者.
例如,我希望能够每2秒调用一次try_to_do_something(),但是目前我还没把它放入事件循环中.
此外,我想添加一些与程序的交互形式,可能通过套接字(另一个观察者).
谢谢
我需要设置一个作业队列,其中通过 Web 界面安排长时间运行的作业队列。然后在多个盒子上运行。我还需要能够删除和重新排序队列中的作业。
目前我们所有的代码都在 perl 中。我正在考虑使用 ApacheMQ、Gearman、Resque 等...
问题是,前面提到的其中一个是否更适合这项工作,那么不同的软件解决方案呢?我的创意计划只是编写一个 MySQL/Perl 队列,但这非常困难。我更喜欢有一个像样的 web 界面的东西,并且有一个 Perl 的界面。一个纯 MySQL/Perl 将是理想的。
谢谢
我在perl中有一个对象库,它们都具有相同的function_calls.我正在寻找如何从字符串库中创建一个approriate对象.
my $object_name='myObject';#would actually be a hash lookup from user input with appropriate error checks
my $string = "return ${object_name}->new(\@params);";
my $object = eval $string;
$object->some_function();
Run Code Online (Sandbox Code Playgroud)
现在我遇到了问题,它适用于某些对象而不适用于其他对象?有没有更可靠的方法来做到这一点.我已经尝试在eval之前打印出字符串,并且使用正确的类名似乎是正确的,每个对象也使用相同的参数,任何想法,谢谢.
我试图确保只有一个perl脚本的实例可以同时运行.该脚本根据传入的参数执行某种db_operation.脚本不一定存在于一个地方或一台机器上,也可能存在多个操作系统.虽然文件系统是在各种机器上自动安装的.
我的第一个方法是创建一个.lock文件,并执行以下操作:
use warnings;
use strict;
use Fcntl qw(:DEFAULT :flock);
...
open(FILE,">>",$lockFilePath);
flock(FILE,LOCK_EX) or die("Could not lock ");
do_something();
flock(FILE,LOCK_UN) or die("Could not unlock ");
close(FILE);
Run Code Online (Sandbox Code Playgroud)
但我不断收到以下错误:
Bareword "LOCK_EX" not allowed while "strict subs" in use
Bareword "LOCK_UN" not allowed while "strict subs" in use
Run Code Online (Sandbox Code Playgroud)
所以我正在寻找另一种解决问题的方法.锁定数据库本身也不实用,因为db可以被其他脚本使用(这是可以接受的),我只是试图阻止这个脚本运行.锁定表进行写入是不切实际的,因为我的脚本不知道操作正在发生什么表,它只是启动另一个作为参数提供的perl脚本.
我想在数据库中添加一个表,只有一个值,并将其用作muetex,但我不知道它是多么实用/可靠(我脑子里有很多红旗).我有一个DBI连接到这个脚本使用的数据库.
谢谢
我正在尝试使用AnyEvent和EV实现一些代码.我想安装一个儿童观察员(我想在下面做的样机)
use Modern::Perl;
use AnyEvent;
use EV;
my $SIG{QUIT} = \&kill_child;
my $exit_status = undef;
my $pid = fork or exec 'child.pl';
my $w = AnyEvent->child(pid => $pid, cb => sub { $exit_status = $_[2]; cleanup_after_child(); });
my $t = AE::timer 0, 5, sub { say $exit_status; fork_another_process(); };
AnyEvent->condvar->recv;
sub kill_child{
foreach my $signal (qw(HUP QUIT INT KILL)){
if(child_alive()){
kill($signal,$pid);
sleep 1;
}
}
exit; #Probably wrong
}
Run Code Online (Sandbox Code Playgroud)
我想帮助编写child_alive()以及找出各种回调以及在kill_child()中放置一个出口.我需要确保在进程退出之前调用cleanup_after_child().
使用AnyEvent Signal观察器会有帮助吗?我的目标是能够安全地关闭守护进程,首先杀死进程子进程并清理它们.我已经问了一个相关问题的问题(等待perl中的子进程)并且希望防止在退出处理期间发生该错误.
谢谢
编辑:以下是否适用于child_alive()函数?
sub child_alive{
return defined($exit_status)?1:0; …Run Code Online (Sandbox Code Playgroud) 我正在使用一个看起来像这样的动作块:
ActionBlock<Tuple<string,byte[],string>> ab =
new ActionBlock<Tuple<string,string,string>>(item => {
service.DoSomeAction(item.Item1, item.Item2, item.Item3);
},
new ExecutionDataflowBlockOptions {
MaxDegreeOfParallelism = 2
});
foreach(var item in Items) {
ab.Post(new Tuple<string,string,string>(item.a, item.b, item.c));
}
ab.Complete();
ab.Completion.Wait();
Run Code Online (Sandbox Code Playgroud)
我的问题是,service.DoSomeAction()由于网络负载可能会失败,我想知道ActionBlock是否有一个机制来重新启动任务.
我当然可以在该调用周围添加一个try/catch块,并在重新抛出异常之前让catch块等待/重试几次.我要找的是ab.Post()用相同的参数调用.我的问题是我已经打电话了ab.Complete().是否可以在不调用的情况下等待ActionBlock ab.Complete().是否有更好的工具可以用于工作?