如何使用所需参数创建子程序?

问题描述:

Perl中是否可以声明一个子例程,以便在调用参数时不会将参数传递给它?如何使用所需参数创建子程序?

+2

如何在编译时判断f(@a)是否将参数传递给'f'? – ikegami

+0

理论上可以使用Devel :: CallChecker或B :: CallChecker进行某种编译时检查,但这需要您熟悉Perl内部知识,并且有许多失败模式。例如。它只会在某些子程序调用时不能用于方法。如果在列表上下文中评估任何参数,它将不起作用。 Perl的核心是一个动态语言。子进程可变大小列表,而不是固定大小的参数元组。我只是很高兴语言只是足够静态检测未知的潜艇和变量,不像更多的动态语言,如Python。 – amon

+0

PPR呢? – simbabque

我认为这种类型的事情是关于最好的,你目前可以做的:

#!/usr/local/bin/perl -w 
use strict; 
require 5.020; 
use warnings; 
use feature qw(say signatures); 
no warnings "experimental::signatures"; 

print "Enter your first name: "; 
chomp(my $name1 = <STDIN>); 

print "Enter your last name: "; 
chomp(my $name2 = <STDIN>); 

say "Calling takesOneOrTwoScalars with 2 args"; 
takesOneOrTwoScalars($name1, $name2); 

say "Calling takesOneOrTwoScalars with 1 arg"; 
takesOneOrTwoScalars($name1); 

say "Calling takesOneOrTwoScalars with 0 args"; 
takesOneOrTwoScalars(); 

sub takesOneOrTwoScalars($firstName, $lastName="") 
{ 
    print "Hello, $firstName"; 
    if ($lastName) 
    { 
     say " $lastName"; 
    } 
    else 
    { 
     say ", I see you didn't give your last name."; 
    } 
} 
+3

请注意,这只会在传递不适合的参数列表时产生*运行时错误*。我不需要签名功能。例如:'用鲤鱼; ... croak“takeOneOrTwoScalars的参数太少”if @_ 2' – amon

一些可以与 prototypes (persub)来实现,在一定程度上

Perl的支持非常有限使用函数原型设计进行编译时参数检查。
...
......这个功能的目的主要是为了让你定义的工作就像内置功能

例如宣布为sub f1(\@)sub f2($$)子程序,潜艇只能被称为f1(@ary)(数组变量,@)和f2(SCALAR, SCALAR)或者存在编译时错误。

但还有很多其他细节,有很多细微的疑虑;请阅读下面的文档和链接。原型而不是类似于编译语言中的函数签名,并且不打算做那个工作,即使它们可能以这种方式出现。即使轻微的误用也会导致微妙的错误。见

所有这一切说如果适当地使用时,它们可以是有用的。见OP ikegami的评论。