in reply to goto and AUTOLOADed methods

That should be fine, although the assignment of $sub looks broken as the calling object doesn't have the $m method defined (unless the $m method is created in the AUTOLOAD call), otherwise AUTOLOAD wouldn't have been called. Also unless you're doing something really clever with $m that will loop forever as the calling object has AUTOLOAD defined, and without the $m method defined $sub will always end up pointing to the AUTOLOAD method and calling itself in the goto. Here's my take on AUTOLOADing methods
sub AUTOLOAD { no strict; (my $m = $AUTOLOAD) =~ s{.*::}(); *$m = make_method_here() if $m =~ /fulfils some condition/; croak "AUTOLOAD: can't access method $m"; unless defined *$m{CODE} and $_[0]->can($m); goto &$m; }

But as far as calling goto with a method name having left @_ intact, that nicely emulates a method call. The drawbacks would be that it'll be slow, and it's always a bit contentious dynamically creating/accessing methods via AUTOLOAD when quite often the likes of Class::Accessor will suffice (but as always, it's somewhat of a rule-of-thumb decision).
HTH

_________
broquaint

Replies are listed 'Best First'.
Re: Re: goto and AUTOLOADed methods
by fergal (Chaplain) on Aug 01, 2003 at 11:50 UTC
    Good point about the infinte loop thingy, although for my application it's not relevant. It's a pity you can't do
    $self->can("SUPER::method_name");

    I suppose I should explain my idea. I'm not doing autloaded accessors or anything like that. Here's a very rough idea of what I'm doing

    package UnloadedObject; use Class::MethodMaker ( new_hash_init => 'new', get_set => [qw( Table Class ID )] ) sub AUTOLOAD { my $method = $AUTOLOAD; $method =~ s/.*:://; my $table = $self->Table; my $id = $self->ID; my $class = $self->Class; my $self = $_[0]; my $sub = $class->can($method) || $class->can("AUTOLOAD"); die "Can't call $method on $class" unless defined($sub); bless $self, $class; %$self = (); $table->fillFromID($self, $id); goto &$sub; }
    So you pull some object out of your database and it has links to other objects but you obviously don't want to pull those objects out because that would pull out more sub objects and pretty soon, your whole database is in memory. So instead you just leave a "fake" object wherever there would be a sub object and you end up with something like
    my $me = $people->getByName("fergal"); my $name = $me->Name; # nothing special my $boss = $me->Boss; # still nothing special my $boss_name = $boss->Name; # bang! magic things happen and suddenly +$boss has all it's data loaded
    It's actually a little more complicated than that but that's the basic idea. I don't have to worry about AUTOLOAD loops because I'm not looking in the same class.

    UpdatedI changed $self to $class in the ->can sutff

      I guess the real point of most of the responses to your original question is that there isn't really that much difference between OO methods and non-OO subs. The "method" syntax is just that -- a bit of syntactic sugar to help people think objectly (object-oriently?)

      If you want to use goto in your AUTOLOAD and have your method think the method was called by the caller of AUTOLOAD, just do it and it will DWYM.

Re: Re: goto and AUTOLOADed methods
by ctilmes (Vicar) on Aug 01, 2003 at 11:22 UTC
    In general, I think it is good practice for AUTOLOAD to instantiate the sub (or method), then goto() it, so that next time it gets called directly instead of going through AUTOLOAD.

    If the instantiation is 'clean', there should be no difference between the first call and subsequent ones.

    That should offer the "least suprise" to the caller.