develooper Front page | perl.perl5.porters | Postings from October 2007

Re: [perl #46987] OO-call failures, autoviv-functions & testing theirexistence

Thread Next
From:
Linda W
Date:
October 29, 2007 16:14
Subject:
Re: [perl #46987] OO-call failures, autoviv-functions & testing theirexistence
Message ID:
47266931.3050509@tlinx.org
yves orton via RT wrote:
> On 10/28/07, via RT Linda Walsh <perlbug-followup@perl.org> wrote:
>> This is a bug report for perl from perl-diddler@tlinx.org,
>> generated with the help of perlbug 1.35 running under perl v5.8.8.
> [...]
>>     my @dummy=(\&boom);                                         #ln 22
> [...]
>> The above prog demonstrates three (3) OO-call related problems.
>> Perl autovivifies "\&boom" into "@dummy" in "sub laytrap" (ln 22,
>> above). This *interferes* with OO calls through a blessed ref
>> later on in program execution.
> 
> IMO this isnt a bug. It may be confusing behaviour, but its not a bug.
> It works just the same as the equivalent code would work with a hash.
---
	Is referencing a "hash" guaranteed to check for references in a
parent before returning failure for a non-local definition?

	I don't think it is the same.  Part of OO functionality --
a MAJOR part, is that if the "method" is not defined local, they it
checks the parent classes.
	The error message tells the user "&localclass::method" isn't
found in "$self->parentmethod;".  The user will think "I know that.  It is
a parent method -- I wouldn't expect it to be in localclass.  Why doesn't
it do the standard OO-lookup *before* returning "undefined".  If I
DID NOT want an OO-call (that checks through parents), I could tell it
to call the function as a local function.  Instead of
     $self->method
I'd use:
     method($self).

But using the method-call syntax "$self->method", it should look through
the parent classes for the method *before* throwing the undefined-error.


> d:\>perl -e"my $x=\&foo; eval 'sub foo { warn qq(foo) }'; $x->()"
> foo at (eval 1) line 1.
> 
> d:\>perl -e"my %f; my $r=\$f{x}; $$r='testing'; print $f{x};"
> testing
> 
> The similarity in behavior is not unexpected, given that Perl's global
> symbol tables are really just hashes in disguise.
----
	BUT a hash table isn't something *DEFINED* to look in parent
classes.  A method-call is.  They are not symmetric.


> The code you marked as #ln 22, and quoted above is the problem.
> Essentially you are creating a function stub, which perl expects you
> to fill in later, but you haven't filled it in. Since this produces
> undesirable results you simply shouldn't do that. 
----
	Well this is the solution others come up with -- but no one
even knew "why" until I reported the bug.  It's confusing and not
behaving as the OO-language lookup is supposed to.

> You should do something like
> 
>    my @dummy; push @dummy,(\&boom) if defined *boom{CODE};     #ln 22
> 
> which takes a reference to the sub only if it is actually defined.
----
	That is yet ANOTHER great workaround.  That doesn't mean
that a call, through a Blessed-ref shouldn't, *FIRST*, do the parental
method lookup, before throwing the fatal error.  I would do the parental
lookup just before throwing the "Undefined" error -- it doesn't have
to be "optimized" -- just "work".

	This is another part that is "really wrong".  The user cannot
rely on the built-in "can()" function to determine if the method is
safe to call.  I tried to "protect" the calls -- but 'can' returns true
if there has been a reference to the same-name, but undefined local
function.  You can't use "defined($self->method)" as a replacement for
$self->can('method');

	I acknowledge that this is not as str8tforward a fix as one
might like, but I believe this area is hit more often than the bug
report numbers represent.  Too many perl-experts knew the workaround, but
couldn't say WHY what I was doing failed.  Narrowing down to the
point where I could get others to understand the bug and to where
felt I had a handle on it well enough to *report the bug*, took a bit
of persistence.  I'd guess most people wouldn't bother to find the "root
cause" let along get it to the point of filing it in a bug.


Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About