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

2 回答 2

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不需要括号,所以我将它们排除在外。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;
}

笔记:

  • say就像print,但在末尾添加了一个换行符。要使用它,你必须有一个 Perl > 5.10 并且你应该use 5.010或者任何版本或use feature qw(say).

  • 总是use strict; use warnings;,除非你肯定知道得更好。

  • 通常,您可以编写程序而无需对变量进行两次赋值(单次赋值形式)。这可以使关于控制流的推理变得更加容易。这就是为什么全局变量(但不是全局常量)不好的原因。

于 2012-11-03T11:47:06.823 回答
-1

您实际上并没有使用全局变量。我将它们的变量范围限定为主例程,因此当您调用子例程时,$file 和 @attributes 的范围仅限于子例程,而不是主例程。

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

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

于 2012-11-03T02:48:49.210 回答