# rudimentary support for a kind of oop in Perl
# This most important new "feature" here is "bless".

package team;   # package is kind of like "class"

sub maketeam
{
    my ($wins,$losses) = @_;
    my $hash = 
    {
      wins => $wins,
      losses => $losses
    };
    bless $hash, "team";  # tags structure with a type (class) name
}

# now for the methods, the first parameter of these methods must always
# be the object structure (i.e., the hash table).

sub win
{
    my $this = shift;
    $this->{wins} += 1;
}

sub lose
{
    my $this = shift;
    $this->{losses} += 1;
}

sub wp  # winning percentage
{
    my $t = shift;  # don't have to call it "this", it's just a var
    $t->{wins} / (1.0 * $t->{wins} + $t->{losses});
}

# --------   now for a subclass ----------------

package hockeyteam;

@ISA = ("team");

# There's nothing deep going on here! "ISA" is just a package-global 
# variable that defines (as strings!) a list of other packages that it
# "inherits".

sub makehockeyteam
{
    my ($wins,$losses,$ties);  # hockey teams can tie

    # create superclass instance - SUPER is "team" by virtue of the ISA list!
    my $hash = team->maketeam($wins,$losses);

    # add the sub-class specific stuff to the structure
    $hash->{ties} = $ties;

    # AND NOW FOR THE MIRACULOUS RELIGIOUS CONVERSION:
    bless $hash, "hockeyteam";  
    # The team is now born again as a hockeyteam.  Praise the lord!
    
} # subclass constructor


# subclass methods
sub tie
{
    my $this = shift;
    $this->{tie} += 1;
}

# We also need to "override" the super class'es wp method

sub wp  # winning percentage (a tie is half a win)
{
    my $t = shift;  # don't have to call it "this", it's just a var
    ($t->{wins}+($t->{ties}/2.0)) / (1.0 * $t->{wins} + $t->{losses} + $t->{ties});
}

# now for some objects:

$rangers = makehockeyteam(0,0,0);
$rangers->lose();  # here, it has to use the ISA var to look up the method
$rangers->win();
$rangers->win();
$rangers->tie();
print $rangers->wp(), "\n";



#---
# What's unsatisfactory about this approach to oop?  Well, the most
# obvious one is that there's no encapsulation: everything is public.
# We can get encapsulation using the function-closure method but 
# then inheritance becomes cumbersome.  Thus, we again see a need (or
# at least a reason) for languages such as C++ and Java.

