Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is the perl print filehandle syntax the way it is?

Tags:

oop

perl

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?

like image 262
Krishna Nandamuri Avatar asked Sep 13 '13 19:09

Krishna Nandamuri


People also ask

What is a Filehandle in Perl?

A filehandle is an internal Perl structure that associates with a file name. Perl File handling is important as it is helpful in accessing file such as text files, log files or configuration files. Perl filehandles are capable of creating, reading, opening and closing a file.

How do I print a Perl statement?

print() operator – print operator in Perl is used to print the values of the expressions in a List passed to it as an argument. Print operator prints whatever is passed to it as an argument whether it be a string, a number, a variable or anything. Double-quotes(“”) is used as a delimiter to this operator.

How do you open a file for read and write in Perl?

If you want to open a file for reading and writing, you can put a plus sign before the > or < characters. open DATA, "+>file. txt" or die "Couldn't open file file.


2 Answers

Since the comma is already used as the list constructor, you can't use it to separate semantically different arguments to print.

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

would just look like you were trying to print the values of 3 variables. There's no way for the parser, which operates at compile time, to tell that $fh is going to refer to a file handle at run time. So you need a different character to syntactically (not semantically) distinguish between the optional file handle and the values to actually print to that file handle.

At this point, it's no more work for the parser to recognize that the first argument is separated from the second argument by blank space than it would be if it were separated by any other character.

like image 168
chepner Avatar answered Nov 16 '22 01:11

chepner


If Perl had used the comma to make print look more like a function, the filehandle would always have to be included if you are including anything to print besides $_. That is the way functions work: If you pass in a second parameter, the first parameter must also be included. There isn't one function I can think of in Perl where the first parameter is optional when the second parameter exists. Take a look at split. It can be written using zero to four parameters. However, if you want to specify a <limit>, you have to specify the first three parameters too.

If you look at other languages, they all include two different ways ways to print: One if you want STDOUT, and another if you're printing to something besides STDOUT. Thus, Python has both print and write. C has both printf and fprintf. However, Perl can do this with just a single statement.

Let's look at the print statement a bit more closely -- thinking back to 1987 when Perl was first written.

You can think of the print syntax as really being:

print <filehandle> <list_to_print>

To print to OUTFILE, you would say:

To print to this file, you would say:

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

The syntax is almost English like (PRINT to OUTFILE the string "This is being printed to myfile.txt\n"

You can also do the same with thing with STDOUT:

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

As a shortcut, if the filehandle was not given, it would print to STDOUT or whatever filehandle the select was set to.

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";

Now, we see the thinking behind this syntax.

Imagine I have a program that normally prints to the console. However, my boss now wants some of that output printed to various files when required instead of STDOUT. In Perl, I could easily add a few select statements, and my problems will be solved. In Python, Java, or C, I would have to modify each of my print statements, and either have some logic to use a file write to STDOUT (which may involve some conniptions in file opening and dupping to STDOUT.

Remember that Perl wasn't written to be a full fledge language. It was written to do the quick and dirty job of parsing text files more easily and flexibly than awk did. Over the years, people used it because of its flexibility and new concepts were added on top of the old ones. For example, before Perl 5, there was no such things as references which meant there was no such thing as object oriented programming. If we, back in the days of Perl 3 or Perl 4 needed something more complex than the simple list, hash, scalar variable, we had to munge it ourselves. It's not like complex data structures were unheard of. C had struct since its initial beginnings. Heck, even Pascal had the concept with records back in 1969 when people thought bellbottoms were cool. (We plead insanity. We were all on drugs.) However, since neither Bourne shell nor awk had complex data structures, so why would Perl need them?

like image 41
David W. Avatar answered Nov 16 '22 02:11

David W.