>>>>> "BJ" == Ben Jones <> writes:
BJ> Hi, I'm farily new to oo perl, and wondered if either someone
BJ> could help me with the following problem, or suggest a less ugly
BJ> way of doing it...
just as a contrast to the doofus thread, note the good subject, good
background info and a respectful question.
BJ> I am creating an object whose attributes are loaded from various
BJ> data sources. Various groups of attributes are loaded from
BJ> specific sources, but I don't want the overhead of loading
BJ> attributes when client code hasn't asked for it yet, and might not
BJ> ever. I didn't want to write an accessor for each, so I thought
BJ> I's use AUTOLOAD. My AUTOLOAD method checks to see if the hash
BJ> attribute exists, and if it doesn't, calls a private method to
BJ> load the correct one. The first solution I thought of to
BJ> accomplish this was to use a hash, with the attribute sought being
BJ> the key, and the value being a ref to the apporpriate method. So
BJ> in non oo, something like this:
this sounds like a fine idea. but the first question is how much work is
it really to get all those attributes at construction time? if they
require slow things like file reads or DB access or page fetches and you
may never use them, your idea makes sense.
BJ> sub _load_attrs {
BJ> my $attr = shift;
BJ> my %attr_lookup = ( 'attr1' => \&method1,
BJ> 'attr2 => \&method2);
BJ> }
for methods you can just use the method name and call them.
my %attr_lookup = ( 'attr1' => 'method1'
'attr2 => 'method2');
my $method = $attr_lookup{ $attr } ;
$self->$method() ;
that is called late binding (among other names). one of perl's nice OO
features is generating method calls on the fly. note that this is NOT
the same as symbolic references which are evil.
now how you handle the AUTOLOAD will also make a difference. using
AUTOLOAD to access attributes will be slow. it should autogenerate
accessor methods on demand as well as initializing the attributes. then
the next time the accessor is called, it will have an installed method
and be initialized.
a simple (untested) version is this:
sub AUTOLOAD {
my $self = shift ;
my $attr = $AUTOLOAD ;
$attr =~ s/.*://;
*{$attr} = sub {
$_[0]->{$attr} = $_[1] if @_ > 1 ;
return $_[0]->{$attr}
} ;
goto &{$attr} ;
}
add your call to the initializer method before the magic goto call at
the end.
note how an intelligent question gets an intelligent answer with
examples and more. too bad doofus will never get help here again because
he got killfiled by too many.
uri
--
Uri Guttman ------
--------
http://www.stemsystems.com
--Perl Consulting, Stem Development, Systems Architecture, Design and Coding-
Search or Offer Perl Jobs ----------------------------
http://jobs.perl.org