我最近一直在阅读有关Perl的内容,并且对于Perl如何处理传递给子例程的参数感到有些困惑.
在Python,Java或PHP等语言中,函数定义采用(伪代码)形式:
function myFunc(arg1, arg2) {
// Do something with arg1 and arg2 here
}
Run Code Online (Sandbox Code Playgroud)
然而在Perl中,它只是:
sub mySub {
# @_ holds all arguments passed
}
Run Code Online (Sandbox Code Playgroud)
据我了解,这是唯一的方法.
如果我想限制调用者只传递2个参数怎么办?
这不仅仅是Perl在其他语言(即Python,C等)中不允许任何变量数量参数吗?
在某些时候这不会成为问题吗?
其他语言中的所有默认参数号检查怎么样?是否必须在Perl中明确地做到这一点?例如
sub a_sub {
if (@_ == 2) {
# Continue function
}
else {
return false
}
}
Run Code Online (Sandbox Code Playgroud)在C++中我会做这样的事情:
void some_func(const char *str, ...);
some_func("hi %s u r %d", "n00b", 420);
Run Code Online (Sandbox Code Playgroud)
在PHP中我会这样做:
function some_func()
{
$args = func_get_args();
}
some_func($holy, $moly, $guacomole);
Run Code Online (Sandbox Code Playgroud)
我如何在Perl中做到这一点?
sub wut {
# What goes here?
}
Run Code Online (Sandbox Code Playgroud) 我有一个名为debug我在我的代码中使用的子程序.它基本上可以让我看到发生了什么,等等.
sub debug {
my $message = shift;
my $messageLevel = shift;
our $debugLevel;
$messageLevel = 1 if not defined $messageLevel;
return if $messageLevel > $debugLevel;
my $printMessage = " " x $messageLevel . "DEBUG: $message\n";
print STDERR $printMessage;
return $printMessage;
}
Run Code Online (Sandbox Code Playgroud)
我想要原型,所以我可以做这样的事情:
debug "Here I am! And the value of foo is $foo";
Run Code Online (Sandbox Code Playgroud)
要么
debug "I am in subroutine foo", 3;
Run Code Online (Sandbox Code Playgroud)
同时,我喜欢将子程序定义放在我的程序的底部,所以你不必在代码中用1/2来找到程序的内容.
我想这样做:
sub debug($;$); #Prototype debug subroutine
/Here goes the main program code/
sub debug { …Run Code Online (Sandbox Code Playgroud) 当我在Windows环境中调用我的Perl脚本而不perl先调用时,参数不会传递给我的脚本.
例如,
C:\> C:\my-perl-scripts\foo.pl bar
Run Code Online (Sandbox Code Playgroud)
调用foo.pl但不识别bar为参数(@ARGV为空).然而,
C:\> perl C:\my-perl-scripts\foo.pl bar
Run Code Online (Sandbox Code Playgroud)
按预期工作.
这是配置问题吗?
理想情况下,我希望能够分发一些perl脚本,让用户添加C:\my-perl-scripts\到路径,然后只需能够foo.pl在运行cmd时从任何地方调用.
如果他们必须首先指定perl,那么他们将始终必须提供完整的路径.
任何想法或建议?
编辑:为了显示我的系统上的assoc和ftype是正确的,我执行了以下命令.
C:\>assoc .pl
.pl=Perl
C:\>ftype Perl
Perl="C:\Perl\bin\perl.exe" "%1" %*
C:\>more t.pl
print "'$_'\n" for @ARGV;
C:\>t a b
C:\>perl t.pl a b
'a'
'b'
C:\>t.pl a b
C:\>
Run Code Online (Sandbox Code Playgroud)
我包括了t和t.pl的输出,以表明它不是%PATHEXT%问题.两者都没有像最初描述的那样输出,而调用perl首先给出了预期的响应.
我不知道下一步该去哪看,但感谢到目前为止的建议.他们非常乐于助人.
编辑2:问题似乎出现在我的vista业务框中.在我的XP专业版盒子上,它按预期工作.两者都有ActivePerl 5.8.9.我还有另一个尚未尝试的远景家用盒子.如果我发现任何事情,我会回复.
编辑3:我找到了答案(发布在下面).我通过运行注册表清理程序,删除perl,再次运行注册表清理程序找到它.在第二次清理时,只剩下一个无效条目 - 导致问题的条目(可能是以前的安装遗留下来的).
我尝试从这个建议创建一个脚本,如下所示:
#!/bin/bash
if [ $# -eq 0 ]; then
tail -f /var/log/mylog.log
fi
if [ $# -eq 1 ]; then
tail -f /var/log/mylog.log | perl -pe 's/.*$1.*/\e[1;31m$&\e[0m/g'
fi
Run Code Online (Sandbox Code Playgroud)
当我没有向脚本传递任何参数时,它显示文件的黑尾,但是当我传递参数时,每一行都是红色的.我希望它只为包含传递给脚本的单词的行着色.
例如,这将包含单词"info"的彩色线条:
./color_lines.sh info
Run Code Online (Sandbox Code Playgroud)
如何更改脚本以使用一个参数?
我正在尝试管理用户执行命令时指定的众多参数.到目前为止,我一直试图限制我的脚本设计来管理参数作为标志,我可以使用Getopt :: Long轻松管理,如下所示:
GetOptions ("a" => \$a, "b" => \$b);
Run Code Online (Sandbox Code Playgroud)
通过这种方式,我可以检查是否指定了a或b,然后执行相应的代码/功能.
但是,我现在有一种情况,用户可以指定两个参数变量,如下所示:
command -a black -b white
Run Code Online (Sandbox Code Playgroud)
这很好,但是我无法想出一个好方法来确定是先指定-a还是-b.因此,我不知道参数变量是在我执行时分配$ARGV[0]还是$ARGV[1]在分配之后GetOptions ("a" => \$a, "b" => \$b);.
在上面的示例中,如何判断哪个变量与哪个变量相关-a联-b?
我想将以破折号(-或--)开头的命令行选项传递给我正在使用以下标志运行的 Perl 程序-e:
$ perl -E 'say @ARGV' -foo
Unrecognized switch: -foo (-h will show valid options).
Run Code Online (Sandbox Code Playgroud)
传递不以-明显工作开头的参数:
$ perl -E 'say @ARGV' foo
foo
Run Code Online (Sandbox Code Playgroud)
我如何正确转义这些以便程序正确读取它们?
我尝试了很多变体,例如\-foo,,,,。尽管有些会产生不同的消息,但这些都不起作用。实际运行并输出.\\-foo'-foo''\-foo''\\-foo'\\-foo\-foo
这是一个Perl n00b问题,但我没有找到一个清晰易懂的在线回答.
我有这个代码:
1.sub remCH();
2.#some stuff
3.$line = remCH($line);
4.
5.sub remCH() {
6.$rem = shift;
7.$rem = chomp($rem);
8.return ($rem);
9.}
Run Code Online (Sandbox Code Playgroud)
执行此代码时总是会出现以下错误(第24行将在上面的代码中为第3行):
Too many arguments for main::rem_CRLF at ./make_csv.pl line 24, near "$line)"
Run Code Online (Sandbox Code Playgroud)
根据我的理解,这是因为函数设置为返回一些东西但是当我声明它时,它被声明为"void".
我如何声明如下函数???
sub remCH(string/integer);
Run Code Online (Sandbox Code Playgroud) 我试图通过此代码将变量从PHP文件传递到Perl文件
在php文件中:
exec("perl delete_all.pl $used");
Run Code Online (Sandbox Code Playgroud)
在perl文件中我正在尝试:filename.pl
print $used;
Run Code Online (Sandbox Code Playgroud)
但它不起作用.