package Complex; use Carp; #a '_' prefix on variables is a common way to indicate private # variables. (Note that in Perl nothing is actually private # ... well that is a lie - you can use encapsulation to make # variables private, so if you want really private variables # then go read Damian Conway's "Object Oriented Perl" ). sub _REAL {0} #_REAL is a constant '0' sub _IMAG {1} #_IMAG is a constant '1' sub new { my $class = shift; #get class name ('Complex') my $real = shift; #get first argument my $img = shift; #get second argument my $self = [$real, $img]; #create anon array with arguments bless $self, $class; #bless the array as a Complex object return $self; #return our new object } sub AUTOLOAD { my $sub = $AUTOLOAD; #get global $AUTOLOAD function name my $self = shift; #get the current object my $value = shift; #get an optional parameter $sub =~ s/.*://; #strip off package name #let the system handle 'DESTROY' function calls return if $sub =~ /DESTROY/; #make function call upper case to match our constants my $sub = uc($sub); #call the function (should be 'REAL' or 'IMAG' which will # return 0 or 1 respectively). The eval will trap runtime # errors in case someone calls a function that is not _REAL # or _IMAG. my $position = eval("&_".$sub); #if the position is not a number then they called something # bogus like $obj->print, which would call &_PRINT from the # eval, then $postion would be 'undef' unless( $position =~ /\d/ ) { croak("Subroutine undefined: \"$AUTOLOAD\""); } #if no parameter then they just want the Real or Imag value # returned instead of set. if( not defined $value ) { #return the value associated with the position in the array # that was returned from the eval above. return $self->[$position]; } else { #a value was passed in, so assign it to the position in the # array that was returned from the eval above. This # returns $value also, which is not strictly needed; return $self->[$position] = $value; } }