As I was programming in Squeak today, I typed a class name, including its two-letter prefix. I wondered, could Environments be used to, dynamically, only in transient memory, remove a prefix from a package? It would be nice to enjoy typing and reading the pure, unprefixed class names, but would want to keep the original prefixes when I save a new version of the package..
On Mon, Apr 07, 2014 at 01:40:53PM -0500, Chris Muller wrote:
As I was programming in Squeak today, I typed a class name, including its two-letter prefix. I wondered, could Environments be used to, dynamically, only in transient memory, remove a prefix from a package? It would be nice to enjoy typing and reading the pure, unprefixed class names, but would want to keep the original prefixes when I save a new version of the package..
I am also curious about how to use Environments for this kind of thing. Right now I am experimenting with an alternative implementation of DateAndTime, and I'm using the good old fashioned approach of giving it a different name, in this case LXDateAndTime. Assuming that I get it working, I will want to be able to replace the current DateAndTime with the new one, but keep the original one working until it is no longer needed. Of course, DateAndTime is used for source code time stamps, so there is a period of time when both implementations have to be in the image. It would be nice if I could do this with the new implementation being named DateAndTime (not LXDateAndTime).
Dave
On Mon, Apr 7, 2014 at 1:40 PM, Chris Muller asqueaker@gmail.com wrote:
As I was programming in Squeak today, I typed a class name, including its two-letter prefix. I wondered, could Environments be used to, dynamically, only in transient memory, remove a prefix from a package? It would be nice to enjoy typing and reading the pure, unprefixed class names, but would want to keep the original prefixes when I save a new version of the package.
I'm not sure what you mean by "dynamically, only in transient memory" here.
You could certainly load a package that has prefixed-class-names and refer to those classes without prefixes. It would be something like this:
| magmaEnv appEnv | magmaEnv := Environment withName: 'Magma'. magmaEnv exportSelf.
appEnv := Environment withName: 'My App'. appEnv import: magmaEnv removingPrefix: 'Ma'; importSelf.
Load your prefixed Magma classes into magmaEnv, and then write your app code in appEnv referring to Magma classes without prefixes.
Colin
On Mon, Apr 7, 2014 at 1:40 PM, Chris Muller asqueaker@gmail.com wrote:
As I was programming in Squeak today, I typed a class name, including its two-letter prefix. I wondered, could Environments be used to, dynamically, only in transient memory, remove a prefix from a package? It would be nice to enjoy typing and reading the pure, unprefixed class names, but would want to keep the original prefixes when I save a new version of the package.
I'm not sure what you mean by "dynamically, only in transient memory" here.
You could certainly load a package that has prefixed-class-names and refer to those classes without prefixes. It would be something like this:
| magmaEnv appEnv | magmaEnv := Environment withName: 'Magma'. magmaEnv exportSelf.
appEnv := Environment withName: 'My App'. appEnv import: magmaEnv removingPrefix: 'Ma'; importSelf.
Load your prefixed Magma classes into magmaEnv, and then write your app code in appEnv referring to Magma classes without prefixes.
That example gave me a lot of context, thanks. So, that would allow me to see and type "ObjectSerializer" instead of MaObjectSerializer. Great! The system is more beautiful.
Now say I save a new MC version of "My App" package. I've made a couple of new references to ObjectSerializer. Now I load that version into a clean image without creating any environments at all. Will I see ObjectSerializer or MaObjectSerializer in the code?
My knowledge of Environments is still very limited, maybe transient-renames could be a good excuse to find time to unbox and try it out.
On Mon, Apr 7, 2014 at 8:10 PM, Chris Muller ma.chris.m@gmail.com wrote:
Now say I save a new MC version of "My App" package. I've made a couple of new references to ObjectSerializer. Now I load that version into a clean image without creating any environments at all. Will I see ObjectSerializer or MaObjectSerializer in the code?
You'll see ObjectSerializer.
Colin
Hm, okay. So when I ran that example code earlier to create the 'My App' Environment,
| magmaEnv appEnv | magmaEnv := Environment withName: 'Magma'. magmaEnv exportSelf.
appEnv := Environment withName: 'My App'. appEnv import: magmaEnv removingPrefix: 'Ma'; importSelf.
and then loaded Magma into its environment and My App into the My App environment, if I were to immediately then press the Changes button in the MC browser for My App, one might assume they should find lots of changes due to the stripping of the prefixes from the existing references to MaObjectSerializer now being without the prefix.
Something tells me that's not what would happen though -- because that would require Environments to go making source-code updates and I'm doubtful it does that. Environments is just about multiple SystemDictionray's with different keys to support prettier / non-conflicting names. That's my high-level understanding of what Environments does, but I don't grok yet how it's supposed to be properly used..
On Mon, Apr 7, 2014 at 8:19 PM, Colin Putney colin@wiresong.com wrote:
On Mon, Apr 7, 2014 at 8:10 PM, Chris Muller ma.chris.m@gmail.com wrote:
Now say I save a new MC version of "My App" package. I've made a couple of new references to ObjectSerializer. Now I load that version into a clean image without creating any environments at all. Will I see ObjectSerializer or MaObjectSerializer in the code?
You'll see ObjectSerializer.
Colin
On Mon, Apr 7, 2014 at 8:51 PM, Chris Muller ma.chris.m@gmail.com wrote:
Hm, okay. So when I ran that example code earlier to create the 'My App' Environment,
| magmaEnv appEnv | magmaEnv := Environment withName: 'Magma'. magmaEnv exportSelf.
appEnv := Environment withName: 'My App'. appEnv import: magmaEnv removingPrefix: 'Ma'; importSelf.
and then loaded Magma into its environment and My App into the My App environment, if I were to immediately then press the Changes button in the MC browser for My App, one might assume they should find lots of changes due to the stripping of the prefixes from the existing references to MaObjectSerializer now being without the prefix.
Something tells me that's not what would happen though -- because that would require Environments to go making source-code updates and I'm doubtful it does that. Environments is just about multiple SystemDictionray's with different keys to support prettier / non-conflicting names. That's my high-level understanding of what Environments does, but I don't grok yet how it's supposed to be properly used..
That's exactly right. Environments swizzles bindings around so that you can refer to classes by whatever names you want, but it doesn't change your source code to actually use those names.
If you've got a pre-existing MyApp that refers to Magma classes via prefixed names, when you load it into appEnv, it won't have any changes, but all those references will be broken. You'll need to rewrite the source code to use the new names. (Should be fairly easy with the RB).
If you're starting your app from scratch, it's less of an issue. :-)
Colin
That's exactly right. Environments swizzles bindings around so that you can refer to classes by whatever names you want, but it doesn't change your source code to actually use those names.
If you've got a pre-existing MyApp that refers to Magma classes via prefixed names, when you load it into appEnv, it won't have any changes, but all those references will be broken. You'll need to rewrite the source code to use the new names. (Should be fairly easy with the RB).
If you're starting your app from scratch, it's less of an issue. :-)
Wow, that is surprising. I always thought of Environments as the tool to _save_ me from having to use the Rewrite tool. I also didn't realize that the source codebase needs to be kept in-sync with the Environment declarations. Wouldn't it be better to let code remain unaware of Environments?
On Tue, Apr 8, 2014 at 7:42 PM, Chris Muller asqueaker@gmail.com wrote:
If you're starting your app from scratch, it's less of an issue. :-)
Wow, that is surprising. I always thought of Environments as the tool to _save_ me from having to use the Rewrite tool. I also didn't realize that the source codebase needs to be kept in-sync with the Environment declarations. Wouldn't it be better to let code remain unaware of Environments?
Indeed! Having code be unaware of Environments was one of the primary design goals. It should be the other way around: tailor the environment to the needs of the codebase. If you have an app that refers to the prefixed names already, just load it into an environment that doesn't strip them off. Or heck, keep loading it into the default environment, along with Magma and ignore environments completely.
The only reason to change your code is because you want to use different (prettier?) names. In that case, do it on your own terms, with whatever naming conventions or development tools you want.
The point of all this is to decouple the declarations of classes from their references, and as a result, remove the need for the community to coordinate the naming of classes. You, as the developer of Magma can use whatever names make sense in the context of developing Magma, and I, as the developer of MyApp, can use whatever names make sense in that context. Regardless what choices we make, it should be possible to set up an environment that lets MyApp use Magma without either of us having to change our code to make it work.
Does that make sense?
Colin
Indeed! Having code be unaware of Environments was one of the primary design goals. It should be the other way around: tailor the environment to the needs of the codebase. If you have an app that refers to the prefixed names already, just load it into an environment that doesn't strip them off. Or heck, keep loading it into the default environment, along with Magma and ignore environments completely.
The only reason to change your code is because you want to use different (prettier?) names. In that case, do it on your own terms, with whatever naming conventions or development tools you want.
The point of all this is to decouple the declarations of classes from their references, and as a result, remove the need for the community to coordinate the naming of classes. You, as the developer of Magma can use whatever names make sense in the context of developing Magma, and I, as the developer of MyApp, can use whatever names make sense in that context. Regardless what choices we make, it should be possible to set up an environment that lets MyApp use Magma without either of us having to change our code to make it work.
Does that make sense?
It makes sense when stated at that (high) level. I think what happens for me is when I start to think about the details of daily development, I start to get confused. Let me see if I can talk my way through self-understanding this.
If I'm developing a new app, I can already choose a different name to avoid conflict. I want Environments to be useful when there are two _existing_ legacy apps that have _already_ chosen to use the same name. Is that use-case handled by Environments? My guess is, it is, as long as the names are changed only in the downstream (e.g., calling) Environment, it is.
For example, if WASession and MagmaSession had both been simply named "Session" from the very beginning but I want MySeasideMagmaApp to use them both, then I could import them each into their own Environment. Then I could import those two Environments into a third "MySeasideMagmaApp" Environment and prepend a prefix to one or both of them. Since Magma is in its own environment, its own references to "Session" are correct. And since Seaside is in its own environment, its own referrences to Session are correct too (Seaside Sessions). Finally, since MySeasideMagmaApp is in ITS own Environment, it can refer to MagmaSession and SeasideSession because I prepended "Magma" and "Seaside" prefixes. Is this a correct understanding?
Hm, seems like there'll need to be some way to set up Environments as part of the package-loading process, so they'll be loaded into the correct Environments... Preamble script?
Thanks.
PS -- I didn't mean to inundate you with questions. I probably need to dig into it and actually try it out. I was just trying to get a feel for the use-cases and usage conventions, so I knew where to start.
On Wed, Apr 9, 2014 at 10:50 AM, Chris Muller asqueaker@gmail.com wrote:
If I'm developing a new app, I can already choose a different name to avoid conflict. I want Environments to be useful when there are two _existing_ legacy apps that have _already_ chosen to use the same name. Is that use-case handled by Environments? My guess is, it is, as long as the names are changed only in the downstream (e.g., calling) Environment, it is.
For example, if WASession and MagmaSession had both been simply named "Session" from the very beginning but I want MySeasideMagmaApp to use them both, then I could import them each into their own Environment. Then I could import those two Environments into a third "MySeasideMagmaApp" Environment and prepend a prefix to one or both of them. Since Magma is in its own environment, its own references to "Session" are correct. And since Seaside is in its own environment, its own referrences to Session are correct too (Seaside Sessions). Finally, since MySeasideMagmaApp is in ITS own Environment, it can refer to MagmaSession and SeasideSession because I prepended "Magma" and "Seaside" prefixes. Is this a correct understanding?
Yes. That's exactly right.
Hm, seems like there'll need to be some way to set up Environments as part of the package-loading process, so they'll be loaded into the correct Environments... Preamble script?
No a preamble because that would make the code know about environments, which (as you pointed out) we don't want. For manual loading, we need to make it possible to open an MC browser for a specific environment, so you can manage the code it contains.
Load scripts should be able to set up environments programmatically and load packages into them. There isn't a nice API for that yet.
PS -- I didn't mean to inundate you with questions. I probably need to dig into it and actually try it out. I was just trying to get a feel for the use-cases and usage conventions, so I knew where to start
No problem. The core environments code pretty good, but actually using them is still a hassle because the tools don't have support yet.
Right now I'm working on making Workspace environment-aware. Instead of a pool dictionary for local bindings, it'll have its own environment. Be default it'll import Smalltalk, but you can import other environments as well. That's exposing all sorts of little issues that I'm working through.
Colin
squeak-dev@lists.squeakfoundation.org