初学者 - 子程序混乱

时间:2012-11-03 02:34:45

标签: perl subroutine

我是初学者,并对此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;
}

2 个答案:

答案 0 :(得分: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]";
}

调用Subs

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运算符可以从其他语言中获知。

然后,在你的循环中,sub将被调用,如

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;
}

注意:

  • sayprint类似,但最后会添加换行符。要使用它,你必须有一个Perl> 5.10你应该use 5.010或任何版本或use feature qw(say)

  • 总是use strict; use warnings;,除非您确定更清楚。

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

答案 1 :(得分:-1)

您实际上并未使用全局变量。我将变量作为主程序的局部变量,因此当您调用子程序时,$ file和@attributes的范围限定为子程序,而不是主程序。

将my更改为$ for file和@attributes,使变量全局并可用于子程序。

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