On 12/12/13 11:08 AM, Mike Small wrote:
I was trying to understand better Tim's example where he tried to use a sub 
that wasn't exported from its module by qualifying it with the module name.
Right. It's easy to reproduce in the REP (and maybe I should have included a slide to that effect).

$ perl6
> module A { sub fn { } }
(A)
> A::fn()
Could not find symbol '&fn'

Or an even more poignant example, using Rakudo's built-in Test module:

$ perl6
> module A { use Test; diag("Foo!") }
# Foo!
> module B { use Test <diag>; diag("Foo!") }
Error while importing from 'Test': no EXPORT sub, but you provided positional argument in the 'use' statement
> module C { need Test; Test::diag("Foo!") }
Could not find symbol '&diag'

Module A works fine, because I import everything from Test into its namespace.

Module B croaks during BEGIN; and there seems to be some confusion as to why.

Module C croaks at runtime, and according to Synposis 11, it indeed ought to; but there also seems to be some confusion as to the whys and hows of that scenario as well. This might be a situation where the documentation has not yet caught up with the implementation, or vice-versa, or where best practices have not caught up with either.

"Another difference is that subroutines default to my scope rather than our scope. 
However, subroutine dispatch searches lexical scopes outward, and subroutines are also 
allowed to be postdeclared after their use, so you won't notice this much. A subroutine 
that is not declared yet may be called using parentheses around the arguments, in the 
absence of parentheses, the subroutine call is assumed to take multiple arguments in the 
form of a list operator."
-- http://perlcabal.org/syn/S06.html#Globally_scoped_subroutines

In other words, the following code will work:

f();
my sub f {
    g();
    my sub g {
        say "It works!"
    }
}

Usually, you can't access "my" variables until after their declared. And the "my" on these sub 
declarations are superfluous. (So "my sub f" is equivalent to just "sub f.") But subs are allowed 
to be used before they're declared, and subroutine dispatch will search, starting with the innermost lexical scope, and 
proceeding outward through broader and broader scopes, until it gets to the global-most scope.

...an example where defaults just changed and on purpose? i.e. did Perl 6 
purposely reconsider the Perl 5 custom...
I'm assuming that's what happened here. In P5, all package symbols are public. And if you want something to be private, you need to establish a convention to mark it thus. So that's why we put underscore in front of "private" methods of a class. Or you have to use workarounds like inside-out objects, in order to make your implementation opaque.

P6 recognizes a much stronger concept of opaque types. P6 classes have a private implementation and a publicly accessible API. And as developer, you can enforce this distinction. So a "my" sub is by definition part of the private implementation. That's why it feels to me really silly to mark a "my" sub "is export." I'm not saying that the language should prohibit you from doing so— I think that every programmer has a First Amendment right to act like an idiot, because all geniuses first sounded like idiots. But I'm saying that if subs are by default in "my" scope, then my best practice (again, speaking as a developer) should be to declare exportable subs "our."

-TimK

_______________________________________________
Boston-pm mailing list
[email protected]
http://mail.pm.org/mailman/listinfo/boston-pm

Reply via email to