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


Reply via email to