On 2008-May-3, at 5:04 pm, John M. Dlugosz wrote:
What does this mean?

our sub outer ()
 {
  ...
  our sub inner () { ... }
 }


inner;  # defined?

I think this should be illegal. Nested named subs makes sense for 'my', with the rules of visibility matching the ability to clone the closure. But putting the nested sub into package scope is nonsense. It's really a different clone every time outer is called, and doesn't make sense to call unless outer is already pending.

I don't know why it would be any more illegal than "sub foo { our $var... }". The inner sub would be in the package's scope, but the name "inner()" would be available only in outer's scope. So that use of "inner" in the last line would be an error.

If inner doesn't actually need anything from outer's block scope, then there is no reason to declare it nested. If you have something specific in mind, like creating specific clones on the fly, then the code in outer can explicitly post the version it creates to the package scope and make it clear exactly when it's being created.

E.g.

our sub outer (::T $x)
 {
  # explicitly create a new multi with every specialization
  state %didit;
  unless ++ %didit{ $x.HOW } {
     my multi sub inner (T $x)  {  ... }
     Package::<&inner> = &inner;
    }
 }


Well, for one thing, "Package::inner" in this example is set at run- time, while "our sub inner" in your first example is declared at compile-time, right?


-David

Reply via email to