2017-08-24 29 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的值。這個表格是我的問題的總長腳本的廢除腳本。非常感謝你!! –