http://www.perlmonks.org?node_id=670917

In a legacy Perl module where I currently fix bugs at work (yes, the same), there is a certain hash that is accessed globally in the main namespace. To protect the innocent, let the name of the hash be foo. (In reality, it did have a descriptive name.) In a certain part of the file, I noticed the following two consecutive lines:

%foo ={}; unlink %foo;

Unless this is very arcane magic, this does nothing what the original programmer thought it would. In scalar context, the above hash evaluates to "1/8" on Perl 5.8.8 in Linux, so this would remove the file 8 in directory 1 in the current working directory. And no, unlink's return value or errors in deleting the "file" are not checked.

I'm guessing the intent was to empty the hash, then to make really, really sure that it is empty by calling some deletion function... What do you make of it? Why would a programmer write something like this? The funniest explanation will win.

UPDATE: Well, you learn something new every day. unlink takes a list as an argument, so the above would actually attempt to delete a file named HASH(0x814dc30) (the numbers may very in your machine). Still, assigning a hash reference into a hash is not what he meant to do either, that's for sure.

--
print "Just Another Perl Adept\n";

Replies are listed 'Best First'.
Re: The strangest use of unlink I know of
by kyle (Abbot) on Feb 28, 2008 at 16:19 UTC

    I thought it might be even more tricky still. Since %foo is empty, unlink gets an empty list. I thought that might mean that it would delete whatever is in $_ as if it got no argument, but that doesn't happen.

    my $test_file = 'file_of_doom'; die 'file already exists' if -e $test_file; system( "touch $test_file" ); die 'file not created' if ! -e $test_file; $_ = $test_file; my %foo = (); unlink %foo; print "file gone!\n" if ! -e $test_file;

    As it is, I think it just does nothing.

      Look more carefully. %foo is not empty. It was initialized with curly brackets -- almost ALWAYS a sign that the author made a mistake. Not a very humorous answer, but Wayne Jarvis is not paid to be funny.

      :|

      Still however -- the code indeed is a no op in terms of "useful" work. One needs to explicitly require %foo as a scalar:
      unlink scalar %foo;
Re: The strangest use of unlink I know of
by Your Mother (Archbishop) on Feb 28, 2008 at 16:55 UTC

    A hash won't resolve to HASH(0x814dc30) in list context; that's the stringification of a reference to a hash. Hashes flatten and return their keys and values in list context.

      The cute thing here is that the hash is initialized with a list of one item, a reference to an empty hash. So:

      $ perl -e '%foo = {}; print %foo, "\n";' HASH(0x814dc30)

      and (note the trailing comma, indicating an undefined value):

      $ perl -e '%foo = {}; print join(",", %foo), "\n";' HASH(0x814dc30),

      --
      print "Just Another Perl Adept\n";

Re: The strangest use of unlink I know of
by CountZero (Bishop) on Feb 29, 2008 at 06:42 UTC
    Was the original programmer of this code perhaps more familiar with another programming language which has a different meaning for unlink (such as releasing memory back to a pool)?

    CountZero

    A program should be light and agile, its subroutines connected like a string of pearls. The spirit and intent of the program should be retained throughout. There should be neither too little or too much, neither needless loops nor useless variables, neither lack of structure nor overwhelming rigidity." - The Tao of Programming, 4.1 - Geoffrey James

Re: The strangest use of unlink I know of
by sundialsvc4 (Abbot) on Feb 28, 2008 at 19:00 UTC

    Clearly, if it's a “thought question” as to what a particular bit of code is supposed to be doing, the obvious thing to do is to get rid of it ... immediately.

Re: The strangest use of unlink I know of
by chrism01 (Friar) on Mar 14, 2008 at 07:17 UTC
    Y, he was prob trying to release it, as a garbage collector only removes an 'object' when the 'link' count is zero, iirc.
    BTW, I never do OO programming, so apologies if I've got that wrong.