Perl中foreach循环首次迭代后glob函数返回undef的原因
Perl中glob循环返回undef的原因及解决办法
问题根源
Perl的glob函数在标量上下文下是个迭代器,会记住上次的匹配状态。第一次调用返回第一个匹配的路径,后续如果没有更多匹配项,就会返回undef,直到用新的模式重置迭代状态。
你的循环里,第一次迭代(搜索路径为.)调用glob后,迭代器已经走到当前模式的末尾。第二次迭代时,哪怕传入静态的'~/.my_config_file',glob还没完成状态重置,直接返回undef。
解决办法
1. 用列表上下文调用glob
把变量放在括号里,触发列表上下文,让glob一次性返回所有匹配项,取第一个结果即可:
my ($file_path) = glob( "$search_path/$filename" );
2. 使用File::Glob的bsd_glob函数
File::Glob提供的bsd_glob函数不会保留迭代器状态,行为更直观,适合这种循环场景:
use File::Glob qw(bsd_glob); my $file_path = bsd_glob( "$search_path/$filename" );
修改后的代码示例
package MyPackage; use warnings; use strict; use File::Glob qw(bsd_glob); our @ConfigSearchPaths = (".", "~"); our $DefaultConfigName = ".my_config_file"; sub load_user_config { my ( $obj, $filename ) = @_; $filename ||= $DefaultConfigName; CONFIG_SEARCH: foreach my $search_path (@ConfigSearchPaths) { my $file_path = bsd_glob( "$search_path/$filename" ); my $file_path_2 = bsd_glob( '~/.my_config_file' ); if( defined $file_path && -r $file_path ) { # 解析文件的逻辑... last CONFIG_SEARCH; # 找到有效配置文件后退出循环 } } }
额外提醒:判断文件可读性前先检查$file_path是否定义,避免触发未初始化变量的警告。
内容的提问来源于stack exchange,提问作者LostSnail
相关产品推荐
相关产品推荐

