小编Bri*_*anH的帖子

如何按排序顺序读取目录中的文件?

当我使用opendir,readdir和读取Perl中的目录时closedir,该readdir函数似乎没有以任何特定顺序读取文件(我可以告诉).

我正在读取一个目录,该目录包含以epoch timestamp命名的子目录:

1224161460
1228324260
1229698140
Run Code Online (Sandbox Code Playgroud)

我想以数字顺序读取这些目录,这将把最旧的目录放在第一位.

当我使用时readdir,它读取的第一个是1228324260,这是中间的一个.我知道我可以将目录内容放在一个数组中并对数组进行排序,但是我可以传递一个选项readdir来按排序顺序读取吗?或者可能是一种更优雅的方法来实现这一点,而不是将所有内容推入数组并对数组进行排序 可能还有模块可以做到这一点,但很难在我们的环境中安装模块,所以除非它是一个内置模块,否则我宁愿不使用模块......

谢谢!

编辑 根据要求,我发布了我正在使用的代码:

opendir( my $data_dh, $data_dir ) or die "Cannot open $data_dir\n";
while ( my $name = readdir($data_dh) ) {
    next if ( $name eq '.' or $name eq '..' );
    my $full_path = "${data_dir}/${name}";
    next unless ( -d $full_path );
    process_dir($full_path);
}
closedir($data_dh);
Run Code Online (Sandbox Code Playgroud)

directory perl getdirectories readdir

8
推荐指数
3
解决办法
2万
查看次数

有没有更好的方法用/ x编写Perl正则表达式,所以代码仍然易于阅读?

我在我的一个脚本上运行了Perl :: Critic,并收到了以下消息:

Regular expression without "/x" flag at line 21, column 26. See page 236 of PBP.
Run Code Online (Sandbox Code Playgroud)

我在这里查看了策略信息,并且我理解在扩展模式下编写正则表达式将有助于任何正在查看代码的人.

但是,我被困在如何转换我的代码以使用/ x标志.

CPAN示例:

# Match a single-quoted string efficiently...

m{'[^\\']*(?:\\.[^\\']*)*'};  #Huh?

# Same thing with extended format...

m{
    '           # an opening single quote
    [^\\']      # any non-special chars (i.e. not backslash or single quote)
    (?:         # then all of...
        \\ .    #    any explicitly backslashed char
        [^\\']* #    followed by an non-special chars
    )*          # ...repeated zero or …
Run Code Online (Sandbox Code Playgroud)

regex perl perl-critic

8
推荐指数
4
解决办法
5638
查看次数

如果Moose中未提供必需属性,如何获得更好的错误消息?

我对穆斯来说是全新的.直到今天,我们的环境都在Perl 5.8.2上,不支持Moose.

我正在研究一些例子,我认为属性上的"required => 1"设置会很方便,但是当我尝试使用该选项时,返回的错误消息实际上并不可用.

这是一个例子:

cat.pl:

#!/usr/bin/perl

{
    package Cat;
    use Moose;
    use Modern::Perl;

    has 'name' => (
        is => 'ro',
        required => 1,
    );
    sub meow {
        my $self = shift;
        say 'Meow!';
    }
}

use Modern::Perl;

my $alarm = Cat->new();
$alarm->meow();
$alarm->meow();
$alarm->meow();
Run Code Online (Sandbox Code Playgroud)

当我运行它:

Attribute (name) is required at /app/perl5/perl-5.10.1/lib/site_perl/5.10.1/aix-thread-multi-64all/Class/MOP/Class.pm line 581
        Class::MOP::Class::_construct_instance('Moose::Meta::Class=HASH(0x110ac1a00)', 'HASH(0x110c3b3c0)') called at /app/perl5/perl-5.10.1/lib/site_perl/5.10.1/aix-thread-multi-64all/Class/MOP/Class.pm line 554
        Class::MOP::Class::new_object('Moose::Meta::Class=HASH(0x110ac1a00)', 'HASH(0x110c3b3c0)') called at /app/perl5/perl-5.10.1/lib/site_perl/5.10.1/aix-thread-multi-64all/Moose/Meta/Class.pm line 258
        Moose::Meta::Class::new_object('Moose::Meta::Class=HASH(0x110ac1a00)', 'HASH(0x110c3b3c0)') called at /app/perl5/perl-5.10.1/lib/site_perl/5.10.1/aix-thread-multi-64all/Moose/Object.pm line 28
        Moose::Object::new('Cat') called at cat.pl …
Run Code Online (Sandbox Code Playgroud)

perl moose

8
推荐指数
1
解决办法
641
查看次数

编写SQL来查询优先级队列表

我正在实现一个小队列来处理首先运行的进程.我在数据库中使用表来执行此操作.这是表的结构(我在SQLite中嘲笑它):

        "id" INTEGER PRIMARY KEY  AUTOINCREMENT  NOT NULL ,
        "identifier" VARCHAR NOT NULL ,
        "priority_number" INTEGER DEFAULT 15,
        "timestamp" DATETIME DEFAULT CURRENT_TIMESTAMP,
        "description" VARCHAR
Run Code Online (Sandbox Code Playgroud)

我正在尝试编写SQL来为我提供下一个可以运行的进程.以下是一些示例数据:

id  identifier  priority_number timestamp   description
1   test1   15  2009-01-20 17:14:49 NULL
2   test2   15  2009-01-20 17:14:56 NULL
3   test3   10  2009-01-20 17:15:03 NULL
4   test4   15  2009-01-20 17:15:08 NULL
5   test5   15  2009-01-20 17:32:23 NULL
6   test6   14  2009-01-20 17:32:30 NULL
7   test7   7   2009-01-20 17:32:38 NULL
8   test8   20  2009-01-20 17:32:57 NULL
9   test9 …
Run Code Online (Sandbox Code Playgroud)

sql queue priority-queue queue-table

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

如何在同一列上过滤具有2个条件的Perl DBIx记录集?

我在DBIx :: Class中弄湿了- 到目前为止爱它了.

我遇到的一个问题是我想查询记录,过滤掉不在特定日期范围内的记录.

我花了一些时间来找出如何进行<=匹配而不是相等匹配:

my $start_criteria = ">= $start_date";
my $end_criteria = "<= $end_date";
my $result   = $schema->resultset('MyTable')->search(
  {
    'status_date' => \$start_criteria,
    'status_date' => \$end_criteria,
  });
Run Code Online (Sandbox Code Playgroud)

这个问题的一个明显问题是,由于过滤器是哈希值,我会覆盖"status_date"的值,并且只搜索status_date <= $ end_date的位置.执行的SQL是:

SELECT me.* from MyTable me where status_date <= '9999-12-31'
Run Code Online (Sandbox Code Playgroud)

我搜索过CPAN,Google和SO,但无法弄清楚如何将2个条件应用于同一列.我能够找到的所有文档都显示了如何在同一列上过滤超过1列而不是2个条件.

我确定我错过了一些明显的东西.有人可以在这指出我吗?

perl dbix-class

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

如何在使用DBI的Perl模块中获得100%的测试覆盖率?

我对Devel :: Cover模块有点新,但发现它确保我没有错过测试非常有用.

我遇到的一个问题是了解Devel :: Cover的报告.我查看了文档,但无法弄清楚我需要测试什么才能获得100%的覆盖率.

编辑 - 我应该说清楚我并不是说我需要100%的覆盖率,因为正如多人指出的那样,100%覆盖率是一个宽松的术语,并不意味着我的代码没有错误,并且可能并不总是完全必要.由于我是Devel :: Cover的新手,我很想知道 为什么我的代码不是100%覆盖,以防我错过了一些重要的测试.

以下是封面报告的输出:

line  err   stmt   bran   cond    sub    pod   time   code
...
36                                                    sub connect_database {
37             3                    3      1   1126       my $self = shift;
38             3    100                          24       if ( !$self->{dsn} ) {
39             1                                  7           croak 'dsn not supplied - cannot connect';
40                                                        }
41    ***      2            33                   21       $self->{dbh} = DBI->connect( $self->{dsn}, q{}, q{} )
42                                                          || croak "$DBI::errstr";
43             1                                 11       return $self;
44 …
Run Code Online (Sandbox Code Playgroud)

testing perl code-coverage dbi

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

不关闭Perl中的目录句柄会有什么影响?

我最近继承了其他人编写的一些代码.

我发现代码中的任何地方都打开了一个目录以供阅读,它从未被关闭,因为原始开发人员有语法问题 - 他正在使用该close函数尝试关闭目录句柄而不是closedir函数.

代码是这样的:

opendir( DIR, $dir ) or die "Cannot open $dir: $!\n";
@files = readdir( DIR );
close( DIR );
Run Code Online (Sandbox Code Playgroud)

(这是Perl最佳实践(第208,278页)中关于检查close函数返回的另一个好点.如果close在这种情况下检查了返回,那么它将失败并显示"Bad file number".)

我已经改变了这一点closedir,但它让我开始疑惑:由于目录句柄从未关闭,对于保持目录句柄长时间打开有什么负面影响?

该程序较大(3,500行代码),运行一段时间(5-10分钟),并且该程序的多个实例同时运行.对于上面示例中的此目录,$dir所有实例的值都相同.如果此程序的10个实例同时运行,则它们都会对同一目录保持一个打开的目录句柄5分钟或更长时间.我确信Perl会在程序结束时自动关闭目录句柄,但最佳做法是尽快关闭它.

对我来说更明显的是,打开文件句柄会导致问题(特别是对于可以写入的文件句柄),但是如果不关闭目录句柄会发生什么坏事?

我问的原因是因为有一个奇怪的情况,这个程序试图创建一个文件(在上面的$ dir定义的目录中).文件名中嵌入了PID,因此文件可能已存在的可能性较小,但Perl无法打开文件进行写入,因为它说它已经存在.当我们查看目录时,该文件不存在.我想知道这个目录下的所有打开目录句柄是否都会导致这样的问题?

我不确定操作系统是否有所作为,但该程序在AIX上运行.

提前谢谢,周五快乐!

perl syntax-error

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

组织许多小项目的subversion存储库的最佳方法

首先,我看了以下几页,并没有得到我的答案: 你如何组织一个颠覆 - 内部存储库软件项目以及 你如何做 -组织-您的版本控制系统信息库

我还查看了使用Subversion的实用版控制的第8章.

他们都有很好的建议,但我很难将其与我的需求联系起来.

基本上,我想组织我们的Web服务器的代码.我们有$ WEBROOT/htdocs和$ WEBROOT/cgi-bin.在我们的htdocs目录下,我们为java脚本和样式表提供了$ WEBROOT/htdocs/js和$ WEBROOT/htdocs/css.

我们的"项目"不是真正的项目,而是一些代码 - 可能是Perl脚本,java脚本文件和样式表.我们可能有大约一百个这样的小"项目",它们几乎都是相互独立的,但都存在于同一个Web服务器上的同一个$ WEBROOT中.

我们的代码还没有进行颠覆,但我希望它是 - 我只是在组织它时遇到了麻烦.如果需要,我们可以有多个svn存储库,但如果每个存储库只有3-10个元素,那对我来说似乎是一种浪费.

我认为可以工作的是这样的:如果我编写一个脚本来计算Web服务器上正在运行的进程(为了一个例子).假设我有一个perl脚本,一个js文件和一个css文件.我可以将"project"命名为webserver_processes,并将其作为以下内容检入存储库:

/svnrepo/webserver_processes/trunk
Run Code Online (Sandbox Code Playgroud)

在行李箱下,我可以:

htdocs/html/webserver_processes
htdocs/js/webserver_processes
htdocs/css/webserver_processes
cgi-bin/webserver_processes
Run Code Online (Sandbox Code Playgroud)

我在这个"项目"中没有任何静态html文档,但如果我这样做,他们会进入"html"目录.

我在这个结构中看到的好处是,我可以一次签出一个"项目",而不会真正影响Web服务器上的任何其他内容.缺点(也许并非真正的缺点)是部署.我必须一次从存储库部署1个项目.我不知道如何用我的$ WEBROOT/htdocs结构和$ WEBROOT/cgi-bin使用这种方法创建一个工作副本.

另外一个选项:

我可以像这样创建一个svn存储库:

/svnrepo/webcode/trunk
Run Code Online (Sandbox Code Playgroud)

在trunk下面是我的web服务器上的所有代码,在这两个目录中:

htdocs
cgi-bin
Run Code Online (Sandbox Code Playgroud)

最大的缺点是,对于1个元素的小代码更改,我将不得不检查我的Web环境中的每一段代码.好处(有点)是我可以在我们的Web服务器上执行"svn update"以获取对存储库提交的任何更改.

也许我只是让它变得比它应该更复杂,但是有没有人对如何在subversion中有效地组织我的代码有任何建议?

提前谢谢了!

布赖恩

svn infrastructure code-organization svn-organization

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

Perl DBIx :: Class是否可以覆盖从数据库中检索列的方式?

我从来没有使用DBIx :: Class直到今天,所以我对它完全陌生.

我不确定这是否可行,但基本上我的SQLite数据库中有一个表中有一个时间戳列.timestamp列的默认值是"CURRENT_TIMESTAMP".SQLite将其存储在GMT时区中,但我的服务器位于CDT时区.

我的SQLite查询在正确的时区获取时间戳是这样的:

select datetime(timestamp, 'localtime') from mytable where id=1;
Run Code Online (Sandbox Code Playgroud)

我想知道在我的DBIx架构中是否有可能"MyTable"强制它在每次从数据库中检索"timestamp"字段时应用datetime函数?

在使用 - > search()函数时,在食谱中看起来可以这样做,但我想知道如果我使用search(),find(),all(),是否可以这样做, find_or_new(),或者从数据库中提取此列的任何函数,它会将datetime()SQLite函数应用于它吗?

DBIx :: Class似乎有很好的文档 - 我认为我只是如此新鲜,我找不到合适的地方/事物来搜索.

提前致谢!

sqlite perl dbix-class

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

在测试独立的Perl脚本时覆盖变量

我现在需要维护一个Perl脚本.它充满了不良做法,包括在整个脚本中使用(和重用)全局变量.在我开始更改脚本之前,我打算尝试编写一些测试脚本,这样我就可以获得良好的回归基础.为此,我将使用本页描述的方法.

我开始编写单个子程序的测试.我把这行放在我正在测试的脚本的顶部附近:

return 1 if ( caller() );
Run Code Online (Sandbox Code Playgroud)

那样,在我的测试脚本中,我可以

require 'script_to_test.pl';
Run Code Online (Sandbox Code Playgroud)

它不会执行整个脚本.

我要测试的第一个子程序大量使用了整个脚本中设置的全局变量.我的想法是尝试在我的测试脚本中覆盖这些变量,如下所示:

require_ok('script_to_test.pl');
$var_from_other_script = 'Override Value';
ok( sub_from_other_script() );
Run Code Online (Sandbox Code Playgroud)

不幸的是(对我来说),我正在测试的脚本在顶部有一个巨大的"我的"块,它声明了脚本中使用的所有变量.这可以防止我的测试脚本看到/更改我正在运行测试的脚本中的变量.

我玩过Exporter,Test :: Mock ......以及其他一些模块,但看起来我想要能够改变任何变量,我必须以某种方式修改其他脚本.

我的目标是不改变其他脚本,但要运行一些好的测试,所以当我开始更改其他脚本时,我可以确保我没有破坏任何东西. 该脚本大约有10,000行(主块中有3,000行),所以我担心如果我开始更改内容,我会影响代码的其他部分,因此拥有一个好的测试套件会有所帮助.

这可能吗? 调用脚本可以修改用"my"声明的另一个脚本中的变量吗?


并且请不要像"从头开始重新编写脚本"等答案,等等.这可能是最好的解决方案,但它没有回答我的问题,我们没有时间/资源重写.

testing perl

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