Beefy Boxes and Bandwidth Generously Provided by pair Networks
The stupid question is the question not asked
 
PerlMonks  

How can I use AUTOLOAD to magically define get and set methods for my member data?

( #8227=categorized question: print w/ replies, xml ) Need Help??
Contributed by Anonymous Monk on Apr 20, 2000 at 22:07 UTC
Q&A  > object-oriented programming


Answer: How can I use AUTOLOAD to magically define get and set methods for my member data?
contributed by Perlmage

Here's a slightly more complex version that creates actual methods on the fly so that you avoid the overhead of an AUTOLOAD method call on the second and successive calls.

It also uses magic GOTO, which is a cool hack in itself.

#!/usr/bin/perl -w
package myClass;
use strict;
use vars qw{$AUTOLOAD $Debug};

$Debug = 1;

sub new {
	return bless {
		thing	=> 1,
		thang	=> 2,
		thong	=> 3,
	}, shift;
}

sub AUTOLOAD {
	my $self = shift or return undef;

	# Get the called method name and trim off the fully-qualified part
	( my $method = $AUTOLOAD ) =~ s{.*::}{};

	# If the data member being accessed exists, build an accessor for it
	if ( exists $self->{$method} ) {

		### Create a closure that will become the new accessor method
		my $accessor = sub {
			my $closureSelf = shift;

			if ( @_ ) {
				return $closureSelf->{$method} = shift;
			}

			return $closureSelf->{$method};
		};

		# Assign the closure to the symbol table at the place where the real
		# method should be. We need to turn off strict refs, as we'll be mucking
	        # with the symbol table.
	  SYMBOL_TABLE_HACQUERY: {
			no strict qw{refs};
			*$AUTOLOAD = $accessor;
		}

		# Turn the call back into a method call by sticking the self-reference
		# back onto the arglist
		unshift @_, $self;

		# Jump to the newly-created method with magic goto
		goto &$AUTOLOAD;
	}

	### Handle other autoloaded methods or errors
}

DESTROY {}


### Test program
package main;

my $a = new myClass;

print $a->thing, $a->thang, $a->thong, "\n";
Answer: How can I use AUTOLOAD to magically define get and set methods for my member data?
contributed by saucepan

If you do this, you may want to provide a new can() method for people to use:

# can - Help UNIVERSAL::can() cope with our AUTOLOADed methods sub can { my ($self, $method) = @_; my $subref = $self->SUPER::can($method); return $subref if $subref; # can found it; it's a real method # Method doesn't currently exist; should it, though? return unless exists $self->{$method}; # Return an anon sub that will work when it's eventually called sub { my $self = $_[0]; # The method is being called. The real method may have been # created in the meantime; if so, don't call AUTOLOAD again my $subref = $self->SUPER::can($method); goto &$subref if $subref; $AUTOLOAD=$method; goto &AUTOLOAD }; }

(This one assumes that people will often call can() without intending to use the method ref it returns, and so it defers calling AUTOLOAD until someone goes to use it. Because of this, it needs a second check to see if someone else has already AUTOLOADed the desired method in the meantime.)

Answer: How can I use AUTOLOAD to magically define get and set methods for my member data?
contributed by chromatic

Here's a quick and dirty autoloader. It assumes your member data is stored in a hash, and that the get and set functions take the form "get_foo" and "set_bar".

use vars '$AUTOLOAD'; # a while later sub AUTOLOAD { my $self = shift; return if ($AUTOLOAD =~ /DESTROY/); # don't mess with garbage c +ollection if ($AUTOLOAD =~ /.*::set_(\w+)/) and (@_) { return $self->{$1} = shift; } elsif ($AUTOLOAD ~= /.*::get_(\w+)/) { return $self->{$1}; } # handle bad methods here, return undef ? }
Answer: How can I use AUTOLOAD to magically define get and set methods for my member data?
contributed by jeteve

Ok, for the non french reader, this is the AUTOLOAD method generating code :

sub AUTOLOAD{ my ($self,$value)= @_ ; return if $AUTOLOAD =~ /::DESTROY$/ ; my $attname = $AUTOLOAD; $attname =~ s/.*::// ; if(! exists $self->{$attname}){ Carp::confess("Attribute $attname does not exists in $self"); } my $pkg = ref($self ) ; my $code = qq{ package $pkg ; sub $attname { my \$self = shift ; \@_ ? \$self->{$attname} = shift : \$self->{$attname} ; } }; eval $code ; if( $@ ){ Carp::confess("Failed to create method $AUTOLOAD : $@"); } goto &$AUTOLOAD ; }
Answer: How can I use AUTOLOAD to magically define get and set methods for my member data?
contributed by jeteve

There's also a module I wrote that generates the accessor methods on demand at run time. You just have to inherit from and you can get/set all your instance variable automagically. It is dynamic and not time consuming since once the accessor method is generated, it's used as a regular perl method. Take a look at: Nice article and perl code It's in french. Enjoy !!

Please (register and) log in if you wish to add an answer



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • Outside of code tags, you may need to use entities for some characters:
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.
  • Log In?
    Username:
    Password:

    What's my password?
    Create A New User
    Chatterbox?
    and the web crawler heard nothing...

    How do I use this? | Other CB clients
    Other Users?
    Others wandering the Monastery: (12)
    As of 2014-08-01 08:08 GMT
    Sections?
    Information?
    Find Nodes?
    Leftovers?
      Voting Booth?

      My favorite superfluous repetitious redundant duplicative phrase is:









      Results (257 votes), past polls