Data Members as Variables

If you're used to C++ objects, then you're accustomed to being able to get at an object's data members as simple variables from within a method. The Alias module provides for this, as well as a good bit more, such as the possibility of private methods that the object can call but folks outside the class cannot.

Here's an example of creating a Person using the Alias module. When you update these magical instance variables, you automatically update value fields in the hash. Convenient, eh?

    package Person;

    # this is the same as before...
    sub new {
	 my $that  = shift;
	 my $class = ref($that) || $that;
	 my $self = {
	    NAME  => undef,
	    AGE   => undef,
	    PEERS => [],
	bless($self, $class);
	return $self;

    use Alias qw(attr);
    use vars qw($NAME $AGE $PEERS);

    sub name {
	my $self = attr shift;
	if (@_) { $NAME = shift; }
	return    $NAME;

    sub age {
	my $self = attr shift;
	if (@_) { $AGE = shift; }
	return    $AGE;

    sub peers {
	my $self = attr shift;
	if (@_) { @PEERS = @_; }
	return    @PEERS;

    sub exclaim {
        my $self = attr shift;
        return sprintf "Hi, I'm %s, age %d, working with %s",
            $NAME, $AGE, join(", ", @PEERS);

    sub happy_birthday {
        my $self = attr shift;
        return ++$AGE;

The need for the use vars declaration is because what Alias does is play with package globals with the same name as the fields. To use globals while use strict is in effect, you have to pre-declare them. These package variables are localized to the block enclosing the attr call just as if you'd used a local on them. However, that means that they're still considered global variables with temporary values, just as with any other local.

It would be nice to combine Alias with something like Class::Template or Class::MethodMaker.