develooper Front page | perl.perl6.language | Postings from May 2008

Re: nested 'our' subs - senseless?

Thread Previous | Thread Next
From:
David Green
Date:
May 6, 2008 11:33
Subject:
Re: nested 'our' subs - senseless?
On 2008-May-6, at 6:07 am, TSa wrote:
> Just to ensure that I get the our behavior right, consider
>
>    sub foo
>    {
>       our $inner = 3;
>    }
>    sub bar
>    {
>       our $inner = 4; # redeclaration error?
>    }
>    say $inner;
>
> Does this print 3 even when foo was never called?

No, it throws an error about "$inner" not being declared properly --  
just as in P5 you'd get 'Variable "$inner" is not imported. Global  
symbol "$inner" requires explicit package name'.

There's no redeclaration error in bar() because it's declaring the  
name for the first time (in bar's scope, that is), and then  
(re)assigning a value to $inner, which is fine.  If foo said "our Int  
$inner" and then bar said "our Str $inner", that should be an error  
though.


     sub foo
     {
         our $inner = 3;
     }
     sub bar
     {
         our $inner = 4;  # fine, assigns or re-assigns $inner
     }

     say $inner;          # error, name "$inner" not recognised here

     our $inner;          # now the name is available in this scope
     say $inner;          # OK, $inner is undef

     foo; say $inner;     # prints 3

     bar; say $inner;     # prints 4


> IOW, is the assignment in foo a real one that only happens when foo  
> is invoked or is it a pseudo-assignment that initializes the  
> variables as if the whole statement where outside of foo?

The assignment happens only when foo() is invoked.  However, the  
variable $*Main::inner is declared at compile-time.  Similarly, an  
"our sub inner" inside foo() would declare the name, but you couldn't  
call inner() until after running foo() --or bar()-- since you can't  
call an undefined sub.


> The consequence of a sub not doing Package is that there are
> no separate foo::inner and bar::inner classes as in
>
>    class foo
>    {
>        our class inner { has $.x = 3 }
>    }
>    class bar
>    {
>        our class inner { has $.x = 4 }
>    }
>    say inner.new.x; # error: no inner in scope
>
> My personal idea is to unify class and sub by allowing sub to do  
> Package.

I don't understand what a "sub doing Package" is supposed to do.  I  
think you get the same thing from that last example whether foo and  
bar are classes or whether they're subs: either way, bar will raise a  
redefinition error, and "say inner.new.x" will throw a "no 'inner' in  
scope" error.


-David



Thread Previous | Thread Next


Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About