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

nevdka has asked for the wisdom of the Perl Monks concerning the following question:

I've recently been debugging an old script. It predates our version control system. It predates our coding standards. It predates all our existing developers. As far as I can tell, it predates every tool we currently use, other than perl itself.

I've found some code that seems bizarre to me. There are a bunch of use constant declarations at the top, and they are used as array keys in some code that pretends to be object oriented, like so:

use constant PARENT => 0; use constant PROGRESS => 1; sub new { my ($class) = @_; my $this = []; bless ($this, $class); $this->[PARENT] = undef; $this->[PROGRESS] = 0; return $this; }

To me, this looks like a dodgy cargo cult way of doing an ordered hash. But then I started wondering, what if it simply predates hashes? Can anyone shed any light on this? (before I remove all history of my interaction with this file...)

Replies are listed 'Best First'.
Re: Is this ancient perl or just a cargo cult?
by chromatic (Archbishop) on Nov 01, 2013 at 05:11 UTC

    It doesn't predate hashes; hashes were in the earliest versions of Perl.

    Perl lets you bless any reference (scalar, hash, array, function, filehandle, glob) as an object. Most objects are blessed hashes, but that's not necessary.

    Accessing array elements is a little bit faster than accessing hash entries. Using a named constant as an array index lets you access object attributes directly by name and gives you a little more compile-time typo protection. It's rare, so most people probably who know about it don't consider it worth the trouble.


    Improve your skills with Modern Perl: the free book.

Re: Is this ancient perl or just a cargo cult?
by BrowserUk (Patriarch) on Nov 01, 2013 at 05:20 UTC
    To me, this looks like a dodgy cargo cult way of doing an ordered hash.

    It is neither dogdy; nor cargo-cult; nor do they pre-date hashes. Both became available at exactly the same time with the advent of blessed references circa. 5.001.

    The code is using a blessed array rather than a blessed hash as the basis of its objects. This is more compact and faster than the "normal" blessed hashes.

    The constants give programmer-friendly names to the fields; whilst still allowing the field lookups to be optimally efficient.

    For completeness, field lookup with a hash still requires an array lookup; but first the key (field name) has to be translated into an index number. And then, if you happen to be unlucky, there might need to be a linear search as well.

    blessed arrays with named constant field indexes are a less used, but perfectly valid, highly functional and more efficient way of implementing objects in Perl.


    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
Re: Is this ancient perl or just a cargo cult?
by boftx (Deacon) on Nov 01, 2013 at 06:12 UTC

    If you squint just a little bit it's not that hard to move back and forth between this:

    sub new { my ($class) = @_; my $this = []; bless ($this, $class); $this->[PARENT] = undef; $this->[PROGRESS] = 0; return $this; }

    and this:

    sub new { my ($class) = @_; my $this = {}; bless ($this, $class); $this->{PARENT} = undef; $this->{PROGRESS} = 0; return $this; }

    As others have already pointed out above, there are some performance perks to using a blessed array ref instead of a hash ref, but I think many of us back then felt that a hash ref was just more "natural" for an object (can the old far.... err ... C programmers like me say "struct"? I knew you could.)

    The answer to the question "Can we do this?" is always an emphatic "Yes!" Just give me enough time and money.