package Student;
use strict;
use warnings;
use Carp;


my $total = 0; #total number of students
our $DEBUG = 0; #print debugging info if true

use overload
    '""' => \&string;

#constructor.  Student will be passed a name and RIN.  GPA set to 0.
sub create {
    $total ++;
    my $class = shift;
    carp "Student name and/or RIN not passed, using undef" if @_ < 2;
    my ($name, $RIN) = @_;
    my $obj = { name=>$name, RIN=>$RIN, GPA=>0 };
    print "Added $name, with RIN: $RIN\n" if $DEBUG;
    bless $obj, $class;
}

#name accessor.  If an argument is passed, sets the name. Returns the 
#name either way
sub name{
    my $obj = shift;
    $obj->{name} = $_[0] if @_;
    return $obj->{name};
}

#RIN and GPA accessors are almost identical to name() above, so we'll add some error checking
sub RIN{
    my $obj = shift;
    if (@_){
	carp "RIN doesn't look like a RIN" if $_[0] !~ /^\d{3}-?\d{2}-?\d{4}$/;
	$obj->{RIN} = $_[0];
    }
    return $obj->{RIN};
}


sub GPA{
    my $obj = shift;
    if (@_){
	my ($GPA) = @_;
	if ($GPA !~ /^\d+(\.\d+)?$/){
	    carp "GPA is non-numeric, using 0";
	    $GPA = 0;
	}
	$obj->{GPA} = $GPA;
    }
    return $obj->{GPA};
}

#Report whether student is passing or failing
sub status {
    my $obj = shift;
    $obj->{GPA} >= 60 ? 'passing' : 'failing';
}

#overloaded stringification
sub string {
    my $obj = shift;
    "$obj->{name} ($obj->{RIN})";
}

#Destructor
sub DESTROY {
    my $obj = shift;
    $total--;
    print "$obj->{name} about to fall out of scope\n" if $DEBUG;
}

#report how many students we have
sub students {
    return $total;
}

1;  #surprisingly important statement!!
