小编fri*_*edo的帖子

处理Moose中的多继承构造函数

问候,

我正在学习Moose,而我正在尝试用Moose 编写一个CGI :: Application子类,由于CGI-App不是基于Moose而变得困难.

在我的其他CGI-App子类中,我喜欢让父类使用一个setup方法来查看子类的符号表并自动设置runmodes.我想我可以使用Moose的元类设施以更清洁的方式实现同​​样的目的.所以这是我在父类中的内容:

use MooseX::Declare;

class MyApp::CGI 
extends Moose::Object
extends CGI::Application { 

    method setup { 
        $self->start_mode( 'main' );

        my @methods = map { $_->name } $self->meta->get_all_methods;

        $self->run_modes( map  { /^rm_(.+)$/  => $_ }
                          grep { /^rm_/ }
                          @methods
                        );
    }

}
Run Code Online (Sandbox Code Playgroud)

......在我的孩子班上:

use MooseX::Declare;

class MyApp::CGI::Login 
extends MyApp::CGI { 
    method rm_main { 
        return "it works";
    }
}
Run Code Online (Sandbox Code Playgroud)

我意识到我的runmodes没有正确设置的原因是因为setupCGI-App构造函数调用了Moose::Object它,并且在我的类中坚持自己的构造函数.我尝试用方法修饰符解决这个问题:

around new { 
    $self = $orig->( @_ );
    $self->CGI::Application::new( …
Run Code Online (Sandbox Code Playgroud)

oop perl moose cgiapp mop

6
推荐指数
1
解决办法
1132
查看次数

分叉进程时会发生什么?

我读过关于fork的内容,根据我的理解,该过程是克隆的但是哪个过程?脚本本身或启动脚本的进程?

例如:

我正在我的机器上运行rTorrent,当一个torrent完成时,我有一个脚本运行它.此脚本从Web获取数据,因此需要几秒钟才能完成.在此期间,我的rtorrent进程被冻结.所以我使用以下内容编写了脚本fork

my $pid = fork();
if ($pid == 0) { blah blah blah; exit 0; }
Run Code Online (Sandbox Code Playgroud)

如果我从CLI运行这个脚本,它会在一秒钟内回到shell,而它在后台运行,正如我想要的那样.但是,当我从rTorrent运行时,它似乎比以前更慢.究竟是什么分叉了?rtorrent进程是否克隆了自己并且我的脚本在那里运行,或者我的脚本是否克隆了自己?我希望这是有道理的.

unix linux perl posix fork

6
推荐指数
2
解决办法
773
查看次数

在大脚本中以词汇方式导入有用的函数

有时我需要一个有用的实用函数,就像List::Util::max在大型程序中间做很多事情一样.所以,如果我这样做

use List::Util 'max';
Run Code Online (Sandbox Code Playgroud)

在我的程序的顶部,我坚持使用该符号,污染我的整个命名空间,即使我只需要在一个子程序中.

所以我一直在考虑尝试不同的模式,而是:

use List::Util ();

# a whole bunch of stuff later...
sub blah { 
    List::Util->import( 'max' );
    $blah = max @foobar;
    ...
}
Run Code Online (Sandbox Code Playgroud)

但是,这有两个问题.首先,它不会在块结束时自动不进行操作(drat.)我将不得不撤消所有内容unimport.

另一个问题是,显然原型没有得到正确应用,所以我不得不说,max( @foobar )而不是更漂亮的无括号版本.

是否有一种简单的方法来临时导入块的符号,这将自动使它们在块的末尾消失,哪些也可以正确处理原型?

import perl lexical-scope

6
推荐指数
1
解决办法
218
查看次数

用于获取数组中最大元素数的Perl习惯用法

我想要除了阵列的前五个元素之外的所有元素,所以我愚蠢地做了:

@foo = @foo[ 0 .. 4 ];
Run Code Online (Sandbox Code Playgroud)

并衷心地称赞我自己的聪明才智.但是那次爆发@foo只有三个元素结束了,因为那时我最终得到了两个undefs,而不是一个三元素数组.所以我改成了:

@foo = @foo > 5 ? @foo[ 0 .. 4 ] : @foo;
Run Code Online (Sandbox Code Playgroud)

这有效,但有点难看.有没有更好的成语说"给我一切到阵列的前五个元素?"

perl idioms

6
推荐指数
3
解决办法
641
查看次数

什么是Perl的qq运算符的Java等价物?

我有一个非常长的字符串,其中包含许多新行(这是一个非常长的SQL语句).

当我用换行符分解它时,SQL更容易阅读.但有时,我需要从代码中复制sql语句以粘贴到sql developer中.

在Perl中,我总是喜欢qq运算符,您可以使用它来代替双引号:

你用它是这样的:

$myString = qq{       
                      SELECT * 
                      FROM table_a a
                      JOIN table_b b ON a.id = b.id ... etc
                };
Run Code Online (Sandbox Code Playgroud)

JAVA中是否有等价物?我发现必须像这样分解字符串中的字符串很尴尬:

String myString = "    SELECT *  " + 
                  "    FROM table_a a " + 
                  "    JOIN table_b b ON a.id = b.id ... etc ";
Run Code Online (Sandbox Code Playgroud)

并且很难从代码中复制SQL语句.我最终不得不删除所有引号和+

是否有Java等价物?或者是否有更好的技巧将可读的,可复制的SQL语句放在Java代码中?

java string syntax perl operators

6
推荐指数
1
解决办法
997
查看次数

自行重新排列作业队列的方法

我有一个作业队列(使用Amazon SQS),它将作业交给许多机器,用于通过HTTP获取和处理各种文档.有数百个不同的主机被访问,并且没有可预测的作业顺序.

为了礼貌,我不希望我的系统在一台主机上反复敲击.因此,如果我得到一份工作#123从example.com获取某些内容,但我发现我在过去的X秒内刚刚从example.com获取了另一件事,我应该转向其他内容并保存作业#123 for后来.

问题是,实现这种模式的好方法是什么?

似乎第一步是让作业运行者在所有域的某个位置保留一个列表,并且最后一次访问该域上的某些内容.我想这可能是一个简单的数据库表.

如果消息处理器获得必须延迟的作业,则有许多可能的选项可用于执行操作.

  1. 只需将消息的副本推送到队列的末尾,然后将其丢弃而不执行它.希望在下一次出现时,足够的时间过去了.这可能会导致大量冗余SQS消息,尤其是在同一域的大型作业集群同时通过的情况下.

  2. 在礼貌要求可以执行工作之前,需要休息几秒钟.这可能导致许多队列处理器同时无所事事.

  3. 接受作业,但将其保存在每个队列处理器上的某个本地队列中.我想每个处理器都可以通过这种方式"声称"一些工作,然后选择以任何顺序处理它们以达到最大程度的礼貌.这仍然是不可预测的,因为每个队列处理器需要知道被其他所有域击中的域.

  4. 为每个域建立单独的队列,并为每个队列分配一个进程.每个进程都必须在执行每个作业之间暂停X秒,因此会有很多睡眠进程开销,但这可能不是一件坏事.

你有设计这种东西的经验吗?你会推荐什么策略?

parallel-processing perl design-patterns job-queue amazon-sqs

6
推荐指数
1
解决办法
453
查看次数

加速perl DBI fetchrow_hashref

我有一些看起来像这样的东西:

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万条记录.我无法更改/升级服务器.

谢谢

mysql sql database perl performance

6
推荐指数
1
解决办法
3380
查看次数

MooseX :: NonMoose类中mixins的问题

考虑以下:

package MyApp::CGI;

use Moose;
use MooseX::NonMoose;
use Data::Dumper;

extends 'CGI::Application';

BEGIN { 
    print "begin isa = " . Dumper \@MyApp::CGI::ISA;
};

print "runtime isa = " . Dumper \@MyApp::CGI::ISA;

... 
Run Code Online (Sandbox Code Playgroud)

编译时的输出是:

begin isa = $VAR1 = [
          'Moose::Object'
        ];
runtime isa = $VAR1 = [
          'CGI::Application',
          'Moose::Object'
        ];
Run Code Online (Sandbox Code Playgroud)

我为什么在意?因为当我尝试useCGI :: Application :: Plugin ::*类时,它希望我CGI::Application已经在编译时继承.插件类试图add_callback在我的类上调用类方法,但不能,因为我@ISA还没有设置.

解决这个问题的最佳方法是什么?@ISABEGIN块中手动调整是否会干扰MooseX::NonMoose

编辑

以下似乎有效,但我发现它令人反感:

package MyApp::CGI;

use Moose;
use MooseX::NonMoose;

use base …
Run Code Online (Sandbox Code Playgroud)

perl moose mixins cgiapp mop

5
推荐指数
1
解决办法
362
查看次数

当Moose中的基础属性发生变化时,重建延迟构建的属性

我有一个lazy_build属性的Moose类.该属性的值是另一个(非惰性)属性的函数.

假设某人为所需属性实例化了值为42的类.然后他们请求延迟属性,该属性计算为42的函数.然后,他们有勇气改变第一个属性!

懒惰的已经构建,因此不会再次调用构建器,并且lazy属性现在已过时.

我现在有一个解决方案,我在必需的属性上维护一个"脏"标志,懒惰的访问器检查脏标志并在需要时重建它.

但是,这似乎很多工作.有没有办法在Moose中处理这个问题,例如使用特征?

perl moose traits lazy-evaluation

5
推荐指数
1
解决办法
789
查看次数

与reftype {}有什么关系?

我最近看到一些代码提醒我提出这个问题.最近,我看到了很多这样的事情:

use Scalar::Util 'reftype';

if ( reftype $some_ref eq reftype { } ) { ... }
Run Code Online (Sandbox Code Playgroud)

调用reftype匿名hashref 的目的是什么?为什么不说呢eq 'HASH'

perl

5
推荐指数
1
解决办法
577
查看次数