Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation

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 surveying the Monastery: (7)
As of 2017-02-24 22:48 GMT
Find Nodes?
    Voting Booth?
    Before electricity was invented, what was the Electric Eel called?

    Results (364 votes). Check out past polls.