2

when running code like this:

use strict;
print Dumper "something";

nothing is printed out and no error occurs during compile and runtime. Why does this happen? Why doesn't strict prevent this code from running? Why is there no error at runtime, even though Dumper is unknown?

I know it produces a warning when those are explicitly enabled, but I'm interested why is this code considered "correct" in any way.

Mariusz Jamro
  • 30,615
  • 24
  • 120
  • 162
viraptor
  • 33,322
  • 10
  • 107
  • 191
  • possible duplicate of [Why does defined sdf return true in this Perl example?](http://stackoverflow.com/questions/1646997/why-does-defined-sdf-return-true-in-this-perl-example) – Sinan Ünür Nov 25 '10 at 03:58

2 Answers2

11

If you had begun with the standard boilerplate, then you would know:

#!/usr/bin/env perl
#
# name_of_program - what the program does as brief one-liner
#
# Your Name <your_email@your_host.TLA>
# Date program written/released
#################################################################

use 5.10.0;

use utf8;
use strict;
use autodie;
use warnings FATAL => "all";

#  ⚠ change to agree with your input: ↓
use open ":std" => IN    => ":encoding(ISO-8859-1)",
                   OUT   => ":utf8";
#  ⚠ change for your output: ↑ — *maybe*, but leaving as UTF-8 is sometimes better

END {close STDOUT}

our $VERSION = 1.0;

$| = 1;

The answer is that your program is syntactically but not semantically correct. You are printing "something" to the unopened Dumper filehandle-object, because Dumper is in the dative slot for the print method call. That makes Dumper print’s invocant. But you never opened a handle by that name, so you are printing to an uninitialized filehandle.

Use my boilerplate. PLEASE!

tchrist
  • 78,834
  • 30
  • 123
  • 180
  • 2
    @friedo: to make sure it autodies on a failure to flush and close stdout. Disk full. I/O error. Stuff like that. – tchrist Nov 25 '10 at 01:49
  • Setting autoflush ($|) by default is not a good practice. It sometimes makes sense, but not always, and should not be done in a boilerplate. At the very least, the boilerplate should have a comment indicating that it is optional. – William Pursell Feb 05 '11 at 14:17
7

One of the valid syntaxes for print is

print FILEHANDLE LIST

In your program Perl is treating Dumper as a filehandle glob.

Running this code with warnings enabled will tell you:

print() on unopened filehandle Dumper at ...

socket puppet
  • 3,191
  • 20
  • 16
  • Ok - I see that now. Do you know the specific reason why actions on unopened filehandles are not errors by default? – viraptor Nov 25 '10 at 00:57
  • 6
    @viraptor: Because you didn’t use my boilderplate. It’s because Unix never says *“please”,* and it never says *“I’m sorry.”* – tchrist Nov 25 '10 at 01:00
  • 8
    @viraptor: they *are* errors; print will return false indicating that it failed. They are also warnings, since they indicate a probable coding error. *Enabling warnings is more important than using strict.* They are *not* exceptions (though you can promote errors in all or selected built ins to be exceptions using `autodie`). – ysth Nov 25 '10 at 01:02
  • Also, had you done "print Dumper("something");" it would have failed correctly. The correct way is "print &Dumper("something");", though most people don't prefer this method. And I agree with ysth, I always use the shebash line #!/usr/bin/perl -w – Rahly Nov 25 '10 at 03:16
  • 1
    @Jeremy: Prefixing sub calls with `&` is generally considered to be a relic of Perl 4 and treated as more-or-less deprecated. Why do you claim `print &Dumper(...)` to be more correct than `print Dumper(...)`? `Also, `use warnings` tends to be preferred over `perl -w` these days, for a variety of reasons. – Dave Sherohman Nov 25 '10 at 09:36
  • print FILEHANDLE LIST isn't a print-specific syntax, it's indirect object syntax: http://perldoc.perl.org/perlobj.html#Indirect-Object-Syntax – Leolo Nov 26 '10 at 06:04