Click here to get back home

weird bug

 HomeNewsGroups | Search | About
 comp.lang.perl.misc    Post an article   get this group's latest topics as an RSS feed add this group's latest topics to your My MSN content add this group's latest topics to your My Yahoo content
Subject Author Date
weird bug kj 04-18-2008
Posted by kj on April 18, 2008, 1:27 pm
Please log in for more thread options


The following short module illustrates a puzzling bug:

use strict;
package Foo;
my $x = +{ 1 => 'one' };

sub foo {
keys %$x if 0; # should do nothing
my $y = eval '$x'; die if $@;
printf "%d\n", scalar keys %$y;
}

1;
__END__


OK, now: the following one-liner produces the expected output:

% perl -MFoo -e 'Foo::foo()'
1

...but if one comments-out the first line of Foo::foo, the output changes:

% perl -MFoo -e 'Foo::foo()'
0

Note that the line that was commented out should do nothing, because
it ends with the conditional qualifier "if 0". Therefore, this
line is essentially a no-op and should have absolutely no effect
on the execution of this code.

I'm seeing this behavior with v. 5.8.8. Does anyone see it also
with more recent versions?

I have no doubt that this is a bug, but I can't begin to figure
out why it's happening. Any light that may be thrown on this puzzle
would be much appreciated.

Also, is there a better solution to this problem than including
silly "voodoo code" like the first line in Foo::foo?

TIA!

Kynn

--
NOTE: In my address everything before the first period is backwards;
and the last period, and everything after it, should be discarded.

Posted by xhoster on April 18, 2008, 1:51 pm
Please log in for more thread options
> The following short module illustrates a puzzling bug:
>
> use strict;
> package Foo;
> my $x = +{ 1 => 'one' };
>
> sub foo {
> keys %$x if 0; # should do nothing
> my $y = eval '$x'; die if $@;
> printf "%d\n", scalar keys %$y;
> }
>
> 1;
> __END__

The appearance of $x in %$x causes the subroutine to take out and
hold a "reference" to $x. The appearance of $x in the string eval
doesn't cause that happen. I assume that when the __END__ is encountered,
the "my $x" goes out of scope, decrementing the refcount. In the one
case, the refcount is decremented to zero, and $x is freed. Later, when
the string eval is invoked, it operates on this freed $x.


> Also, is there a better solution to this problem than including
> silly "voodoo code" like the first line in Foo::foo?

Change
my $y = eval '$x';
to
my $y = eval ;

That way, the use of $x is not hidden from the subroutine so it knows to
keep a reference to $x.

Unless there is a good reason you were using '$x' instead of in the
first place. I can't think of such a reason off the top of my head.

Xho

--
-------------------- http://NewsReader.Com/ --------------------
The costs of publication of this article were defrayed in part by the
payment of page charges. This article must therefore be hereby marked
advertisement in accordance with 18 U.S.C. Section 1734 solely to indicate
this fact.

Posted by Ben Morrow on April 18, 2008, 1:59 pm
Please log in for more thread options

>
> The following short module illustrates a puzzling bug:
>
> use strict;
> package Foo;
> my $x = +{ 1 => 'one' };
>
> sub foo {
> keys %$x if 0; # should do nothing
> my $y = eval '$x'; die if $@;
> printf "%d\n", scalar keys %$y;
> }
>
> 1;
> __END__
>
>
> OK, now: the following one-liner produces the expected output:
>
> % perl -MFoo -e 'Foo::foo()'
> 1
>
> ...but if one comments-out the first line of Foo::foo, the output changes:
>
> % perl -MFoo -e 'Foo::foo()'
> 0

This can be reduced to

package Foo;

my $x = 1;

sub foo {
#$x;
my $y = eval '$x';
printf "from %s: %s\n",
scalar caller, defined $y ? $y : '<undef>';
}

foo;

1;

which gives

~% perl -MFoo -eFoo::foo
from Foo: 1
from main: <undef>

with all perls I have to hand (5.6, 5.8, 5.10, blead). This is a
longstanding bug in eval STRING: it won't capture variables from an
outer lexical scope unless they are explicitly mentioned in the
immediately surrounding scope. Any mention, such as the line commented
out, is sufficient.

What I don't understand is 1. why it works when called from the same
file and 2. I though this had been fixed in 5.10. I guess not...

> Also, is there a better solution to this problem than including
> silly "voodoo code" like the first line in Foo::foo?

Fix perl's eval-handling to work properly? :)

Ben


Posted by Ben Morrow on April 18, 2008, 3:08 pm
Please log in for more thread options

Quoth xhoster@gmail.com:
> >
> > What I don't understand is 1. why it works when called from the same
> > file
>
> When it is called in the same file, the variable is still "in scope" in its
> own right because the file scope has not yet ended. Once the file
> scope has ended, the variable contents are destroyed unless something else
> (like a subroutine stuffed into the symbol table) keeps it alive.

Yup. Thank you: I was confusing locating an entry in the lexical pad
with refcounting of the contents of that entry.

Ben


Similar ThreadsPosted
weird failure with Net::FTP January 1, 2005, 11:05 am
Weird Error message February 15, 2005, 8:59 pm
Weird Module Interactions November 21, 2005, 1:20 pm
Weird socket happenings December 27, 2005, 7:44 am
Weird regexp problem May 4, 2006, 7:53 am
weird perl script January 25, 2007, 8:17 am
Weird character issue March 30, 2007, 1:14 pm
weird behavior with open and pipe June 30, 2005, 4:03 pm
Regular Expression Help - Weird Results December 6, 2005, 5:20 pm
Weird error after a configuration change April 27, 2007, 3:33 pm

Our other projects:

Art Dolls, Fairies and Mermaids - Sunnyfaces.net

Roy's Linux, Programming and Search Engines messages

1-Script XML SitemapXML Sitemap