| Played with this a while, and the metaprogramming supporting this is fun :) Once again proving that you can dream up a wild idea, and Ruby will support you in achieving your dreams. Looking at Syntropy::ModuleLoader, "modules" get to pretend they are in some main-like flat scope, but actually are executing in the instance scope of a Syntropy::ModuleContext. A consequence of this is that it is difficult to imagine these modules (and their exports) interoperating with plain Ruby code that doesn't have access to the `#import` (or needs to eschew it for some reason). This seems fine in the context of a "closed loop" framework: expect to only ever consume a Syntropy module's `#export` in another Syntropy module, and only using Syntropy's `#import`. That seems like the happy path, but it is a tradeoff: you really need to buy into this "module" system all the way. There might be an escape hatch, if plain Ruby code (i.e. not another Syntropy module) has access to the instance of ModuleLoader. With that, you can grab an export value via `#load`, which seems fine as long as the thing you need to `#load` isn't a module or class. Specific to exporting a module or class, it feels natural for me to want to assign it to a capitalized constant when importing. I expected this not to work, as Ruby will reject instance scope `SomeModule = 'some_value'` if I write it as source code (SyntaxError, dynamic constant assignment). However, when I `#instance_eval("SomeModule = 'some_value'")` it as a string (as Syntropy::ModuleContext does), Ruby accepts it? I'm surprised! The downside is that these end up as some kind of shadow constants, relative to each instance of Syntropy::ModuleContext? That is, they can only ever be accessed by name inside of a string passed to `#instance_eval`. I need to think longer about what the implications are. It's certainly interesting. |