2012-11-03 62 views
1

我是一个初学者,对这个Perl子程序中发生了什么感到困惑。初学者 - 子程序混淆

我只使用全局变量来简化事情,但它仍然无法正常工作。

我只是试图用IF语句使用文件测试运算符来打印文件的读,写和可执行属性。

任何人都可以指出我的问题吗?

路易

sub getfileattributes { 
    if (-r $file) { 
     $attributes[0] = "readable"; 
    } else { $attributes[0] = "not readable"; } 
    if (-w _) { 
     $attributes[1] = "writable"; 
    } else { $attributes[1] = "not writable"; } 
    if (-x _) { 
     $attributes[2] = "executable"; 
    } else { $attributes[2] = "not executable"; } 
}  

my @attributes; 
my $file; 

foreach $file (@ARGV) { 
    &getfileattributes; 
    printf "The file $file is %s, %s and %s\n", @attributes; 
} 
+13

总是使用'​​use strict;使用警告;'!它会立即告诉你你的错误是什么。 – ikegami

+7

使用全局变量不是*如何简化事情 – friedo

+3

全局变量不会“简化事情”。他们正好相反。当您在尽可能最小的范围内声明变量时,更容易知道它们来自哪里,他们如何到达那里以及下一个要去的地方。 –

回答

3

使用全局变量通常非常糟糕,并指向设计错误。在这种情况下,错误似乎是你不知道如何将参数传递给子。

这里是在Perl的模式:

sub I_take_arguments { 
    # all my arguments are in @_ array 
    my ($firstarg, $secondarg, @rest) = @_; 
    say "1st argument: $firstarg"; 
    say "2nd argument: " .($firstarg+1). " (incremented)"; 
    say "The rest is: [@rest]"; 
} 

替补调用像

I_take_arguments(1, 2, "three", 4); 

(不要调用它们作为&nameOfTheSub,这使得使用非常特殊的行为,你不通常想要。)

这将打印

1st argument: 1 
2nd argument: 3 
The rest is: [three 4] 

子程序可以返回值,或者与return语句或作为最后一条语句的值执行。这些潜艇是等价的:

sub foo {return "return value"} 
sub bar {"return value"} 

我会写你的getfileattributes作为

sub getFileAttributes { 
    my ($name) = @_; 
    return 
     -r $name ? "readable" : "not readable", 
     -w $name ? "writable" : "not writable", 
     -x $name ? "executable" : "not executable"; 
} 

这到底是怎么回事?我拿一个参数$name,然后返回一个列表的值。 return关键字可以省略。 return需要一个值列表并且不需要parens,所以我将它们排除在外。 TEST ? TRUE-STATEMENT : FALSE-STATEMENT运算符从其他语言中已知。

然后,在你的循环,子会被调用像

for my $filename (@ARGV) { 
    my ($r, $w, $x) = getFileAttributes($filename); 
    say "The file $filename is $r, $w and $x"; 
} 

foreach my $file (@ARGV) { 
    my @attributes = getFileAttributes($file); 
    printf "The file $file is %s, %s and %s\n", @attributes; 
} 

注:

  • say就像print,但增加了一个换行符最后。要使用它,你必须有一个Perl> 5.10,你应该use 5.010或任何版本或use feature qw(say)

  • 总是use strict; use warnings;除非你知道的更好。

  • 通常,您可以编写程序而不必将变量分配给两次(单一赋值形式)。这可以使关于控制流的推理更容易。这就是全局变量(但不是全局常量)不好的原因。

+0

这个解释很棒! – simbabque

+0

非常好!谢谢。 – Loumont

-1

您没有实际使用全球varaibles。我将它们的变量作为本地主变量的变量,所以当您调用子例程时,$ file和@attributes被限定在子例程中,而不是主例程。

将我更改为我们的$ file和@attributes,使变量成为全局变量并且可用于子例程。

您可以通过使用perl的-d参数在调试器中运行它并检查项目的值来检查这一点。

+0

爆!那就是诀窍。非常感激。猜猜我需要在书中进一步阅读。 – Loumont

+0

很好。很高兴我能帮上忙。 – Glenn

+6

不好的建议;你比你受的伤更多。使用'我们'= aweful。移动'我'=穷人。使用args =完美。 – ikegami