I would like to premise that I've some experience now and even though I consider myself to be well far away from being an expert, I would have never expected that it could happen to me to be bit in the neck by open()...

I premise that I always

use strict; use warnings;
so that even if I make frequent mistakes, perl rapidly helps me finding them by complaining loudly. In this case however, the program seemed to be fine at all effects except that it silently "didn't work".

Now, this problem I had had to do with a method that properly trimmed down to a bare minimum looked like this:

sub parse { my ($self,$hashref)=@_; open my $fh, '<:raw', $self->{FILE} or die $!; while (<$fh>) { chomp; $hashref->{$_}++ for split; } }
Now it happened that I made a trivial mistake in that I called it like a sub (from another method) and like all trivial mistakes it didn't appear to be trivial until I spotted it, which took quite a while.

Conclusion: What happened? "Obviously" that the hashref given as explicit argument was dereferenced and the value corresponding to the key 'FILE' was accessed, which in turn was undef, so that as per perldoc -f open an anonymous (empty) file was opened for reading and the code in the loop was never executed (so that the fatal error it would have triggered for dereferencing an undef value never popped out either!)

Why didn't do the obvious checks (e.g. definedness in the first place) on the filename I was about to open()? Because basically I was already doing them in the method that called the one (corresponding to that) above.

As a side note, I wonder wether perl could emit a warning when one tries to open() an anonymous file for reading (or for writing) only... or are there common situations in which it could be desirable to do so?

Update: I've noticed that the cmt above has been completely misunderstood, hopefully this followup explains better what I really meant.

For a complete but minimal example check this:

#!/usr/bin/perl -l use strict; use warnings; package Foo; sub new { my ($self,$file)=@_; bless { FILE => $file }, $self; } sub parse { my ($self,$hashref)=@_; open my $fh, '<:raw', $self->{FILE} or die $!; while (<$fh>) { chomp; $hashref->{$_}++ for split; } } package main; my ($file,%hash)=shift; Foo->new($file)->parse(\%hash); # right Foo::parse(%hash); # wrong print for keys %hash; __END__
Of course the two lines marked with cmts above are very different and it's hard to imagine how one could type mistakingly the latter for the former, but in my real case it was much less so, IMHO.

In reply to I've been bit in the neck by open() by blazar

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.