为什么在标量上下文中Perl文件glob()无法在循环外工作? [英] Why doesn't Perl file glob() work outside of a loop in scalar context?

查看:76
本文介绍了为什么在标量上下文中Perl文件glob()无法在循环外工作?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

根据有关文件glob的Perl文档,< *>在标量上下文中使用operator或glob()函数时,应遍历与指定模式匹配的文件列表,每次调用时返回下一个文件名,否则在没有更多文件时返回undef.

According to the Perl documentation on file globbing, the <*> operator or glob() function, when used in a scalar context, should iterate through the list of files matching the specified pattern, returning the next file name each time it is called or undef when there are no more files.

但是,迭代过程似乎只能在一个循环内进行.如果它不在循环中,那么它似乎在读取所有值之前立即重新开始.

But, the iterating process only seems to work from within a loop. If it isn't in a loop, then it seems to start over immediately before all values have been read.

从Perl文档中:

在标量上下文中,glob遍历此类文件名扩展,当列表用尽时返回undef.
In scalar context, glob iterates through such filename expansions, returning undef when the list is exhausted.

但是,在标量上下文中,运算符每次调用时都会返回下一个值,或者在列表用完时返回undef.

However, in scalar context the operator returns the next value each time it's called, or undef when the list has run out.

http://perldoc.perl.org/perlop.html#I/O-Operators

http://perldoc.perl.org/perlop.html#I/O-Operators

示例代码:


use warnings;
use strict;

my $filename;

# in scalar context, <*> should return the next file name
# each time it is called or undef when the list has run out

$filename = <*>;
print "$filename\n";
$filename = <*>;      # doesn't work as documented, starts over and
print "$filename\n";  # always returns the same file name
$filename = <*>;
print "$filename\n";

print "\n";

print "$filename\n" while $filename = <*>; # works in a loop, returns next file
                                           # each time it is called

在包含3个文件... file1.txt,file2.txt和file3.txt的目录中,以上代码将输出:

In a directory with 3 files...file1.txt, file2.txt, and file3.txt, the above code will output:


file1.txt
file1.txt
file1.txt

file1.txt
file2.txt
file3.txt

注意:实际的perl脚本应该在测试目录之外,否则您将在输出中看到该脚本的文件名.

Note: The actual perl script should be outside the test directory, or you will see the file name of the script in the output as well.

我在这里做错什么了吗,或者这是应该如何工作的?

Am I doing something wrong here, or is this how it is supposed to work?

推荐答案

这是一种将<> glob运算符状态的魔力捕获到一个对象中的方法,该对象可以通过常规方式进行操作:匿名子(和/或关闭)!

Here's a way to capture the magic of the <> glob operator's state into an object that you can manipulate in a normal sort of way: anonymous subs (and/or closures)!

sub all_files {
    return sub { scalar <*> };
}

my $iter = all_files();
print $iter->(), "\n";
print $iter->(), "\n";
print $iter->(), "\n";

或者也许:

sub dir_iterator {
    my $dir = shift;
    return sub { scalar glob("$dir/*") };
}
my $iter = dir_iterator("/etc");
print $iter->(), "\n";
print $iter->(), "\n";
print $iter->(), "\n";

然后我的倾向是将此文件归类为好奇心".忽略glob()/<>的特殊用法,并使用opendir/readdir IO :: All /readdir File :: Glob 代替:)

Then again my inclination is to file this under "curiosity". Ignore this particular oddity of glob() / <> and use opendir/readdir, IO::All/readdir, or File::Glob instead :)

这篇关于为什么在标量上下文中Perl文件glob()无法在循环外工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆