我是初学者,并对此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;
}
答案 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;
}
注意:
say
与print
类似,但最后会添加换行符。要使用它,你必须有一个Perl> 5.10你应该use 5.010
或任何版本或use feature qw(say)
。
总是use strict; use warnings;
,除非您确定更清楚。
通常,您可以在不分配变量两次的情况下编写程序(单一赋值形式)。这可以使控制流程的推理更加容易。这就是全局变量(但不是全局常量)不好的原因。
答案 1 :(得分:-1)
您实际上并未使用全局变量。我将变量作为主程序的局部变量,因此当您调用子程序时,$ file和@attributes的范围限定为子程序,而不是主程序。
将my更改为$ for file和@attributes,使变量全局并可用于子程序。
您可以通过使用perl的-d参数在调试器中运行它并检查项的值来自行检查。