Beefy Boxes and Bandwidth Generously Provided by pair Networks
Problems? Is your data what you think it is?

Question of scope

by Popcorn Dave (Abbot)
on May 06, 2002 at 19:04 UTC ( #164411=perlquestion: print w/replies, xml ) Need Help??
Popcorn Dave has asked for the wisdom of the Perl Monks concerning the following question:

Fellow monks,

I've got the following bit of code that is losing the contents of a global array upon it's exit.

$canvas->Tk::bind('<Button-1>' => [sub { my ($e,$x,$y) = (@_); shift; push (@coords, $x); push (@coords, $y); }, Ev('x'), Ev('y')]);

Now it's my ascertion, that since @coords was previously defined as a global, I should be able to keep the information in it without having to return it, correct? The values in @coords should not be clobbered as they're not declared as locals in this subroutine.

Is this one of those I'm gonna kick myself when I get an answer things that I'm just obtusely overlooking?


Replies are listed 'Best First'.
Re: Question of scope
by rinceWind (Monsignor) on May 06, 2002 at 20:26 UTC
    I cannot answer your question regarding @coords without knowing precisely how @coords was previously defined as a global.

    Within the use strict; confines, there are two methods which, on the surface appear equivalent, are in fact different.

    use vars qw(@coords); our @coords;
    I may be able to give a more definite answer if you post more of the code. See also 'our' is not 'my' and Our, use vars, and magic, oh my!

    Also, another minor point - the shift; serves no purpose as you have already obtained the arguments from @_.

      My @coords was defined as: my @coords=(); towards the top of my program.

      All I'm attempting to do is push the coordinates on to a global array, but they're being lost after that routine.

      I've done print statements to verfy they did get pushed in to the array, and that $x and $y actually exist ( that I'm not pushing undefined ) so I'm stymied to say the least.

      Hopefully that will clarify my situation so that you may be able to shed a little light on this for me.


        if your using use strict (you are .. right?) then it would die if he was pushin onto an undeclared @..
Re: Question of scope
by gav^ (Curate) on May 07, 2002 at 00:53 UTC
    You might find one of these forms simpler (and shorter): sub { push @coords, @_[1,2] }
    sub { my (undef, $x, $y) = @_; push @coords, $x, $y; }


Re: Question of scope
by perrin (Chancellor) on May 06, 2002 at 19:33 UTC
    Do you have strict and warnings on? You might just have a typo in the name of the array.
Re: Question of scope
by stephen (Priest) on May 07, 2002 at 03:43 UTC

    Be careful, for here you are using a closure. Remember, when an anonymous subroutine is defined, it uses whatever lexical variables are in scope at the time it was created. So:

    use strict; my @foo = (); my $pushit = sub { push @foo, @_; }; $pushit->('apple'); $pushit->('orange'); print @foo, "\n";
    will print "appleorange", but
    use strict; my @foo = (); my $pushit = sub { push @foo, @_; }; my @foo = (); $pushit->('apple'); $pushit->('orange'); print @foo, "\n";
    will print nothing, since the @foo that is printed is not the same @foo that is being populated. (That'll also happen if you're not using strict, and somehow only declare @foo after the closure is created.) If this is the case, it'll show up if you turn warnings on... if the new @foo (or @coords in your case) is in the same scope as the other one. If @coords is file-scoped, you might well want to use 'our' instead of 'my'... that way you're guaranteed a single variable.


Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://164411]
Approved by silent11
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others avoiding work at the Monastery: (12)
As of 2016-12-09 21:25 GMT
Find Nodes?
    Voting Booth?
    On a regular basis, I'm most likely to spy upon:

    Results (157 votes). Check out past polls.