<import: PoolDict> for namespaces
| Project: | GNU Smalltalk |
| Component: | VM |
| Category: | feature |
| Priority: | normal |
| Assigned: | Unassigned |
| Status: | fixed |
The two commits at the tip of my master as I write this:
a9a46e1... add namespace pragmas, like class pragmas, for new syntax 9d92f75... unexported importation of pools into namespaces for their classes' methods
Let you do things like this:
Eval [PackageLoader fileInPackages: #('Parser' 'NetClients')]
Namespace current: Test [
<import: STInST>
Object subclass: MyTest [
test [^RBParser]
]
<import: NetClients>
MyTest extend [
test2 [^URIResolver]
]
]
More or less as documented in sym.c. Tests are also included, although namespace pragmas are not tested for Compiler (though the above test file works).
Accessing pool vars with #at: and friends on the namespace is explicitly unsupported, as that would be tantamount to always reexporting imports, which I think would be most unfriendly. This may cause issues with Undeclared bindings, that I didn't test for.
Updates
The implementation is okay, and obviously you cannot reexport via #at: as that would require computing a linearization of the namespaces on every #at:. In practice, that would mean that A.B would not refer to a B defined in a shared pool of A.
However I am not sure that it's good to not make the import work for classes defined in a subspace, because that means that I cannot just take a class defined in A and wrap it into Namespace current: B [ ]. Can you convince me otherwise?
Would it be difficult to implement? I imagine you'd use something like the complete TwistedPools with the superspace replacing the environment (which simplifies things in turn).
The implementation is okay, and obviously you cannot reexport via #at: as that would require computing a linearization of the namespaces on every #at:. In practice, that would mean that A.Var would not refer to a Var defined in a shared pool of A.
However I am not sure that it's good to not make the import work for classes defined in a subspace, because that means that I cannot just take a class defined in A and wrap it into Namespace current: B [ ] to move it into A.B. Can you convince me otherwise?
Would it be difficult to implement? I imagine you'd use something like the complete TwistedPools with the superspace replacing the environment (which simplifies things in turn).
| Attachment: | import-pooldict-ns.patch (21.08 KB) |
> In practice, that would mean that A.Var would not refer to a Var defined in a shared pool of A.
I consider this to be a feature, not just an optimization. My template is the import feature in Common Lisp -- because GST namespaces don't distinguish between external and internal symbols, I thought it best to apply the most likely strategy globally for pools.
> However I am not sure that it's good to not make the import work for classes defined in a subspace, because that means that I cannot just take a class defined in A and wrap it into Namespace current: B [ ] to move it into A.B. Can you convince me otherwise?
I am not sure what you mean. The namespace-pool-add happens strictly when a namespace is visited, so all namespaces added by the class-containing-namespace walk will also have their pools added. For example:
"assuming A and B are undefined"
Namespace current: A [
Namespace current: B [
Object subclass: Va [
test [
"resolves to STInST.RBParser in
current implementation"
^RBParser
]
]
]
...where an <import: STInST> appears above the Namespace current: B line.
Also as a result of how namespace-pool-add is tied to namespace-add, superclasses' namespaces' pools are also included. See pools.st:149 and PoolResolutionTests.st:150 for tests of this implication.
| Status: | committed | » fixed |
> > not refer to a Var defined in a shared pool of A.
>
> I consider this to be a feature, not just an optimization.
I agree.
> all namespaces added by the class-containing-namespace
> walk will also have their pools added
Yes, I just tried it on this and it worked:
Namespace current: A [
Object subclass: KlassA [ KlassA class >> pathSep [ ^PathSeparator ] ]
Namespace current: B [
Object subclass: KlassB [ KlassB class >> pathSep [ ^PathSeparator ] ]
]
]
A.KlassA pathSep printNl.
A.KlassA allSharedPoolDictionariesDo: [ :each | each printNl ].
A.B.KlassB pathSep printNl.
A.B.KlassB allSharedPoolDictionariesDo: [ :each | each printNl ]
Should have just tried it before asking you, sorry! :-) Merged to master.
