Data hiding
- Posted by Matt Lewis <matthewwalkerlewis at ?m?il.com> Oct 16, 2007
- 620 views
I've been thinking about this topic, and I've identified several issues. I can think of two basic methods to restrict visibility: 1. From within the declaring file 2. From outside the declaring file We have a decent mechanism for restricting visibility based on #1, but lose all control once it gets out. The solutions proposed by Pete and CChris are what might be called hybrid methods. For reference, here are the links to these two approaches: http://oedoc.free.fr/Packages.htm http://palacebuilders.pwp.blueyonder.co.uk/dhc.htm (Pete, your links to the various replies are broken--missing the '#'.) CChris' approach provides the package+identifier and restrict lists, which are mostly #2 based, but the addition of the new internal and exported keywords earn them a hybrid status. Pete requires a #1 approach, but also relies a bit on #2 to enable visibility. Both used explicitly named scoping mechanisms, which throw up red flags in my mind. They might not be a problem, but I'd be interested to hear from the respective authors what happens when the same name is used in two different places, for different purposes. IOW, does it cause an error? Are the two scopes treated as one? Etc... One concern I have about CChris' approach is that once a symbol is exported from a package, there's no way to hide it from downstream users: "An exported symbol is visible from any part of the system." Here's a scenario where I think you'd want to be able to do this. You have a library that relies on another library for some backend work. But you don't want to expose any symbols from that library, which might have already restricted visibility on some symbols, and therefore have exported some of its symbols. Is there a way to do this, CChris? Maybe the restrict keyword does this, but I'm not sure from the documentation. Pete's system seems to be a lot simpler, but doesn't offer the ability to do this either. Now for an overview on how I'd implement import. For the file that issued an import statement, it would be identical to an include. For files that either include or import that file, no imported symbols would be visible, unless included or imported via another route. This approach doesn't rely on any explicit grouping, or knowing which files "belong" to which group. It just defines the way global symbols propagate, allowing the coder to stop the propagation at any point. It's an admittedly minimalist approach, but that's part of what I like about it (and why I think it's particularly suited for euphoria). ex:
-- myapp.ex include libMatt.e import libPete.e global object PETE -- PETE is visible from libMatt.e -- PETE is not visible from myapp.ex --myapp.ex include libMatt.e import libPete.e global object PETE include libPete.e -- PETE is visible from libMatt.e -- PETE is visible from myapp.ex
Here is my [quick] evaluation of the current proposals: CChris: Pro - gives "transitional" capability to hide info from outside file - high granularity of symbols to hide/expose Con - seems overly complicated (5 new keywords, total 7 different uses) - can't "firewall" symbols (unless that's what restrict does) ??? - how will package naming conflicts be dealt with Pete: Pro - simple implementation (2 keywords [assuming shared_scope = 1 word]) - high granularity of symbols to hide/expose Con - requires editing source files - can't "firewall" symbols up the include chain ??? - how will shared_scope naming conflicts be dealt with? Matt (import approach): Pro - very simple implementation (1 new keyword) - can hide/firewall symbols at any point in include chain Con - granularity of other proposals achievable, but requires changing file layout (i.e., moving variables to files that are imported) I'd be interested in hearing from people other than us 3. :) Matt