Beefy Boxes and Bandwidth Generously Provided by pair Networks
"be consistent"

Comment on

( #3333=superdoc: print w/replies, xml ) Need Help??

Every time I bring this up people say I'm bonkers. Here goes.

Occasionally Perl's OO system is bashed, because it's too lax, which is true in some respects. I guess the most sensible answer is "wait for Perl 6", or "use Java" for most arguments. That's what I hear, more often than not.

What I'm bringing up is one aspect of strictish OO that is handled in Perl. This is compile time field (properties, instance data) checking. What? compile time? Yes, fscking compile time, I'm not lying.

The fields pragma is, as far as I know, the least used useful module out there. This post is nothing but advocacy for it. Improperly used, it gives you no real benefits, except the implicit use of depracated features (pseudohashes), under Perl 5.8.

However, if you do all the steps you need to get the benefits, you end up with something pretty powerful, especially if you're a lousy typist, or can't read very well.

Say you are implementing a Dog. Some dogs are stupid. You might start out with something like this:

package Dog; sub new { my $pkg = shift; bless { intelligence => shift, }, $pkg; }
And then you add a method:
sub is_stupid { my $self = shift; return $self->{inteligence} < 3; }
Presto. You have a dog class. Now lets create $lassie. She is intelligent, right?
my $lassie = Dog->new(10); print "Lassie is " $lassie->is_stupid ? "dumb" : "smart";
Whoops. Warnings would help, but strict wouldn't. Anyway, you get the point. I typoed the field name, and everything broke. I could be pecking for hours, looking for that.

So lets get a little formal, and say what we define:

package Dog; use fields qw/intelligence/; sub new { my $pkg = shift; my $self = $pkg->fields::new(); $self->{intelligence} = shift; $self; }
So where does that get us? Well, nowhere. If you use base qw/Dog/ somewhere, the subclass would get that field, but that doesn't concern us now. Otherwise it's just a silly way to bless your $self.

The problem is that there's a general myth about fields, that that's all you're supposed to do, and that because it doesn't work, and to top it off uses pseudohashes, fields is bad. Both statements are false (the conclusion might not be, decide for yourself). Regarding the phashes, since 5.9 fields uses restricted hashes. The interface didn't change. In the future, fields might be implemented completely differently, and at the bottom line that's the point. You're not supposed to care that it uses phashes, because the phashes are hidden behind the usage interface.The other issue, well, we're getting there.

Lets move on to the my variable declaration. Notice that my TYPE $var syntax thingy? Well, it lets you tell perl that $var will be of class TYPE.

my Dog $lassie; # perl knows, at compile time, that lassie isa Dog
Aha! so If we do
package Dog; use fields qw/intelligence/; sub new { my $pkg = shift; my Dog $self = $pkg->fields::new; $self->{inteligence}; # typo again, but this time it doesn't compi +le $self; }
presto, we've got compile time field checking. If it were only a bit more concise, that could be really fun, but what does it matter. Go home and start using it.


Update: grammer fixes.

zz zZ Z Z #!perl

In reply to use fields; # damnit by nothingmuch

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, 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, 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.
  • Log In?

    What's my password?
    Create A New User
    Discipulus de gustibus non disputandum

    How do I use this? | Other CB clients
    Other Users?
    Others drinking their drinks and smoking their pipes about the Monastery: (4)
    As of 2017-04-28 11:26 GMT
    Find Nodes?
      Voting Booth?
      I'm a fool:

      Results (521 votes). Check out past polls.