Some sort of scoping problem

Discussion in 'Perl Misc' started by Mintcake, May 6, 2008.

  1. Mintcake

    Mintcake Guest

    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->{xyzzy}, ' ', scalar @{$self->{xyzzy}};
    }

    sub ini {
    my ($self, $field) = @_;
    eval "\$self->{$field} = \\\@$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.
     
    Mintcake, May 6, 2008
    #1
    1. Advertising

  2. Mintcake

    Ben Bullock Guest

    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.
     
    Ben Bullock, May 6, 2008
    #2
    1. Advertising

  3. Mintcake

    Guest

    Mintcake <> wrote:
    > 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->{xyzzy}, ' ', scalar @{$self->{xyzzy}};
    > }
    >
    > sub ini {
    > my ($self, $field) = @_;
    > eval "\$self->{$field} = \\\@$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.
     
    , May 6, 2008
    #3
  4. Mintcake

    Ronny Guest

    On 6 Mai, 03:04, Mintcake <> wrote:
    > package Foo;
    >
    > my @xyzzy = (1,2,3);
    >
    > sub new {
    > my $self = bless {}, shift;
    > $self->ini('xyzzy');
    > print \@xyzzy, ' ', scalar @xyzzy;
    > print $self->{xyzzy}, ' ', scalar @{$self->{xyzzy}};
    >
    > }
    >
    > sub ini {
    > my ($self, $field) = @_;
    > eval "\$self->{$field} = \\\@$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} = \\\@$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} = \\\@$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
     
    Ronny, May 7, 2008
    #4
  5. Mintcake

    Dave Weaver Guest

    On Mon, 5 May 2008 18:04:09 -0700 (PDT), Mintcake <> wrote:
    > 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->{xyzzy}, ' ', scalar @{$self->{xyzzy}};
    > }
    >
    > sub ini {
    > my ($self, $field) = @_;
    > eval "\$self->{$field} = \\\@$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->{$field} = $fields->{field};
    }
     
    Dave Weaver, May 9, 2008
    #5
  6. Mintcake

    Dave Weaver Guest

    On 09 May 2008 09:06:22 GMT, Dave Weaver <> wrote:
    > sub ini {
    > my ( $self, $field ) = @_;
    > $self->{$field} = $fields->{field};


    Oops! That should, of course, be:
    $self->{$field} = $fields{$field};
     
    Dave Weaver, May 9, 2008
    #6
  7. Mintcake

    Ben Bullock Guest

    On Fri, 09 May 2008 09:06:22 +0000, Dave Weaver wrote:

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


    It has nothing to do with "use warnings;".

    > Here are a couple of suggestions to solve your problem:


    I'm sorry but you have missed the point of the question and the answers
    given.
     
    Ben Bullock, May 9, 2008
    #7
  8. Mintcake

    Dave Weaver Guest

    Ben Bullock <> wrote:
    >
    > > Here are a couple of suggestions to solve your problem:

    >
    > I'm sorry but you have missed the point of the question and the answers
    > given.
    >


    I admit that may be the case, but I am none the wiser for your reply.
     
    Dave Weaver, May 9, 2008
    #8
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. =?Utf-8?B?RGF2ZQ==?=

    Stupid Scoping Problem?

    =?Utf-8?B?RGF2ZQ==?=, Jan 30, 2004, in forum: ASP .Net
    Replies:
    3
    Views:
    350
    =?Utf-8?B?RGF2ZQ==?=
    Jan 30, 2004
  2. Daniel Lemos Itaborai

    Dynamic Scoping problem

    Daniel Lemos Itaborai, Aug 23, 2004, in forum: Python
    Replies:
    2
    Views:
    421
    Ville Vainio
    Aug 23, 2004
  3. Adrian Dragulescu
    Replies:
    1
    Views:
    394
    Diez B. Roggisch
    May 21, 2009
  4. Navin
    Replies:
    1
    Views:
    746
    Ken Schaefer
    Sep 9, 2003
  5. ZMAN

    scoping problem

    ZMAN, May 21, 2004, in forum: Perl Misc
    Replies:
    4
    Views:
    89
    Eric Schwartz
    May 26, 2004
Loading...

Share This Page