12.5. Tips for the C++ or Java Programmer

The object-oriented features of Perl may appear frighteningly sparse; in fact, they are the consequence of a careful design to avoid unnecessarily bloating the language. For instance, there is no this keyword for referring to the current object in a method; instead, it's passed as the first parameter, and you can pick your own name. Most people pick $self because the declaration my $self … has a nice ring to it (or because they are former Smalltalk programmers).

Run-time semantics alone determine whether a routine is an object method or a class method, so you can easily write one that swings both ways. (A common idiom makes an object method out of a constructor.)

There is nothing special about a constructor method in Perl; you can call it anything you want, but most Perl programmers call it new to make you feel welcome. Not only is the underlying implementation of an object exposed, but you get to implement it yourself from a bewildering array of choices. (The one you'll feel most comfortable with is a hash; don't even look at the others until you've gotten the hash under your belt.) And there is no native support for creating instance data attributes or inheriting them, although there are optional pragmata (base, fields) that provide some syntactical sugaring for doing so.

Regardless, your callers should not access your instance data directly but instead via accessor methods. You may use a module (such as Class::Struct) to create those methods automatically, although it seems that any class worth writing these days requires custom logic in each accessor method anyway.

It is possible for a caller to modify the object's instance data directly unless you go to great lengths to make the instance data as private as you're accustomed to. (See “Closures as Objects” in the perltoot documentation page.) This is rarely perceived as a problem in Perl since the philosophy is that people who fiddle with instance data directly when the specification for the public interface to the class doesn't permit it deserves whatever they get.

Because there are no function prototypes (of the kind you're used to) in Perl, there is no method overloading with different prototype signatures. You get to validate the number and type of arguments you're called with at run time, if you want.

You cannot enforce abstract (pure virtual) methods to be overridden at compile time, but you can create one that throws a run-time exception, unless it has been overridden.

You'll find more methodical comparisons among Perl, C++, and Java in Damian Conway's excellent book, Object-Oriented Perl (Manning, 1999).

12.5.1. Specific Tips for the Java Programmer

In Perl you have the option of creating a program that is not at all object-oriented and—horrors—isn't even a class. This is actually the best approach for solving many problems, as hard as it may be to get out of the habit of doing a class hierarchy decomposition every time you write a program.

The issue of “to what extent code you publish for reuse should be object-oriented” has engendered fiercely partisan arguments in the Perl community, with impassioned advocates at both ends of the spectrum. The upshot of this is that you can take whatever position you want and justify it by an appeal to authority.[4] Our rule of thumb is: If you're writing something just for your own use which is not likely to have significant reusability, the overhead for making it object-oriented is unlikely to be worthwhile. If you're writing something to be used by other people, an O-O interface will probably be worth the effort, considering how neatly it separates the interface from the implementation and relieves you of the need to provide any more support than simply ensuring that the interface lives up to its promises.

[4] Use everything to your advantage ...

Garbage collection in Perl does not happen asychronously, but is entirely deterministic (except for the order in which objects are freed during global destruction at the end of a program). When the reference count on an object drops to zero, it is destroyed immediately.

Although Java allows you to inherit from only one concrete base class and multiple abstract classes, Perl makes no distinction between the two kinds of class and says that you can do as much multiple inheritance as you like. You may find that your fears about incestuous inheritance relationships do not come to pass, however.

Reflection in Perl is accomplished by several methods. If the object $obj is implemented as a hash, you can discover its set of attributes with keys %$obj. You can find out if it supports a given method meth with $obj->can('meth'), and you can get a list of all the methods it supports by traversing the symbol table for the package looking for subroutines. Finally, you can construct its inheritance hierarchy by following the @ISA array package variable or by using the CPAN module Class::ISA (http://search.cpan.org/search?dist=Class-ISA) which provides a friendly interface for that.

Finalizer chaining does not happen automatically in Perl either—the Perl term for finalize is DESTROY—and for much the same reasons as in Java.

In keeping with the Perl philosophy of permissiveness, there is no equivalent of final to prevent a method from being overridden in a derived class.

12.5.2. Specific Tips for the C++ Programmer

The lack of strong typing which probably seemed liberating to the C programmer probably seems offensive to you. (Perl may seem irritatingly free-form until you grasp the Perl ethos.)

Perl does have operator overloading, although it isn't used as often as you'd think. perldoc overload tells you all about it.

Because Perl doesn't have strong typing, you won't need to construct template classes for generic operations since they're generic to begin with.

We personally find the use of references in C++ to be annoying, because a change in a function prototype can change the actual value that is passed in a call to the function. If you actually like this feature, you can replicate it—after a fashion—with what Perl calls subroutine prototypes. They won't look like prototypes to you—they're more like patterns specifying the order and types of arguments that can be passed—but one of the consequences is that you can construct a prototype that will allow a subroutine to be called with an array and receive a reference to that array where it would normally receive the list of all the elements in the array.

We suggest you not be too hasty to avail yourself of this feature, primarily because unlike C++, Perl does not require prototypes to be declared in order for a program to work, and if yours somehow fail to get declared—or get declared too late—then the semantics of your program will change in wonderfully unpredictable ways.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset