Beefy Boxes and Bandwidth Generously Provided by pair Networks
Syntactic Confectionery Delight
 
PerlMonks  

In praise of Perl's object system.

by DStaal (Chaplain)
on Sep 08, 2010 at 19:39 UTC ( [id://859398]=perlmeditation: print w/replies, xml ) Need Help??

I was thinking about an old node of mine the other day, and got to pondering Perl's object system in general. I came to the conclusion that it's much better than it gets spoken of.

Most people coming to Perl's object system have already done object-oriented programming in one or more other languages. They know how it works, and what objects are. A typical thought on what an object is probably is something like this:

An object is a set of functions that know what data they are to operate on.

This is a decent, usable, understanding of what an object is. It is also subtly wrong. An object is:

An object is a set of data that knows what functions operate on it.

The difference is subtle, but quite important for understanding objects in Perl. In most languages, you get a set of dedicated grammar for defining the object, the data that is in it, and the functions that are related to it. Perl has cut these to an absolute minimum. In fact, Perl gets by with just a handful of words, and one new calling syntax:

  • bless()
  • SUPER
  • DESTROY()
  • overload

And the syntax: (I'm ignoring indirect syntax, as generally a bad idea.)

$foo->bar();  # The same as: 'bar($foo);' in the package $foo is blessed into.

That, for all normal intents and purposes, is it. (I could be missing something. Also, SUPER might be usable outside an object.) Everything that other languages do with private, public, property, etc. are all done using the above and other already existing features of the Perl language.

The most important one, and the one where that subtly-wrong definition will bite you, is bless(). It marks a reference to a set of data as being of an object. The functions that operate on this data are the functions in a specific package. (Defaulting, of course, to the current package.)

Note that Perl's packages are used for other things: They are the normal way to group related functions together. They can be used to limit scope, or to help organize code. Many many modules simply export functions from their own package into the calling package upon demand. So that grouping is not part of Perl's object system. It is part of Perl.

Also, there is no imposed structure on the reference that has been blessed. It can be any reference, of any type, and can be as complicated as you want it to be. (I haven't actually tried bless()ing a code reference, but I suspect it would work...) Perl allows references to point to structures that contain other references, so you can have arbitrary complexity, if you want it. You can also use that reference as a key into some other data structure(s), allowing for even more options.

This leads to some simple points: If the reference is directly to the data, then anyone can access that data through that reference. This is the same as 'public' data in many other languages. (With the same pros and cons.) If data is accessed via using the reference as a key into some other data structure, then the data is as private as that data structure. It can be 'protected' or 'private', as the case depends. Since the reference can contain data structures, the actual data can be stored in ways that allow all of the above, within a single class. All of this with one word of syntax, and the data storage techniques you already know!

Which brings the next point: Some of that data might be more important that other data. Or larger, harder to access, or need to be accessed more often, or... This isn't a problem for Perl, because object data is handled using the same tools as any other data. You need it done one way? Do it that way. You have the whole language to work with.

This 'object data is regular data, just marked as part of an object' extends into the one real syntax: the calling syntax. All it really does is say which package to look in for the function, and implies that the function gets one extra piece of data, your reference.

So, object functions are regular functions. You can even call them as regular functions, if you pass them the correctly-structured arguments.

There is no conceptual difference, in Perl, between anything that is an object, and anything that isn't. Data is data. Functions are functions. The programmer is free to do what they like with them. Objects are a way to organize code.

You want a singleton object? Just return the same data reference every time. You want a pool of objects? Keep a group of references, and alternate between them as you want. You want people to be able to access your data directly? Give it to them in the reference. You want to protect it? Have the reference point to a key for another data structure, that you keep hidden.

You want to be able to string object method calls to infinity? Ok, have them return their blessed reference. You want easy mutators for specific data elements? Simple enough to write.

Once I started to think about it, I realized the 'cryptic' OO-system in Perl isn't cryptic at all. It is just enough to make sure you can do anything you want, and nothing to get in your way.

It's beautiful. It's simple. It's powerful. It's Perlish.

Replies are listed 'Best First'.
Re: In praise of Perl's object system.
by BrowserUk (Patriarch) on Sep 08, 2010 at 20:24 UTC
    It's beautiful. It's simple. It's powerful. It's Perlish.

    Hear, here! Bravo! D'accord!

    • Hans Hofmann:

      The ability to simplify means to eliminate the unnecessary so that the necessary may speak.

    • E. F. Schumacker:

      Any intelligent fool can make things bigger, more complex, and more violent. It takes a touch of genius—and a lot of courage—to move in the opposite direction.

    • Charles Mingus:

      Making the simple complicated is commonplace; making the complicated simple, awesomely simple, that's creativity.

    • Henry David Thoreau ("Where I Lived and What I Lived For" Walden):

      Our life is frittered away by detail... Simplify, simplify, simplify! ... Simplicity of life and elevation of purpose.

    • William of Ockham (also known as Ockham's Razor)

      Plurality should not be assumed without necessity.

    • Mahlon Hoagland (Toward the Habit of Truth)

      Simplicity is indeed often the sign of truth and a criterion of beauty.


    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: In praise of Perl's object system.
by moritz (Cardinal) on Sep 08, 2010 at 20:50 UTC
    It's beautiful. It's simple. It's powerful. It's Perlish.

    I can't agree that it's Perlish. Perl was never about minimalism, and the object system is as minimalistic as possible.

    There are other indicators for the fact that the object system was bolted on afterwards: You have to know about the representation of objects (blessed references) to create one (compare with strings, where you just write "..." to create one), and the method call, a very common operation in OO code, uses a two-character syntax (compare to string concatenation, which is just one character).

    Yes, it's simple. It's also powerful. But not perlish.

    Also the fact that methods are just subs in a package is more of a burden than a blessing: it makes introspection of classical Perl 5 OO quite impossible, because you can never know if a sub is intended to be used as a method or a sub.

    If you use a module which imports subroutines, they show up as methods in your class when you introspect by looking into the package. Worse, they hide methods of the same name which a superclass might have provided.

    (Yes, there are ways to fix that - Moose and namespace::autoclean go long ways to help you with that - but it doesn't feel perlish to me that I have to install modules from CPAN to fix built-in behavior. It's just perlish that it's possible at all :-) ).

    Perl 6 - links to (nearly) everything that is Perl 6.

      There are other indicators for the fact that the object system was bolted on afterwards.
      Or as Larry likes to say, it wasn't "bolted on", it was "bolted through" :)
      It has often been claimed that Perl 5 OO was "bolted on", but that's inaccurate. It was "bolted through", at right angles to all other reference types, such that any reference could be blessed into being an object.
      The above Larry quote is taken from the "Some of the Problems with Perl 5 OO" section of A12.

      but it doesn't feel perlish to me that I have to install modules from CPAN to fix built-in behavior.

      Now that is very perlish - using modules to fix built-in behavior.

      use strict; use warnings;
      although those are pragmas, and core. But see also perl5i
        although those are pragmas, and core

        which makes all the difference when talking about installing, no?

        Perl 6 - links to (nearly) everything that is Perl 6.

      I can't say I agree. Perl 5's object orientation is high enough that you don't have to drop out of Perl 5 to extend it (for most things), and low enough that it doesn't trap you in any specific way of doing things. That's very perlish to me.

      If it weren't this powerful, we wouldn't have Moose today, but whatever people thought OO should be like when Perl 5 first got it.


      Ordinary morality is for ordinary people. -- Aleister Crowley

        This is exactly what I was thinking: A) the OO system in Perl5 is very Perlish to me and B) the low-level, flexible, "incompleteness" of it is the only reason we had a chance to arrive at a kit as cool and modern as Moose.

      Well, IMHO perl6 OO system is absolute much better than perl5. Nevertheless, what I worry about is perl6 is becoming a language but not a powerful tool language like perl5 does.

      What does powerful tool mean? people who use it can spend seconds to resolve the problem. He doesn't care about model, inherit and such. I hope perl6 doesn't need to sacrifice sys admin to becoming a true OO language.





      I am trying to improve my English skills, if you see a mistake please feel free to reply or /msg me a correction

        Just to be clear, I was talking about the Perl 5 object system, just as DStaal did.

        Now regarding your concerns, is there any reason to believe we are sacrificing usability for the average sysadmin?

        And would you care to explain the difference between a "language" and a "tool language"? I see a programming language as a tool to build programs with, so that distinction doesn't seem to make sense to me.

        Perl 6 - links to (nearly) everything that is Perl 6.
      Also the fact that methods are just subs in a package is more of a burden than a blessing: it makes introspection of classical Perl 5 OO quite impossible, because you can never know if a sub is intended to be used as a method or a sub.

      That's what documentation is for.

      Can you suggest one realistic scenario where there is a need to decide between a subroutine and a method at runtime?

      Please note. This is a genuine question. I can't think of one, but that doesn't mean that there isn't one.


      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.
        That's what documentation is for.

        Assuming a perfect world, in which you know which files to search in for documentation, I'd agree.

        Having worked with XML::LibXML I found the documentation to be scattered over so many different files (due to a steep inheritance hierarchy) that consulting the documentation was often more work than writing a small example, and using introspection.

        Can you suggest one realistic scenario where there is a need to decide between a subroutine and a method at runtime?

        Suppose you write some RPC interface, and the incoming data structure tells you what method to call on a certain object. In order to give the appropriate error message when it's not possible to call the method, you need to check if the method exists prior to calling it.

        You can't generally just try it, and catch a MethodDoesNotExist exception if it goes wrong, because that might be an internal error from within the called method too. And it's nice for the user to distinguish the "method does not exist" and "internal error while calling method" errors.

        But the real downside of the non-distinction between subs and methods is the fact that importing utility subs from modules makes them available as methods, and even if you don't care, somebody inheriting from your class wonders what's up with those weird method calls.

        This is a real problem, and has happened to the DBIx::Class users and developers. Their "solution" was namespace::autoclean, but it's really just a workaround, not a solution.

        Perl 6 - links to (nearly) everything that is Perl 6.
Re: In praise of Perl's object system.
by DrHyde (Prior) on Sep 09, 2010 at 13:00 UTC
    An object is a set of data that knows what functions operate on it.

    It's not so much that the bunch of data "knows" what functions operate on it, but that the data has some associated functions which it shares with other similar data.

    This, of course, leads us to see that an "inside-out object" must be a function with some associated data that it may share with other related functions. We normally call such objects "closures" :-)

Re: In praise of Perl's object system.
by JavaFan (Canon) on Sep 08, 2010 at 21:05 UTC
    It's beautiful. It's simple. It's powerful. It's Perlish.
    Yeah, it's as beautiful as regular expressions in C. Just like Perl's OO system, C has powerful regular expressions. C gives you arrays of integers, and with that, you can build any regular expression system you want. You want a DFA? Then use a DFA. You want POSIX matching rules? Go ahead, and do so. NFA? C isn't stopping you. Variable with lookbehind? Go on, just do it - C is giving you all the tools you need.

    As you can see, due to it's simplicity, C's regular expressions are way more powerful and flexible than Perls.

Re: In praise of Perl's object system.
by sundialsvc4 (Abbot) on Sep 14, 2010 at 00:38 UTC

    It is also worth keeping in mind that “Perl has a history.”   It has been around for quite some time now, and there are (believe it or not...) many millions of lines of “mission-critical” (Perl-5) source code in service right now.   Therefore, anything that Perl does, today, must keep one foot firmly in the future and one foot firmly in the present.

    It doesn’t take much for (say...) an academic-person to try to change the world by inventing a “new and improved” language.   Hell, IBM tried to do that in 1964 with PL/1.   It was a very serious effort that is still (of course...) in service today, but it didn’t do what it was really intended to do.   It didn’t displace FORTRAN, and it didn’t displace COBOL, either.   When you have invested millions of dollars into millions of lines of source-code that works, no amount of “new and improved” is ever going to persuade the accountants ... or the stockholders.

    Perl’s object-system, therefore, has “pressing engineering constraints.”   And-d-d-d, Perl being Perl, Perl has risen admirably to the occasion!   The object-features of Perl-5 are efficient and fast, and packages like Moose clearly demonstrate just how far it can be pushed.

    Language implementors, of course, never rest on their laurels.   PL/1 remains quite viable.   Perl is in the process of evolving a whole new manifestation of itself.   And we even have ADD 1 TO COBOL GIVING COBOL.

    And... folks are making money for their companies using all of these technologies.   And they are managing to do that without rewriting all of the code that was written before (as earnestly as they might want to do so!).

    And... maybe... that is what really matters most.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlmeditation [id://859398]
Approved by moritz
Front-paged by moritz
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others pondering the Monastery: (5)
As of 2024-04-16 18:14 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found