Le 10 avr. 2015 à 06:09, Ben Coman a écrit :
I believe #asClass itself was introduced for a use case to simplify Workspace "user interactive" Gofer scripts to retrieve and load Configurations. Since this is through away code its not covered by your modularity concerns, and I'm not sure if it came before or after its friends, but can we retain or substitute something to avoid needing ugly "(Smalltalk at: #ConfigurationOfXXX) load" ?
This is a "first impression" consideration for people dealing with Configurations for the first time (even thought we now have Configuration Browser). The use case is that newbies will copy-paste a script from a web site to Playground and execute the whole script resulting in a error "Unknown class ConfigurationOfXXX." They don't know to execute in two separate steps, first "Gofer ... load" then "ConfigurationOfXXX load".
Alternatively, what if the Metacello package extended Gofer with a method #configurationOf: so websites can show...
config := Gofer new url: 'http://smalltalkhub.com/mc/MyProject/main' package: 'MyXXXPackage'; load; configurationOf: 'XXX' "return class ConfigurationOfXXX" config load.
...so the compiler is dealing with a variable "config" rather than class 'ConfigurationOfXXX' that it doesn't know yet, or a further altenative...
Gofer new url: 'http://smalltalkhub.com/mc/MyProject/main' package: 'MyXXXPackage'; load; configurationOf: 'XXX' do: [ :config | config load ]; configurationOf: 'YYY' do: [ :config | config load ].
cheers -ben
It is not a problem anymore. We have better ways to load a configuration and the associated packages: Metacello new configuration: 'XXX'; squeaksource3: 'MyProject'; version: '0.9.0'; load. Le 10 avr. 2015 à 08:57, phil@highoctane.be a écrit :
For the GLM things, I guess it allows one to have code that works only if an extra module is loaded.
We have asString and it is fine. Now asClass will not be. Duh?
aThing perform: #someAction is as complicated.
Yeah make a lint rule but do not disallow the usage.
The problem is that if you want to allow to browse remote code or to have 2 versions of the same class in the system for example, aSymbol asClass will not work. It will always search the class in the environment of the String class. The resolution of a symbol should be the responsibility of Environment. asString does not have the same problem. To me, #perform: is not a problem because the resolution of the selector is done by the class. I don't see a case where you do not want that. Christophe.
On 10/04/2015 4:32 am, "stepharo" <stepharo@free.fr> wrote: Hi
We want to raise a strong warning against the extension of the use of asClass and friends. asClass should not be used in Pharo distribution. I will propose to deprecate it.
We are working on dependency analysis, module system, remote debugging and asClass introduces lose class references and many related problems.
I would like to remove this behavior because it is clear that it will just grow up and lead to deadcode and ugly dependencies.
First, most of the time you can avoid to query Smalltalk globals at: and that BY CONSTRUCTION a software system should be built and it should define its own customization.
Second, at least use self class environment at: #foo
Why is it much much much better? because it does not rely on String class resolution and as such is much more modular. You do not want to have the resolution of a symbol related to the place where String is defined but on where your code is actually.
Imagine that tomorrow your code is in its own module. Then you want to know from your code point of you if a binding exist not from the one of environment in which String is.
here are some examples:
============================== quadrangleClass ^ 'QuadrangleForTesting' asClass
Strange it simply breaks. Of course it broke the smallLint rule.
============================== Metacello should better define OSProcess as a dependent.Because it is not clear what will happen if if not there?
extractRepositoryFrom: zipFile to: directory "unzip <zipFile> into <directory>"
| out err proc errorMessage | out := FileStream forceNewFileNamed: '/tmp/zip.out'. err := FileStream forceNewFileNamed: '/tmp/zip.err'. errorMessage := ''. [ proc := #OSProcess asClass thisOSProcess forkJob: '/usr/bin/unzip' arguments: {'-u'. zipFile. '-d'. directory} environment: nil descriptors: (Array with: nil with: out with: err).
==================
I do not get why we need this funky logic.
openInBrickWindowLabeled: aLabel
#GLMSystemWindowBrick asClassIfAbsent: [ ^ self asMorph openInWindow ].
^ #GLMSystemWindowBrick asClass new label: aLabel; color: Color transparent; addBrickBack: ( GLMBrick new vSpaceFill
window "Answer the receiver's window." #GLMWindowBrick asClassIfAbsent: [ ^ self ownerThatIsA: SystemWindow ].
^ (self ownerThatIsA: #GLMWindowBrick asClass) ifNil: [ self ownerThatIsA: SystemWindow ]
sendUsageData: aBoolean | settingsClass | settingsClass := #GTSpotterEventRecorderSettings asClassIfAbsent: [ ^ self ]. ^ settingsClass sendUsageData: aBoolean
sendUsageData | settingsClass | settingsClass := #GTSpotterEventRecorderSettings asClassIfAbsent: [ ^ false ]. ^ settingsClass sendUsageData