我正在阅读Simon Cozens的 Beginning Perl ,并在第8章 - 子程序中指出“子程序”是用户函数,而{{1} },print
,open
等是内置的运算符或函数。
他们是什么?它们是内置的,语言固有的特性(如C的split
运算符)还是它们实际上是sizeof
模块的子程序/函数?
如果它们是子程序,main
,while
,for
等也是子程序?那些运营商如unless
,+
,-
等等呢?
答案 0 :(得分:27)
print
,open
,split
不是子程序。它们不会导致子调用。它们甚至不存在于符号表中(在main::
或其他情况下,尽管您可以将它们称为CORE::split
等),并且无法获得对其代码的引用(尽管工作正在进行中)在CORE::
中为它们创建代理服务器,以便将它们视为子例程。它们就像+
一样是运算符。
$ perl -MO=Concise,-exec -e'sub f {} f()'
1 <0> enter
2 <;> nextstate(main 2 -e:1) v:{
3 <0> pushmark s
4 <#> gv[*f] s
5 <1> entersub[t3] vKS/TARG,1 <--- sub call
6 <@> leave[1 ref] vKP/REFC
-e syntax OK
$ perl -MO=Concise,-exec -e'split /;/'
1 <0> enter
2 <;> nextstate(main 1 -e:1) v:{
3 </> pushre(/";"/) s/64
4 <#> gvsv[*_] s
5 <$> const[IV 0] s
6 <@> split[t2] vK <--- not a sub call
7 <@> leave[1 ref] vKP/REFC
-e syntax OK
$ perl -MO=Concise,-exec -e'$x + $y'
1 <0> enter
2 <;> nextstate(main 1 -e:1) v:{
3 <#> gvsv[*x] s
4 <#> gvsv[*y] s
5 <2> add[t3] vK/2 <--- Just like this
6 <@> leave[1 ref] vKP/REFC
-e syntax OK
他们以各种名称而闻名:
大多数被认为是以下之一:
子程序通常被称为函数(因为它们在C和C ++中),因此“函数”是一个含糊不清的单词。这种含糊不清似乎是你问题的基础。
至于while
,for
,unless
等,它们是流量控制语句使用的关键字
while (f()) { g() }
和语句修饰符
g() while f();
答案 1 :(得分:11)
Perl关键字是Perl源代码分发中regen/keywords.pl
文件中定义的关键字。这些是:
__ FILE __,_ _ _ _,_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ UNITCHECK,CORE,DESTROY,END,INIT,CHECK,abs,接受,报警, 并且,atan2,bind,binmode,bless,break,caller,chdir,chmod, chomp,chop,chown,chr,chroot,close,closedir,cmp,connect, continue,cos,crypt,dbmclose,dbmopen,default,defined,delete, die,do,dump,each,else,elsif,endgrent,endhostent,endnetent, endprotoent,endpwent,endservent,eof,eq,eval,exec,exists, exit,exp,fcntl,fileno,flock,for,foreach,fork,format,formline, ge,getc,getgrent,getgrgid,getgrnam,gethostbyaddr,gethostbyname, gethostent,getlogin,getnetbyaddr,getnetbyname,getnetent, getpeername,getpgrp,getppid,getpriority,getprotobyname, getprotobynumber,getprotoent,getpwent,getpwnam,getpwuid, getservbyname,getservbyport,getservent,getsockname,getsockopt, 给定,glob,gmtime,goto,grep,gt,hex,if,index,int,ioctl, join,keys,kill,last,lc,lcfirst,le,length,link,listen, 本地,本地时间,锁,日志,lstat,LT,m,地图,mkdir,msgctl, msgget,msgrcv,msgsnd,my,ne,next,no,not,oct,open,opendir, 或者,ord,我们的,包,包,管,流行,pos,打印,printf,原型, push,q,qq,qr,quotemeta,qw,qx,rand,read,readdir,readline, readlink,readpipe,recv,redo,ref,rename,require,reset,return, 反向,rewinddir,rindex,rmdir,s,say,scalar,seek,seekdir, select,semctl,semget,semop,send,setgrent,sethostent,setnetent, setpgrp,setpriority,setprotoent,setpwent,setservent,setsockopt, shift,shmctl,shmget,shmread,shmwrite,shutdown,sin,sleep, socket,socketpair,sort,splice,split,sprintf,sqrt,srand,stat, state,study,substr,symlink,syscall,sysopen,sysread, sysseek,system,syswrite,tell,telldir,tie,tied,time,times, tr,truncate,uc,ucfirst,umask,undef,除非,unlink,unpack, unshift,untie,until,use,utime,values,vec,wait,waitpid, wantarray,warn,when,while,write,x,xor,y。
perlsyn , perlop 和 perlsub 联机帮助页需要阅读,其后可能是 perlfunc 联机帮助页。要了解如何覆盖与对象一起使用的内置运算符,请参阅 overload 联机帮助页。
答案 2 :(得分:1)
内置运算符不是Perl子例程。例如,
#!/usr/bin/perl
use strict;
use warnings;
sub Foo { print "In foo\n"; }
my $ref;
$ref = \&Foo;
$ref->();
$ref = \&print;
$ref->();
第一个$ref->();
是间接呼叫;它打印“In foo”。
第二个产生警告:
Undefined subroutine &main::print called at ./tmp.pl line 14
因为print
不是子程序的名称。
答案 3 :(得分:0)
简单地将“内置函数”视为您未创建的函数。容易吗? : - )