Perl - 为什么班次在使用后会失去价值?

时间:2009-11-19 18:00:09

标签: regex perl variables shift

此代码有效 - 它需要一个完整的txt文件路径数组并将其删除,以便在调用$exam_nums[$x]时返回文件名

for (0..$#exam_nums)
{
 $exam_nums[$_] =~ s/\.txt$//; #remove extension
 $exam_nums[$_] =~ s/$dir//g; #remove path
}

当我尝试为单个变量执行此操作时,它不起作用。我正在调用一个子程序并向它发送一个礼物,但该变量在结尾处是空的。 (它进入if语句块,因为其中的其他行运行正常。)这是代码:

致电sub:

notify($_);

$_来自foreach(@files)循环

子:

sub notify
{
 if(shift)
 { 
  $ex_num = shift;
  $ex_num =~ s/\.txt$//; #remove extension
  $ex_num =~ s/$dir//g; #remove path
        print $ex_num;
        print "\nanything";
 }
}

我尝试在正则表达式的“删除扩展”部分中取出$,但这没有帮助。

5 个答案:

答案 0 :(得分:13)

你正在转移TWICE。 if语句中的第一个移位删除了值,第二个移位什么都没有。 shift具有实际修改@_的副作用。除了返回第一个元素外,它还会从@_永久删除第一个元素。

编辑:来自man perlfunc

   shift ARRAY
   shift   Shifts the first value of the array off and returns it,
           shortening the array by 1 and moving everything down.  If there
           are no elements in the array, returns the undefined value.  If
           ARRAY is omitted, shifts the @_ array within the lexical scope
           of subroutines and formats, ...

答案 1 :(得分:6)

您试图从ex_num(参数列表)中提取@_个参数两次:shift(改变@_)与{{1}不同(只是查看$_[0]的第一个元素但不改变它)。请参阅perldoc -f shift

此外,您的功能正在关闭@_,这可能是您的意图,也可能不是。 (有关闭包的更多信息,请参阅perldoc perlfaq7。)我已将其删除并将其作为附加函数参数添加:

$dir

答案 2 :(得分:5)

我使用File::Basename而不是自己动手。它允许您将文件路径解析为其目录,文件名和后缀。

答案 3 :(得分:1)

根据Jim Garrison's信息,我拉了一个开关来解决问题:

sub notify
{
    $ex_num = shift;
    if($ex_num)
    {   
        $ex_num =~ s/\.txt$//; #remove extension
        $ex_num =~ s/$dir//g; #remove path
    }
}

答案 4 :(得分:0)

使用核心模块,局部变量和Perl 5.10。

use 5.010;
use File::Basename;

sub notify {
    my $ex_num = shift;
    my $name = basename($ex_num, '.txt');
    say $name;
}