Beefy Boxes and Bandwidth Generously Provided by pair Networks
Don't ask to ask, just ask
 
PerlMonks  

'Our' limits?

by cedar (Initiate)
on Jul 14, 2006 at 16:24 UTC ( [id://561255]=perlquestion: print w/replies, xml ) Need Help??

cedar has asked for the wisdom of the Perl Monks concerning the following question:

I'm trying to get a grip on what 'our' does, and got a bit of a shock. The manual says "An our declaration declares a global variable that will be visible across its entire lexical scope, even across package boundaries." but I don't think that's what I see.

So I'm playing around and come up with this. I'm expecting to be able to change the $d arrayref in the top subroutine and see the changes in the package that called it. But I don't, insted I see the arrayref changing back as we go back up the stack. That would be cool if it were a "my", but it's not. Can anyone shed some light?

Thanks

package Foo; sub top { my($fn) = @_; our($d) = ["a", "b"]; printf "Top before %s [%s]\n", $d, join(",", @$d); $fn->($d); printf "Top After %s [%s]\n", $d, join(",", @$d); } package Bar; Foo::top(sub { our($d) = @_; printf " Before %s [%s]\n", $d, join(",", @$d); $d = []; printf " After %s [%s]\n", $d, join(",", @$d); });
C:\Scripts>perl scope.pl Top before ARRAY(0x183f218) [a,b] Before ARRAY(0x183f218) [a,b] After ARRAY(0x183f248) [] Top After ARRAY(0x183f218) [a,b]
C:\Scripts>perl -v This is perl, v5.6.1 built for MSWin32-x86-multi-thread (with 1 registered patch, see perl -V for more detail) Copyright 1987-2001, Larry Wall Binary build 635 provided by ActiveState Corp. http://www.ActiveState. +com Built 15:34:21 Feb 4 2003

Replies are listed 'Best First'.
Re: 'Our' limits?
by Ieronim (Friar) on Jul 14, 2006 at 16:43 UTC

    The following code will work as you expected:

    package Foo; our $d; #the only line added sub top { my($fn) = @_; our($d) = ["a", "b"]; printf "Top before %s [%s]\n", $d, join(",", @$d); $fn->($d); printf "Top After %s [%s]\n", $d, join(",", @$d); } package Bar; Foo::top(sub { #our($d) = @_; #removed! printf " Before %s [%s]\n", $d, join(",", @$d); $d = []; printf " After %s [%s]\n", $d, join(",", @$d); });

    The lexical scope is bordered by the innermost curly brackets or the boundaries of the file :) You must declare your variable in the lexical scope which includes all scopes where you want to see this variable. This is why i added the line our $d;

    If you define the variable $d with our in the different packege, it is supposed to be a DIFFERENT $d variable. This is why i commented out the line in the second package.

    See our() manpage for more details.

    UPD: added execution result:

    Top before ARRAY(0x1a60b7c) [a,b] Before ARRAY(0x1a60b7c) [a,b] After ARRAY(0x1a60bb8) [] Top After ARRAY(0x1a60bb8) []
Re: 'Our' limits?
by polettix (Vicar) on Jul 14, 2006 at 16:51 UTC
    When you use our you're accessing package variables without having to explicitly name them. That is, when you write:
    package Foo; our $var; $var = 10;
    you're actually setting the $Foo::var. The our declaration is lexically scoped. The following example could be of some use:
    package Foo; our $d; # FIRST $d = __PACKAGE__; package Bar; sub bar { print 'in ', __PACKAGE__, '::bar $d is equal to ', "$d\n"; return; } our $d = __PACKAGE__; # SECOND sub baz { print 'in ', __PACKAGE__, '::baz $d is equal to ', "$d\n"; return; } package main; Bar::bar(); Bar::baz(); __END__ poletti@PolettiX:~/sviluppo/perl$ perl our.pl in Bar::bar $d is equal to Foo in Bar::baz $d is equal to Bar
    Bar::bar() "sees" the FIRST declaration, while
    Bar::baz()> is in the scope of the second. <p>In your example, you actually access <c>$Bar::d
    in the anonymous sub you pass to Foo::top(): the fact that it has the same value of $Foo::d depends on the assignment:
    our($d) = @_;
    which makes $Bar::d equal to $Foo::d - ach! :)

    Flavio
    perl -ple'$_=reverse' <<<ti.xittelop@oivalf

    Don't fool yourself.
Re: 'Our' limits?
by ikegami (Patriarch) on Jul 14, 2006 at 17:08 UTC
    Compare
    $Foo::d = 'foo'; $Bar::d = 'bar'; package Foo; { our $d; # Creates an alias to $Foo::d print("$d\n"); # Prints 'foo' } # End of alias's scope. package Bar; { our $d; # Creates an alias to $Bar::d print("$d\n"); # Prints 'bar' } # End of alias's scope.
    with
    $Foo::d = 'foo'; $Bar::d = 'bar'; package Foo; our $d; # Creates an alias to $Foo::d print("$d\n"); # Prints 'foo' package Bar; # $d is still aliases to $Foo::d print("$d\n"); # Prints 'foo' # End of alias's scope.
Re: 'Our' limits?
by jmcada (Acolyte) on Jul 14, 2006 at 16:44 UTC
    I think you'll still have to reference the package that the 'our' variable is declared in. The doc is just saying that you can see the 'our' variable in other packages. It doesn't state how you have to refer to it. (See $Foo::d below)
    package Foo; sub top { my($fn) = @_; our($d) = ["a", "b"]; printf "Top before %s [%s]\n", $d, join(",", @$d); $fn->($d); printf "Top After %s [%s]\n", $d, join(",", @$d); } package Bar; Foo::top(sub { our($d) = @_; printf " Before %s [%s]\n", $d, join(",", @$d); $Foo::d = []; printf " After %s [%s]\n", $d, join(",", @$d); }); --(0)> perl test.pl Top before ARRAY(0x8144234) [a,b] Before ARRAY(0x8144234) [a,b] After ARRAY(0x8144234) [a,b] Top After ARRAY(0x81442dc) []

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://561255]
Approved by davido
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others surveying the Monastery: (4)
As of 2024-03-28 13:24 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found