`
alricren
  • 浏览: 28599 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

Perl Subroutine Prototype的作用

    博客分类:
  • Perl
阅读更多

      Perl Subroutine Prototype乍看之下是Perl提供了为Subroutine严格定义输入参数类型的一种途径。我们来看一下它的大致用法:

 

 

sub only_one_scalar_param($) {

}
only_one_scalar_param 1;         #正确
only_one_scalar_param(1);        #正确
only_one_scalar_param(1, 2);    #编译期间报错

 

 

要让Perl Subroutine Prototype能够正常工作,有如下几个条件

 

  1. subroutine的申明或者定义需要在编译期间可见,通俗点讲就是要在调用之前。
  2. 旧的Perl subroutine的调用是在subroutine前加上&,在加上&的情况下,Prototype也不起作用。
#定义在调用之后

only_one_scalar_param(1);          #正确
only_one_scalar_param(1, 2);      #正确,prototype没起作用

only_one_scalar_param 1;          #编译期间报错

sub only_one_scalar_param($) {

} 
 

 

sub only_one_scalar_param($) {
}
&only_one_scalar_param 1;         #正确
&only_one_scalar_param(1);        #正确
&only_one_scalar_param(1, 2)    #正确,prototype没起作用

 

 

      那Prototype的到底是用来做什么的呢? 在某些时候,Prototype确实可以用来检验输入参数(如最一开始的例子),并在编译期间就提示错误信息,但是实际上Prototype并不是如通常想象的那样,下面看一个例子

 

 

sub only_one_scalar_param($) {
       my( $value ) = @_;
       print "$value\n";
}

only_one_scalar_param(10);              #输出的是10
only_one_scalar_param(qw/1 2 3/);   #传入的是个list。 ?!没报错,输出的是3

 

      第一次调用的输出结果很容易让人理解,不过为什么第二次不仅没有错误,而且还输出的是3呢? 

      因为prototype定义的第一个参数是一个scalar,因此当遇上qw/1 2 3/这个list时,就将其转换成了scalar,即该list的长度。

 

那Prototype到底有什么用?

 

1.  省略括号

 

 

my @results = myfunc 3, 5;
#相当于 my @results = myfunc(3, 5);

#如果定义了prototype
sub myfunc($);
my @results = myfunc 3, 5;
#相当于 my @results = (myfunc(3), 5);

 

 

 

sub no_param(); #不可以使用参数


 

 

2.  编写类似built-in function的函数样式

 

 

sub mypush(\@@) {
       my( $array_ref, @to_push ) = @_;
       push @{$array}, @to_push;
}

mypush @array, 1, 2, 3;

 

 

使用Prototype可以让我们写出类似built-in function的subroutine,这是使用prototype的主要目的

 

 perlsub 写道
Because the intent of this feature is primarily to let you define subroutines that work like built-in functions, here are prototypes for some other functions that parse almost exactly like the corresponding built-in.

 

 

在其他情况下,使用Prototype是危险的!

 

再来看一个例子

 

 

use List::Util qw( min max );

sub clip_to_range($$@) {
       my ($min, $max, @data) = @_;

       return map { max( $min, min($max, $_) ) } @data;
}

clip_to_range(1, 2, (5..10));  
#min是1, max是2,data是(5..10)

my $range_ref = [1, 2];    #独立定义了一个range
clip_to_range(@{$range_ref}, (5..10));   
#使用这个range, 想表达和上面一次调用相同的意思,但是...
#min是2, max是5,data是(6..10)

 

 

为什么min是2呢? 因为@{$range_ref}被当成了第一个scalar参数,被转换成了长度,所以是2。而max则应该是下一个参数,Perl就从(5..10)中把5当做了max,余下的(6..10)就作为data。

 

程序真正执行的和自己预期的不相同,往往容易导致产生了Bug但是查不出来,因此最好避免这种情况的发生。上面的这个例子正是《Perl Best Practices》中的一条:“Don't use subroutine prototypes.

 

 

3
0
分享到:
评论

相关推荐

    Perl开发环境.zip

    例如,`if`语句、`for`和`while`循环、数组和哈希数据结构、子程序(subroutine)定义、模块导入等。同时,熟悉一些常用模块如`DateTime`(日期和时间操作)、`DBI`(数据库接口)、`LWP::UserAgent`(HTTP客户端)...

    Perl程序如何调用C代码

    它的主要作用是定义 C 函数如何被 Perl 脚本调用,以及在两者之间如何传递参数和返回结果。XS 语言的核心组件是 XS 接口描述文件,这些文件通常以 .xs 为后缀。 XS 语言的主要特性包括: 1. **参数处理**:XS 负责...

    神奇的perl两本perl入门教材合集

    1. **高级Perl特性**:比如引用、匿名函数、闭包、子过程(subroutine)以及模块的编写。 2. **网络编程**:介绍如何使用Perl进行HTTP、FTP等协议的通信,以及邮件发送、套接字编程等。 3. **数据库交互**:讲解如何...

    perl-5.32.1.tar.gz

    - **子程序(subroutine)**:类似于函数,可以封装代码并重复使用。 - **模块(module)**:Perl拥有丰富的模块生态系统,CPAN(Comprehensive Perl Archive Network)是世界上最大的开源软件仓库之一,提供了数万...

    Perl 5官方文档

    3. **块和控制结构**:Perl有if/else、while、for、foreach等控制结构,以及子程序(subroutine)和eval函数。 4. **符号表**:Perl使用符号表来跟踪变量和子程序,这是其动态类型的基础。 5. **上下文**:Perl的值...

    perl第四版及练习题答案和Perl 语言编程.chm

    在深入学习阶段,你需要了解Perl的面向对象编程,子程序(subroutine)和模块化编程,以及异常处理。此外,熟悉Perl的内置数据结构和高级正则表达式技巧将大大提高你的编程效率。 总的来说,Perl是一门功能强大的...

    Modern Perl原版和中文版

    9. **子过程和模块化**:通过子过程(subroutine)和模块,Perl可以实现代码的复用和组织。 10. **命令行选项**:Perl脚本可以直接作为命令行工具使用,接受参数和选项。 通过阅读"Modern Perl",开发者不仅可以...

    perl程序编写教程

    13. **模块化编程**:Perl中的子程序(subroutine)可以组织成模块,通过`require`或`require_once`引入。 14. **Perl最佳实践**:Perl社区有一套推荐的最佳实践,如Perl::Critic,可以帮助编写更清晰、可维护的...

    超好perl学习教程

    Perl还支持多种控制结构,如if-else语句、for和while循环,以及子例程(subroutine)。 压缩包中的`index.htm`可能是教程的主页面,提供目录或索引,引导用户浏览各个部分。`perl11.htm`、`perl13.htm`、`perl3....

    Intermediate Perl.pdf

    edition of Learning Perl. In the intervening years, Perl itself has grown substantially from a "cool" scripting language used primarily by Unix system administrators to a robust object-oriented ...

    perl语言自学手册

    8. **子程序(subroutine)**: Perl中的函数定义使用`sub`关键字,可以通过参数传递值,并可以使用`return`语句返回结果。 9. **错误处理**: 使用`eval`函数捕获运行时错误,`die`和`warn`函数用于抛出错误信息...

    Perl语言入门(Learning Perl).第五版.PDF

    读者将学习到条件语句(if-else)、循环结构(while、for、foreach)、子程序(subroutine)以及异常处理(eval)。理解这些概念对于编写结构化的Perl代码至关重要。 模块是Perl生态系统的一大特色,它允许程序员...

    perl中文参考手册

    此外,还会讲解流程控制结构,如if语句、while循环和for循环,以及如何使用子程序(subroutine)来组织代码。 在函数部分,手册涵盖了Perl内置的大量函数,如字符串操作函数(如`length`、`substr`)、正则表达式...

    perl多线程教程集

    Perl是一种强大的脚本编程语言,尤其在处理文本和系统管理任务方面表现突出。在现代软件开发中,多线程已经成为一种必要的并发处理机制,能够提高程序的效率和响应性。Perl同样支持多线程编程,这使得它在处理大规模...

    perl24 perl编程指南

    在"Perl24 Perl编程指南"中,读者将逐步学习如何组织代码(使用subroutine),如何处理错误(通过eval和die),以及如何调试程序(使用DB::DB模块)。教程还将介绍模块的安装和使用,以及Perl的面向对象编程概念。 ...

    perl 中文手册 CHM

    1. **基础语法**:包括变量定义、赋值、数据类型(如标量、数组、哈希)、控制结构(如if-else、for、while循环)、子程序(subroutine)等基本编程概念。 2. **正则表达式**:Perl以其强大的正则表达式引擎著称,...

    Perl 语言学习(自学绝佳资料)

    此外,Perl的子例行(subroutine)和块(block)结构使得代码组织更加模块化。 函数和模块是Perl编程的重要组成部分。函数是可重用的代码块,而模块则是封装功能的文件,可以使用use或require关键字导入。Perl的...

    Perl 参考大全

    "Perl参考大全"可能还会深入讲解一些高级话题,如正则表达式的高级用法、预编译的模式匹配、子程序(subroutine)的定义和调用、以及如何编写高效的Perl代码。同时,对于那些想要进行系统编程或Web开发的读者,书中...

Global site tag (gtag.js) - Google Analytics