THIS IS VERY VERY DRAFTY (so lots of bugs flew in)
Package-like things (they are namespaces)
[todo - rationalize when to say "namespace" vs "package"]
Kinds of packages:
Structure Adds
-------------------------------------------------------------
Package namespace, traits, autoload
+- Module export/import, version
+- Role methods, attributes, inheritance, parameterized
+- Class methods, attributes, composition, instantiation
+- Enum weird methods
Name and duration:
Syntax Name Name visibility Duration
--------------------------------------------------------------------------
package P top-level global until exit or deletion
my package P top-level lexical dynamic?
our package P relative to same as same as current package (?)
package anonymous n/a dynamic
Scope of declaration
... package P; ... # to end of enclosing scope
... package P {...} # block scope
... package {...} # block scope
Same for modules, classes, roles?, enums?, subtypes?
But grammars and rules have a separate system.
Names
Names are hierarchical, like filesystem path names.
They start with :: . The separator is also :: . Just like / in unix.
Strings can be interpolated into names by ($expr) , but must begin and end
at separator boundaries.
Special namespaces
::* global (root)
::MY current lexical
::CALLER a view of the caller's namespace
::*::Main the user default
A name N can be used:
N by itself
%N:: as a hash (symbol table)
$N @N %N &N to name variables
The beginning of a name can be abbreviated, to make short names even
simpler.
Example Shorter Rule
---------------------------------------------------------------------------
%::A %A Starting :: can be dropped if not at the word beginning
::*::A ::*A Root doesn't need a separator
::A A Declared name doesn't need the starting ::
::*A *A Root's starting :: can be dropped where there is no
confusion with unary * (such as declarations).
There are a bunch of examples below.
A single hierarchy is shared by modules, classes, roles, enums, and
subtypes. [yes?]
Grammars and rules use the same separator, but otherwise have a
separate system.
Relative package names are searched for
- from inner lexical scopes to outer, then
- from inner packages to outer, then
- in the global namespace.
[this deserves elaboration]
Autoloading
The presense of names in a namespace can be faked. Or implemented
lazily. If a user inquires about (defined(...)), or tries to use a
variable, which is not in the symbol table, hooks are called.
For SCALAR ARRAY HASH SUB METH ...:
AUTO... predicates test the existance of a variable,
returning undef or _any_ ref of the right type.
AUTO...DEF accessors actually fetch the requested variable.
[Can a package or role AUTOMETH?]
Binding
:= ::= # todo
Examples
::A namespace name, relative
::A::B
::A::B::C
::* namespace name, absolute (::* is root)
::*A (root doesn't need a separator)
::*A::B
::*A::B::C
%A:: namespace as hash; relative name
%A::B::
%*:: namespace as hash; absolute name
%*A::
%*A::B::
%x variable name, lexical ("%" could be any sigil $@%& etc)
%A::x variable name, relative ("%" could be any sigil $@%& etc)
%A::B::x ("%" could be any sigil $@%& etc)
%*x variable name, absolute ("%" could be any sigil $@%& etc)
%*A::x ("%" could be any sigil $@%& etc)
%*A::B::x ("%" could be any sigil $@%& etc)
Abbreviations used
::*::A ::*A # root doesn't need a separator
%::A:: %A:: # leading :: is only needed if it starts the word
# ::A::B could NOT be abbreviated A::B (??)
%::A::x %A::x
%::*::x %*x # using both
%::*::A:: %*A::
Notable namespaces
::MY # current lexical namespace
%MY:: # \__ as hash
%MY::x # \__ a variable in ("%" could be any sigil $@%& etc)
::*Main # default user namespace
%*Main:: # \__ as hash
%*Main::x # \__ a variable in ("%" could be any sigil $@%& etc)
Runtime interpolation:
::("A") ::A
::("A::B") ::A::B
::("A::")B # ILLEGAL
::("A")::B ::A::B
::A::("B") ::A::B
::A::("B")::C ::A::B::C
::("*") ::*
::("*A") ::*A
::("*::A") ::*A
%::("A"):: %A::
%::("A::") # ILLEGAL
%::("A::x") %A::x ("%" could be any sigil $@%& etc)
::($expr) a namespace name
::($e1)::($e2) a namespace name
%::($expr):: a namespace used as a hash
%::($expr) a variable name ("%" could be any sigil $@%& etc)
Using a namespace hash (a symbol table):
%P:: # namespace P as a hash (a symbol table)
%P::<$s> # lookup $s
%P::<@a> # lookup @a
%P::{'$s'} # lookup $s again, just quoted differently.
%P::{$sym} # lookup some symbol specified at runtime