Click here to get back home

Some sort of scoping problem

 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
Some sort of scoping problem Mintcake 05-05-2008
Posted by Mintcake on May 5, 2008, 9:04 pm
Please log in for more thread options
This is *not* a trivial problem. If you know Perl well, please take a
bit of time to look at this.

I have the following code in a file Foo.pm

package Foo;

my @xyzzy = (1,2,3);

sub new {
my $self = bless {}, shift;
$self->ini('xyzzy');
print \@xyzzy, ' ', scalar @xyzzy;
print $self->, ' ', scalar @};
}

sub ini {
my ($self, $field) = @_;
eval "$self-> = \@$field";
}

1;

__END__

My main program is simply this:

#!/usr/local/bin/perl -l

use Foo;

new Foo;

__END__

The two lines of output are:

ARRAY(0x90edda4) 3
ARRAY(0x90edfcc) 0

It seems that there are two separate arrays, one of which is empty. I
was expecting the blessed hash to simply contain a reference to the
@xyzzy lexical declared with module scope.

If I include the package Foo code in the main program instead of a
separate module I get the expected result.
If I lose the ini() subroutime and put the eval directly in the
constructor I get the expected result.
If I don't declare @xyxxy with my or use our instead I get the
expected result.
If I add a use strict in Foo.pm and change $self->ini('xyzzy') to
$self->ini('plugh') I get the expeted error:

Can't use an undefined value as an ARRAY reference at /home/tony/lib/
Foo.pm line 11.

I'm using perl v5.8.8 and I get the some on i686-linux and Activstate
on Windoze.


Posted by Ben Bullock on May 5, 2008, 10:08 pm
Please log in for more thread options
On Mon, 05 May 2008 18:04:09 -0700, Mintcake wrote:

> This is *not* a trivial problem. If you know Perl well, please take a
> bit of time to look at this.

I don't know Perl that well, but in case this needs confirmation, I had a
look & confirmed the following odd behaviour:

> If I include the package Foo code in the main program instead of a
> separate module I get the expected result. If I lose the ini()
> subroutime and put the eval directly in the constructor I get the
> expected result. If I don't declare @xyxxy with my or use our instead I
> get the expected result.
> If I add a use strict in Foo.pm and change $self->ini('xyzzy') to
> $self->ini('plugh') I get the expeted error:
>
> Can't use an undefined value as an ARRAY reference at /home/tony/lib/
> Foo.pm line 11.
>
> I'm using perl v5.8.8 and I get the some on i686-linux and Activstate
> on Windoze.

Posted by xhoster on May 5, 2008, 11:32 pm
Please log in for more thread options
> This is *not* a trivial problem. If you know Perl well, please take a
> bit of time to look at this.
>
> I have the following code in a file Foo.pm
>
> package Foo;
>
> my @xyzzy = (1,2,3);
>
> sub new {
> my $self = bless {}, shift;
> $self->ini('xyzzy');
> print \@xyzzy, ' ', scalar @xyzzy;
> print $self->, ' ', scalar @};
> }
>
> sub ini {
> my ($self, $field) = @_;
> eval "$self-> = \@$field";
> }

ini never latches onto @xyzzy, because @xyzzy is not mentioned
in ini at compile time. Very similar to:

http://groups.google.com/group/comp.lang.perl.misc/browse_frm/thread/eaf48dac9f298e29

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 Ronny on May 7, 2008, 7:45 am
Please log in for more thread options
> package Foo;
>
> my @xyzzy = (1,2,3);
>
> sub new {
> my $self = bless {}, shift;
> $self->ini('xyzzy');
> print \@xyzzy, ' ', scalar @xyzzy;
> print $self->, ' ', scalar @};
>
> }
>
> sub ini {
> my ($self, $field) = @_;
> eval "$self-> = \@$field";
>
> }
>
> 1;

> My main program is simply this:
>
> #!/usr/local/bin/perl -l
> use Foo;
> new Foo;
>
> The two lines of output are:
>
> ARRAY(0x90edda4) 3
> ARRAY(0x90edfcc) 0

First I run your program with

use warnings;

enabled, and here I got the message:

Variable "@xyzzy" is not available at (eval 1) line 2.

Which means @xyzzy can't be seen from within eval. Things are
different if I "use" the variable inside the routine, so that
the compiler can see it - for example by writing

sub ini {
my ($self, $field) = @_;
print "ini: ", \@xyzzy,"\n";
eval "$self-> = \@$field";
}

You can also put the usage after the eval; it is only important
that the variable is used somewhere in the function:

sub ini {
my ($self, $field) = @_;
eval "$self-> = \@$field";
print "ini: ", \@xyzzy,"\n";
}

In both cases, Foo::new will print the same value for the hash.

We learn two things from this:

(1) Perl can be pretty bizarre in its details.
(2) If you do not "use warnings", you are automatically in a state of
sin.

Ronald

Posted by Dave Weaver on May 9, 2008, 5:06 am
Please log in for more thread options
> This is *not* a trivial problem. If you know Perl well, please take a
> bit of time to look at this.
>
> I have the following code in a file Foo.pm
>
> package Foo;
>
> my @xyzzy = (1,2,3);
>
> sub new {
> my $self = bless {}, shift;
> $self->ini('xyzzy');
> print \@xyzzy, ' ', scalar @xyzzy;
> print $self->, ' ', scalar @};
> }
>
> sub ini {
> my ($self, $field) = @_;
> eval "$self-> = \@$field";
> }

Others have explained the problem and pointed out why you
should "use warnings;".

Here are a couple of suggestions to solve your problem:

1. Use a package variable instead of a lexical:
        our @xyzzy = ( 1, 2, 3 );

2. Use a lookup table:
my %fields = (
         xyzzy => [ 1, 2, 3 ],
        );

        sub ini {
         my ( $self, $field ) = @_;
         $self-> = $fields->;
        }


Similar ThreadsPosted
Stumped by eval and scoping problem March 17, 2005, 2:55 pm
Odd sort() problem September 29, 2004, 10:59 am
sort problem March 7, 2006, 4:12 pm
can Perl Sort do this, unix sort breaks on it (muliple spaces as demiliter) February 2, 2005, 6:08 pm
Re: A Sort Optimization Technique: decorate-sort-dedecorate August 30, 2006, 4:32 pm
capture scoping August 19, 2004, 1:17 pm
scoping question August 5, 2005, 12:08 pm
submatch scoping in while September 23, 2006, 4:14 pm
Question about scoping February 27, 2007, 3:33 am
Lexical scoping question. February 10, 2005, 3:56 pm

Our other projects:

Art Dolls, Fairies and Mermaids - Sunnyfaces.net

Roy's Linux, Programming and Search Engines messages

1-Script XML SitemapXML Sitemap