Objects


[ Site Index] [ Attic Index] [ Perl Index] [ Feedback ]


Spooky music? Maybe not.

But sometimes you don't need to hear that twilight zone background to know that you've strayed over to the wrong side of the track, somewhere where Things Are Different.

A plaintive posting on comp.lang.perl.modules marked the spot where one hapless programmer realised that something wasn't quite right in Perl-land. He'd discovered Perl 5:

>I'm trying to use the Net::FTP module to look at a remote
>directory and get a file based on the results.
>Cutting and pasting from the man page:
>          use Net::FTP;
>
>           $ftp = Net::FTP->new("some.host.name");
>           $ftp->login("anonymous","me@here.there");
>           $ftp->cwd("/pub");
>           $ftp->get("that.file");
>           $ftp->quit; 
>
>Works fine if I already know what file I want. But if I dont
>I have to use:
>	$ftp->ls;
>
>But where does the result of the ls go?? How do I put it in
>a string scalar? And whats this -> business anyhow? Its not
>in the camel or the llama.

Perl 5 is to Perl (1-4) as C++ is to C. Except it's faster, smaller, more elegant, more powerful ... and harder to wrap your head around.

In particular, Perl 5 has a major advantage over Perl 4: it has References, and (by using them) Objects.

Our programmer, lost in the Twilight Zone of Perl 5, asked us, "whats this -> business anyhow?" To understand the answer, it helps to understand the most fundamental difference between Perl 4 and Perl 5.

Perl 4 had three types of data:

Perl 5 adds another item: the reference.

A reference is a pointer; it contains the address (in Perl's symbol table) of a variable or function. You stash references in scalars. You get hold of a reference by assaulting a variable name like this:

@fred = ("foo", "bar", "quux"); # fred is an array
$fred = \@fred;                 # $fred now contains a reference to @fred
You can get back at the original data like that:
print @$fred[1];  
This prints "bar" the first item in the array @fred.

To make it clearer, we can use the array constructor, @{ ... }:

@{ $fred }
The {} constructor means 'evaluate whatever's inside here as a pointer to an entity of type @.

You can equally well use %{} or ${} (which dereference as a hash or a scalar respectively), or even &{} (which supposes that what you're holding is a reference to the entrypoint of a function).

You can also have anonymous variables:

my $anon_hash = \{
                  "red", "dog",
                  "mad", "bull",
                  "blue", "sea"
                };
$anon_hash is a scalar containing a reference to The Hash with No Name.

You can print its contents like this:

foreach (keys ( %{ $anon_hash } ) {
    print "$_ -> ", ${$anon_hash}{$_}, "\n";
}
but it's maybe easier to do it as below, for the sake of readability:
my $anon_hash = \{
                  "red" => "dog",
                  "mad" => "bull",
                  "blue"=> "sea"
                };

foreach $item (keys ( %{ $anon_hash } ) {
    print "$item ->  $anon_hash->{$item} \n";
}
The => is a synonym for , (comma, the list separator operator), and the -> dereferences a variable through a hash, in much the same way that C lets you dereference bits of a structure through a pointer.

Anyway. It's time to explain about objects:

An object is an anonymous associative array. Some of its elements are references to functions (which are 'methods' that can act on its data). An object is 'blessed' so that it knows what kind of object it is; by knowing what it is, it can also figure out where its methods live.

You call 'new' to create a new object of type dog. You 'bless' the object, which tells it that it's a dog (meaning, that it knows to use the functions defined in the module dog.pm as its methods). You call 'eat' to get your dog to eat, or 'sleep' to tell your dog to sleep. The dog's data is stored with it in the dog module's symbol table, and because it's blessed with a sense of identity our dog knows that it's a four-legged-wooly-woofing-object.

Let's go over that once more, from another angle.

Suppose we have an object of type dog, called spot. The dog object, and it's associated methods, are defined in a module called "dog". Dog has a method called eat(). We tell spot to eat:

$spot->eat("dinner");
This could be written as:
&dog::eat($spot, "dinner);
But the OOP stuff gives us a neat way of encapsulating a set of data along with its appropriate functions. There's a reason for this, but I don't have time to write an wholesale exegesis about it here.

You can find out more about Perl objects if you read the Perl manpages -- specifically perlref (references) and perlobj (Perl objects). If you're feeling brave, try reading perlbot (Perl Bag'o'tricks). You may also want to order a copy of Programming Perl, Second Edition, which covers Perl 5.

Remember, it may be the Twilight Zone, but if you go there armed with a torch you should come through alright.


[ Site Index] [ Attic Index] [ Perl Index] [ Feedback ]