in reply to Choosing between AUTOLOAD vs Delegation

Please help me to identify whether I should stick with AUTOLOAD or should I move to Class::Delegator class.

Three thoughts come to mind reading your post:


With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.

The start of some sanity?

Replies are listed 'Best First'.
Re^2: Choosing between AUTOLOAD vs Delegation
by tobyink (Canon) on Mar 12, 2012 at 17:41 UTC

    I agree with your:

    *{ __PACKAGE__ . '::' . $methodname } = $connect->can( $methodname );

    ... in principle, but in practice it has a subtle bug. (OK, there's the $connect versus $connection typo too, but we'll ignore that as strict mode should make it obvious.)

    The first time the autoloaded method is called, the connection object is passed to the method as its invocant. Subsequent calls will get the device as the invocant.

    What should be used is something more like:

    sub AUTOLOAD { no strict 'refs'; *{__PACKAGE__.'::'.$methodname} = sub { (shift)->getConnection->$methodname(@_) }; return (shift)->getConnection->$methodname(@_); }

    Also it's worth noting that whenever you write an AUTOLOAD method, it's worth considering writing a can method, because the default method inherited from UNIVERSAL::can ignores autoloaded methods.

    Class::AutoloadCAN explains the issues around AUTOLOAD and can and offers a solution. Personally I've found Class::AutoloadCAN a little buggy myself and ended up re-implementing it on a module-by-module basis (e.g. these __autoload, can and AUTOLOAD methods).

    perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'