2017-08-24 41 views
-1

我只是perl的一个月的经验。 对于基于perl的程序执行问题,commend变量返回到先前的值。 问题是什么? 这是代码。变量在Perl中返回到以前的值

1st(); 
2nd(); 
sub 1st { 
     $cmd = "cat asdf"; 
} 
sub 2nd { 
    if ($code =~ /aa/) { 
      my $cmd = "$reg $annotation"; 
      out_log($cmd); 
    } else { 
      my $cmd = "$reg $annotation"; 
      out_log($cmd); 
    } 
    out_log("$cmd"); 
    open (Work,$cmd); 
} 

在这种状态下,$ CMD注册于if语句,但执行$ CMD if语句中,$ CMD值返回子程序1的值之后。 感谢您的建议。

+2

其实,subs不能以数字开头。 – simbabque

回答

4

你在混合词法变量。如果你的程序有use strictuse warnings,这将是非常明显的。

如果你没有用my声明一个变量,Perl会认为它是一个包变量。它将从程序的每个部分(在相同的命名空间中)可见。

如果你声明变量为my,它将是词汇。这意味着,它只有范围内存在其创建。

my $foo = 1;   # 
        # 
if ($foo) {  # # 
    my $bar = 2; # # 
}     # # 
       ^^ 
        | | scope that $foo exists in 
        | scope that $bar exists in 

同样的事情发生在这里。

要设置包变量$::cmd(与::作为main命名空间)到"cat asdf"1st子内部。然后您打电话2nd分,这将进入else分支。在这个范围内,它将创建一个新的词汇$cmd。它只在程序的这一部分有效。然后传递给out_log(),这可能会打印出来。之后,您将$::cmd"cat asdf"值传递给out_log()。此时新的$cmd不再存在。

code with freehand lines

如果你有在你的程序use strict,该计划将不会在所有的工作,因为默认的包变量行为是在这种情况下关闭的,所以你必须定义变量。

实际上,您不应该使用包变量操作,而是将参数传递给您的函数。

除此之外,还有一些其他的东西在你的程序中不是很好的做法。你应该使用3个参数open和一个词法文件句柄,并且检查返回值open

功能的名称不能以数字开头,所以1st2nd不是有效的名称。最好是在他们所做或所代表的东西之后命名。这样以后可以更轻松地阅读您的程序。

一个完整的程序可能看起来像这样。

use strict; 
use warnings; 

my ($code, $reg, $annotation); # these values come from somewhere... 

run_cmd(compose_cmd(), $code, $reg, $annotation); 

sub compose_cmd { 
    return "cat asdf"; 
} 

sub run_cmd { 
    my ($cmd, $code, $reg, $annotation) = @_; 

    if ($code =~ /aa/) { 
     my $cmd = "$reg $annotation"; 
     out_log($cmd); 
    } 
    else { 
     my $cmd = "$reg $annotation"; 
     out_log($cmd); 
    } 
    out_log("$cmd"); 
    open my $fh, '<', $cmd or die $!; 

    # do stuff with $fh ... 
} 

sub out_log { 
    print @_; 
} 
+0

哦,对不起。最后的out_log用于检查$ cmd的值。这个表格是我的问题的总长脚本的废除脚本。非常感谢你!! –