在perl中获取stdin输入有多少种方法?

lstz6jyr  于 2022-11-15  发布在  Perl
关注(0)|答案(2)|浏览(171)

我一直在学习perl,并发现这句格言很有趣。它说做任何事情都有多种方法。我知道你可以使用printsay来输出东西,但我还没有找到任何其他方法来读取输入,除了使用一个预定义的文件指针之类的东西。
还有别的办法吗?

erhoui1w

erhoui1w1#

这个问题太宽泛了。
有许多不同的方式可以从控制代码读取:

  • <>/readline(与$/ = $line_ending;一起使用)
  • <>/readline(与$/ = undef;一起使用)
  • <>/readline(与$/ = \$block_size;一起使用)
  • <>/readline(与$/ = "";一起使用)
  • getc
  • read
  • sysread
  • ...

还有一些工具可以处理终端。

  • 术语::读取密钥
  • 术语:读取行
  • 诅咒
  • ...

此外,控制代码可以多种方式表示。

  • 对IO值的引用(例如*STDIN{IO}
  • 包含IO值的glob(例如*STDIN
  • 引用包含IO值的glob(例如\*STDIN
  • 包含IO值的glob的名称(例如'STDIN'
  • IO::Handle对象

在一行程序中,-n-p-l-0-F-a-C都与标准DIN有一些联系。
...

nkcskrwz

nkcskrwz2#

我知道你问的是标准输入,但你的问题背后的想法可能需要一些澄清。我最终会达到这一点,但首先让我们想想这个问题的基础。
Perl有一句格言“There's More One Way To Do It”(TIMTOWTDI),但这实际上是在思考通往特定结果的路径,而不是开出每一个低级事物都有冗余或重复的处方。
有些事情有明显的冗余,因为任务以不同的方式出现,有时候有一个特殊的情况是如此普遍,它有自己的捷径,是这些特殊的用途导致了重叠,并不是每个原始人都必须有一个替代品。
例如,考虑stat函数,它返回一个我们所知道的关于一个文件(inode,不管什么)的信息列表,其中之一是最后一次修改时间(如果这对你的文件系统有意义的话)。

my $mtime = (stat $file)[9];

您可以取得两个档案的修改时间并加以比较,或者您可以使用修改时间来检查档案的年龄:

if( $mtime > (time-86400) ) { say "File is over a day old" }

但是,Perl及其sysadmin和报告路径知道这个任务是一个常见的任务,因此还有-M文件测试操作符,用于返回自程序启动以来的文件寿命(以天为单位):

if( -M $file > 1 ) { say "File is over a day old" }

如果你经常做这个任务,也许是因为你旋转日志文件,清理目录,或者其他什么,这个简短的,更适合的版本是很方便的(如果你能记住值的符号,因为过去是正的)。
这一思想包含了“主题”,Perl称之为$_,有些人非常非常讨厌它,因为你必须记住哪些东西对主题起作用,而不是重复你想使用的东西,你把它放在$_中,这样它就成了默认的东西:

$_ = 'some_file'
if( -M > 1 ) { say "$_ is over a day old" }

或使用后缀表示法:

say "$_ is over a day old" if -M > 1;

或者作为一句俏皮话,简洁是一种优点(在某种程度上):

$ ls | perl -lne 'print if -M > 1'

现在考虑标准输入。我们可以有一种语言,只有sysread从磁盘上获取原始的八位字节。我们必须处理各种各样的其他事情,比如构造行,知道何时停止,解码数据,等等。这是如此乏味,我甚至不打算打出这个例子。但是,更常见的是,我们想要读取文本行。readline为我们完成了所有工作:

open my $fh, ...;
while( readline($fh) ) { ... }

它还有一个同义词,如菱形运算符:

while( <$fh> ) { ... }

如果您需要标准输入(一个经常执行的任务),可以使用预定义的文件句柄名称:

while( <STDIN> ) { ... }

但是,从标准输入阅读是如此常见,以至于当在while中使用时,它也是<>的默认文件句柄,如下所示:

while( <> ) { ... }

差不多了,默认的文件句柄是ARGVARGV是另一个级别的快捷方式,它可以为您读取许多文件,并将它们显示为相同的输入源。如果没有明确的来源,它就可以处理标准的输入,这只是对我们可能想做的事情的另一种认可。
作为一名语言学家,Larry可能至少知道Zipf的“人类行为和最省力原则”。Zipf发展了一个工人的工具台的类比,在那里最常用的工具离工人最近,然后转向人类语言,在那里最常用的表达思想有最短的单词-M是一个经常被表达的概念,即使你可以用概念不可知的原语做同样的事情。而且,Larry经常谈到霍夫曼编码,在表示(如压缩)重复的事物时,最频繁出现的事物得到最短的代码。在拉里的程序设计语言中,最频繁的任务应该有最短的路径。
同样地,Perl有通用的方法,但是也认识到有一些特殊的、更专业的任务是足够通用的,它们应该有自己的语法或特殊的行为。你可以根据你的问题需要选择通用性的级别。
Perl的哲学是Python的“pythonic”思想的反面,在Python中,两个人做同样的工作,应该使用相同的原语,以相同的方式大致产生相同的代码。有一种首选的方式来做事情。这可能是有价值的,因为程序员不需要记住过长的编程内容列表来完成工作。即使共同的想法没有定制的结构,一个程序员团队应该有更少的风格和风格差异,这是有好处的。
Perl社区的某些部分也倾向于“Python”的想法,并使用他们喜欢的模块和习惯用法。这导致了TIMTOWTDIBSCINABTE(有不止一种方法可以实现它,但有时一致性也不是一件坏事)或TIMTOWTDIBMOTAW(有不止一种方法可以实现它,但大多数方法都是错误的)。

相关问题