14

I am wondering why the perl creators chose an unusual syntax for printing to a filehandle:

    print filehandle list

with no comma after filehandle. I see that it's to distinguish between "print list" and "print filehandle list", but why was the ad-hoc syntax preferred over creating two functions - one to print to stdout and one to print to given filehandle?

In my searches, I came across the explanation that this is an indirect object syntax, but didn't the print function exist in perl 4 and before, whereas the object-oriented features came into perl relatively late? Is anyone familiar with the history of print in perl?

4

4 回答 4

4

由于逗号已用作列表构造函数,因此您不能使用它来分隔语义上不同的print.

open my $fh, ...;
print $fh, $foo, $bar

看起来就像您试图打印 3 个变量的值。在编译时运行的解析器无法告诉它$fh在运行时将引用文件句柄。因此,您需要一个不同的字符来在语法上(不是语义上)区分可选文件句柄和实际打印到该文件句柄的值。

在这一点上,解析器不再需要识别第一个参数与第二个参数被空格分隔,而不是它被任何其他字符分隔。

于 2013-09-13T22:06:05.153 回答
3

如果 Perl 使用逗号使print看起来更像一个函数,那么如果您要包含除$_. 这就是函数的工作方式:如果传入第二个参数,则还必须包含第一个参数。在 Perl 中没有一个函数可以在第二个参数存在时第一个参数是可选的。看看split。它可以使用零到四个参数来编写。但是,如果要指定 a <limit>,则还必须指定前三个参数。

如果您查看其他语言,它们都包含两种不同的打印方式:一种是您想要 STDOUT,另一种是您要打印到 STDOUT 以外的其他语言。因此,Python 同时具有printwrite。C 有printffprintf。然而,Perl 只需一条语句就可以做到这一点。

让我们更仔细地看一下 print 语句——回想一下 Perl 第一次编写的 1987 年。

您可以将print语法视为真正的:

print <filehandle> <list_to_print>

要打印到OUTFILE,您会说:

要打印到这个文件,你会说:

print OUTFILE "This is being printed to myfile.txt\n";

语法几乎是英语(PRINT to OUTFILE the string "This is being printing to myfile.txt\n"

你也可以对 STDOUT 做同样的事情:

print STDOUT "This is being printed to your console";
print STDOUT " unless you redirected the output.\n";

作为一种快捷方式,如果没有给出文件句柄,它将打印到 STDOUT 或选择设置为的任何文件句柄。

print "This is being printed to your console";
print " unless you redirected the output.\n";

select OUTFILE;
print "This is being printed to whatever the filehandle OUTFILE is pointing to\n";

现在,我们看到了这种语法背后的思想。

想象一下,我有一个通常会打印到控制台的程序。但是,我的老板现在希望在需要时将一些输出打印到各种文件中,而不是 STDOUT。在 Perl 中,我可以很容易地添加一些 select 语句,我的问题就会得到解决。在 Python、Java 或 C 中,我将不得不修改我的每个打印语句,并且要么有一些逻辑来使用文件写入STDOUT(这可能涉及文件打开和复制到 STDOUT 的一些 conniptions。

请记住,Perl 并不是为了成为一种成熟的语言而编写的。编写它是为了比 awk 更轻松、更灵活地完成解析文本文件的快速而肮脏的工作。多年来,人们使用它是因为它的灵活性,并且在旧概念之上添加了新概念。例如,在 Perl 5 之前,没有引用之类的东西,这意味着没有面向对象编程之类的东西。如果我们在 Perl 3 或 Perl 4 时代需要比简单的list, hash,scalar变量更复杂的东西,我们必须自己处理它。复杂的数据结构并非闻所未闻。C 从一开始就有 struct 。哎呀,即使是帕斯卡也有记录的概念回到 1969 年,当时人们认为喇叭裤很酷。(我们以精神错乱为由辩护。我们都在吸毒。)但是,既然 Bourne shell 和awk复杂的数据结构都没有,那么 Perl 为什么需要它们呢?

于 2013-09-16T17:02:50.147 回答
2

回答“为什么”可能是主观的,接近于“拉里喜欢它”。

但是请注意,间接对象表示法不是 的一个特性print,而是可以与任何对象或类和方法一起使用的一般表示法。例如与LWP::UserAgent.

use strict;
use warnings;
use LWP::UserAgent;

my $ua = new LWP::UserAgent;

my $response = get $ua "http://www.google.com";
my $response_content = decoded_content $response;
print $response_content;

任何时候你写method object,它的意思都是一样的object->method。另请注意,只要您不嵌套此类符号或不使用复杂的表达式来获取对象,解析器似乎只能可靠地工作,因此除非您想在括号和引用中获得很多乐趣,否则我建议您不要使用它除了 IO 方法的常见情况和其余 IO 方法之外的任何print地方close

于 2013-09-16T13:23:36.810 回答
0

为什么不?它简洁且有效,符合 perl 的 DWIM 精神。

很可能是那样,因为拉里沃尔喜欢那样。

于 2013-09-13T19:43:03.230 回答