Example: Implementation of Car in Perl

Previous Table of Contents Next

Example: Implementation of Car in Perl

Listing 18.1 shows how a simple car could be represented in Perl. This listing should be saved as Car.pm.

To create a class in Perl, a constructor must bless a reference into the class. What this means is a reference (it doesn't matter what type, most people use hash references) is going to be created within the new subroutine. The bless function will take that reference and associate it with the class as an instance. The new subroutine should then return that reference.

Listing 18.1. First Part of the Car Class

1: #!/usr/bin/perl -w


3: use strict;

4: package Car;


6: my $model_name = "RoadPerl";

7: my $vin = 1;


9: sub new {

10:    my $car = {

11:        vin => $vin++,

12:        rpm => 0,

13:    };

14:    bless $car;    

15: }

Line 4: This establishes that all the package variables mentioned within, and all the subroutines, will be in the Car namespace. With a class, you don't need to export any subroutine names, which differs from the modules you saw last hour.

Lines 6Ц7: These variables will be visible only within this class. Because any subroutine in the class can see them, and they're not inside of your blessed reference; these are called class variables.

Lines 10Ц13: A hash reference is created. Because it will be passed to every method called by this class, you've put some information in it that's unique to each car produced. The VIN, or vehicle identification number, starts at 1 and goes up for each car you produce, and the RPM (engine speed) is initialized to 0.

Line 14: The reference is blessed into the class. The bless function returns the reference, so it's usually the last statement in the constructor.

There's no rule that says that the constructor for Car has to be called new; it's just convention. In fact, your class can have as many constructors as it wants, or none at all. But it's a little pointless without a constructor.

Listing 18.2 continues our Car Class by providing methods to get the speed of the car and the VIN. Methods that are simply returning properties of a class are called accessor methods.

Listing 18.2. Property Methods in the Car Class

16: sub vin {

17:     my($self)=@_;

18:     return $self->{vin};

19: }

20: sub speed {

21:     my($self)=@_;

22:     return $self->{rpm}/100;

23: }

Line 17: When the vin method is called (because it is a method) the first argument to the subroutine will be a copy of the original blessed reference from line 13. Normally, the first line of the method takes the argument list from @_ and moves it into more meaningful variable names. By tradition, the object itself is called $self.

Line 18: With the original reference in hand, it's a simple matter of retrieving the VIN number from the hash reference and returning it.

Lines 21Ц22: Again, $self is set to the original reference. This time you've taken the RPM speed of the engine, done a little math on it, and returned a speed for the vehicle.

The Car Class's next two methods, shown in Listing 18.3, control the car's internals and provide the Car's actions.

Listing 18.3. Methods in the Car Class

24: sub brake {

25:     my($self)=@_;

26:     $self->{rpm}=0;

27:     print "Skreetch!\n";

28: }

29: sub accelerate {

30:     my($self,$value)=@_;

31:     $self->{rpm}=$self->{rpm} + $value;

32:     if ($self->{rpm} > 10) {

33:         die "Engine blew up in " . $self->{vin};

34:     }

35:     print "Vroom!\n";

36: }

Lines 25Ц27: If the brake method is called on a car object, this subroutine will set the motor rpm back to zero and print a message. This is done by using the $self reference, and manipulating the RPM value in the hash.

Line 30: If the car wants to accelerate, it has to call this method with an additional value to indicate how much acceleration to give the car. This is stashed into $value.

Line 31: The value passed in is used to increment the RPM of the car.

Lines 32Ц35: If you accelerate too many times or too much, the engine will blow up, and the program will stop. Otherwise a satisfying message will print.

Finally, Listing 18.4 provides methods to get information about the entire Car Class. Because an object instance isn't required to use these, they're called class methods.

Listing 18.4. Remainder of the Car Class

37: sub model_name {

38:     return $model_name;

39: }

40: sub models_sold {

41:     return $vin-1;

42: }

Lines 38 & 41: Notice that these methods don't use $self. Why? Because the value returned is the same for every instance of this class. This is information that the class knows about itself and about all the instances of the class.

You can call class methods in any of the following ways:

Car->model_name();  # Probably the preferred style

Car::model_name();  # Using the package name directly, see Hour 17

$car->model_name();  # Using an instance of Car works too.

Using the Car Class

Now you have a car class. How do you use it? Using the class, it would look like this:

my $newcar = new Car;

So now $newcar contains a blessed reference into the car class. What does this mean? If you use that reference with the method operator ->, functions within that class will be called, like so:

print $newcar->vin();

When Perl sees this it will call the vin subroutine inside of the Car class. As an added bonus it will pass a copy of that original reference as the first argument to the subroutine vin.

If you want your car to accelerate, you'll need to pass an additional value indicating how much:

print $newcar->accelerate(2);

Again, Perl finds the class that $newcar has been blessed into, finds the accelerate subroutine, and calls it. It will be called with two arguments: the reference (as all methods are) and the value 2. You know that internally, it will be used to increase the car's RPM. But from our perspective, it will just print Vroom!.

Listing 18.5 is a small program to create a sort-of race. Several cars will be created, each one will accelerate
Previous Table of Contents Next

© 2000- NIV