From: <ik...@us...> - 2009-09-07 21:51:40
|
Revision: 55 http://webfetch.svn.sourceforge.net/webfetch/?rev=55&view=rev Author: ikluft Date: 2009-09-07 21:51:29 +0000 (Mon, 07 Sep 2009) Log Message: ----------- streamline autoload, exceptions Modified Paths: -------------- branches/v0.13/lib/WebFetch.pm Modified: branches/v0.13/lib/WebFetch.pm =================================================================== --- branches/v0.13/lib/WebFetch.pm 2009-09-07 01:56:55 UTC (rev 54) +++ branches/v0.13/lib/WebFetch.pm 2009-09-07 21:51:29 UTC (rev 55) @@ -146,6 +146,7 @@ 'WebFetch::Exception::MustOverride' => { isa => 'WebFetch::TracedException', + alias => 'throw_abstract', description => "A WebFetch function was called which is " ."supposed to be overridden by a subclass", }, @@ -1120,8 +1121,7 @@ # placeholder for fetch routines by derived classes sub fetch { - WebFetch::Exception::MustOverride->throw( - "fetch() function must be overridden by a derived module\n" ); + throw_abstract "fetch is an abstract function and must be overridden"; } @@ -1671,32 +1671,45 @@ ? $self->{wk2fnum}{$wk} : undef; } -=item AUTOLOAD +=item AUTOLOAD functionality +When a WebFetch input object is passed to an output class, operations +on $self would not usually work. WebFetch subclasses are considered to be +cooperating with each other. So WebFetch provides AUTOLOAD functionality +to catch undefined function calls for its subclasses. If the calling +class provides a function by the name that was attempted, then it will +be redirected there. + =cut # autoloader catches calls to unknown functions -# first try: redirect to the class which made the call, if the function exists -# second try: act as a read-only accessor for object data -# (want a read/write accessor? define the function explicitly) +# redirect to the class which made the call, if the function exists sub AUTOLOAD { my $self = shift; my $type = ref($self) or throw_autoload_fail "self is not an object"; my $name = $AUTOLOAD; - $name =~ s/.*://; # strip fully-qualified portion + $name =~ s/.*://; # strip fully-qualified portion, just want function - # skip all-caps special Perl functions + # decline all-caps names - reserved for special Perl functions + # if Perl core didn't handle this name, we won't mess with it either + my ( $package, $filename, $line ) = caller; if ( $name =~ /^[A-Z]+$/ ) { - return; + throw_autoload_fail "reserved function $name declined " + ." - called by $package ($filename line $line)"; } # check for function in caller package # (WebFetch may hand an input module's object to an output module) - my ( $package, $filename, $line ) = caller; if ( $package->can( $name )) { - my $retval = eval $package."::".$name."( \$self, \@_ )"; + # make an alias of the sub + { + no strict 'refs'; + *{__PACKAGE__."::".$name} = \&{$package."::".$name}; + } + #my $retval = eval $package."::".$name."( \$self, \@_ )"; + my $retval = eval { $self->$name( @_ ); }; if ( $@ ) { my $e = Exception::Class->caught(); ref $e ? $e->rethrow @@ -1706,14 +1719,6 @@ return $retval; } - # act as a read-only accessor - # add write accessors when API can specify what's OK to write - if ( exists $self->{$name}) { - # define the sub for better efficiency next time - eval "sub WebFetch::$name { return \$_[0]->{$name}; }"; - return $self->{$name}; - } - # if we got here, we failed throw_autoload_fail "function $name not found - " ."called by $package ($filename line $line)"; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |