为什么在Perl中可以全局访问函数

时间:2014-03-26 19:24:43

标签: perl function

我刚刚开始阅读有关Perl的内容。我知道现在提出问题还为时过早(我应该继续阅读),但我无法自拔。

我是一名c ++开发人员。我在Perl中注意到的是函数是“全局的”。你不需要“包含”任何东西来使用很多功能。例如,在c ++中,如果要使用string,则必须在stl中包含string。在perl中,您不必包含任何操作字符串或数字(数学函数)的内容。所以,我的问题是:

为什么要让一切都“公开”?如果我想操纵字符串,为什么我需要访问数学函数?

2 个答案:

答案 0 :(得分:8)

我认为Perl原本打算成为管理员的工具,因此为此提供了一个广泛的operators列表。他们中的一些人甚至可以访问数据库!

虽然这些在Perl世界中被称为函数(基于它们被记录的文件的名称),但它们在C ++意义上的单词 [1] <不是函数。 / SUP>。它们实际上是运算符 [2] ,就像notand一样。作为运算符,它们不受常规子程序语法的约束。例如,子程序无法复制printsystem的语法,这是构建这些语法的第二个原因。

不可否认,如果Perl今天写的,事情会有所不同。计算机科学领域一直在发明限制范围的新方法。我们现在更加重视封装和最小内核。大多数操作符将被编写为模块中的子例程,并且大多数具有异常语法的操作符将被设计为采用正常的子例程参数。这不是推测性的;你只需要看看Perl6,我就打赌你会发现这是真的。那为什么要把一切都公开呢?我们不应该。


  1. &#34;子程序&#34;是C ++称之为函数的Perl词。

  2. perlfunc的前两句是:&#34;本节中的函数可以作为表达式中的术语。它们分为两大类:列表运算符和命名的一元运算符。&#34;

    它们中的大多数最终被编译为Perl虚拟机中具有相同名称的运算符。

    >perl -MO=Concise,-exec -E"sub f { 'abcdef' }  say(substr(f(), 2, 3));"
    1  <0> enter
    2  <;> nextstate(main 48 -e:1) v:%,{,469764096
    3  <0> pushmark s
    4  <0> pushmark s
    5  <#> gv[*f] s
    6  <1> entersub[t3] sKS/TARG   <- A subroutine call
    7  <$> const[IV 2] s
    8  <$> const[IV 3] s
    9  <@> substr[t4] sK/3         <- substr operator
    a  <@> say vK                  <- say operator
    b  <@> leave[1 ref] vKP/REFC
    -e syntax OK
    

答案 1 :(得分:4)

与C ++不同,Perl具有大量预定义函数,其名称实际上是(几乎)关键字。 (根据ikegami的上述评论,他们是关键词,但不是保留词。)

例如,Perl的substr()内置于该语言中的方式与C ++ +的方式非常相似。

历史上,其原因是便利。编写可以执行中等复杂事物的1行Perl脚本非常常见,因为您不需要多行#include指令来启用常用功能。你也不需要定义一个&#34; main&#34;功能/子程序;执行只是从脚本的顶部开始:

$ perl -e 'print scalar localtime time, "\n"'
Wed Mar 26 13:30:04 2014

Perl还支持用户定义的功能,可以组织成模块;这些可以通过use指令获得。

可以使用相同的语法调用预定义的,用户定义的和模块定义的函数。

一个例子:

#!/usr/bin/perl

use strict;
use warnings;

use Time::HiRes qw(gettimeofday);

my $now = time();                   # time is a built-in function
my ($sec, $usec) = gettimeofday();  # gettimeofday() is defined in Time::HiRes
my $then = yesterday();             # yesterday() is defined below

print  "Yesterday:      $then\n";
print  "Now:            $now\n";
printf "More precisely: %d.%06d\n", $sec, $usec;

sub yesterday {
    return time() - 86400;
}