Johan Brichau wrote:
Itâs true that when you do a lot of cross-dialect development, such a method is often what you desire. However, I think itâs better to do feature detection instead of dialect detection.
+1 and others agree... (though on the net its possible to find material to support any view) "test for features, not for platforms" http://programmers.stackexchange.com/questions/50876/are-there-any-best-prac... "The best bet is always to test for features, not versions, because it's difficult to screw that up and it allows for the possibility that things might be back-ported in future. " http://mac-os-x.10953.n7.nabble.com/CocoaApp-isThisTiger-td29619i20.html "The Autoconf approach to portability is to test for features, not for versions." http://en.wikipedia.org/wiki/Autoconf btw Johan, how would you handle a method-existence-based requirement rather than class-existence-based? ...
So, something like:
((Smalltalk includesKey: #CharacterWriteStream) ifTrue:[ stream := CharacterWriteStream on: (String new: 10) ] ifFalse:[ stream := WriteStream on: (String new: 10) ]
And yes: use Grease where applicable. We try to maintain Grease across Pharo, Squeak and Gemstone. I also think itâs actively ported to VA.
cheers Johan
On 05 Oct 2014, at 09:00, stepharo <stepharo@free.fr> wrote:
Hi jan
Thanks for the proposal. I thought about it and I'm against because it goes again the idea of dispatch. I prefer to have a class and some dispatch. Seaside with Grease is the way to go from my perspective. Finally I do not want such methods in the systems because I spent my time removing isXXXX because of bad design. Let us see what other people think.
Stef
With the disclaimer that I haven't done cross platform Smalltalk yet, in general philosophy I agree with Stef. "A Mentoring Course On Smalltalk" regarding elimination of conditional logic says, "drawing design time distinctions at run time is intention obscuring by nature". ...
On 4/10/14 22:14, Jan Vrany wrote:
Hi guys,
I've just opened:
https://pharo.fogbugz.com/f/cases/14160/Introduce-isXXX-dialect-testing-meth...
Introduce isXXX (isPharo, isVisualWorks, ...) dialect testing methods to SmalltalkImage to ease multi-dialect development.
You would need to get ALL dialects to implement the convention?
RATIONALE:
Commonly used approach to solve differences among dialect is to use a sort of platform object and dispatch there for troublesome operations that has to be specialized. This platform object is usually in platform specific package.
Other option is to load some library like Grease or Sport.
The problem of the first approach is that brings to much (unnecessary) burden when used for two, three things. The amount of of the code and management is way to bigger then the amount of the code that has to be specialized.
However if you do want to go the testing-for-versions, and your concern is management of separate packages, then perhaps it can all be done on one package. The following does not seem too onerous from a code perspective... ------------------ CrossPlatform>>platform ^ CurrentPlatform ifNil: [ "<--class variable" CurrentPlatform := self class subClasses detect: [ :candidatePlatformClass | candidatePlatformClass isCurrentPlatform CrossPlatform subclass: SomeCoolDialect. SomeCoolDialect>>isCurrentPlatform ^ (Smalltalk version includesSubstring: 'SomeCoolDialect') ------------------ CrossPlatform>>writeStreamOn: aString self platform writeSteamOn: aString SomeCoolDialect>>writeStreamOn: aString ^ CharacterWriteStream on: aString ------------------ Loading Grease/Sport on the other hand introduces a
dependency on an external package - not worth of for two or three things.
The proposed dialect testing messages would allow for simple, #ifdef-like idiom like:
"New #ifdef's which test for specific compilers or manufacturers or operating systems are unacceptable. All #ifdef's should test for features." https://www.cs.utah.edu/dept/old/texinfo/gdb/gdbint.html cheers -ben
| stream | ... ((Smalltalk respondsTo: #isSomeCoolDialect) and:[Smalltalk isSomeCoolDialect]) ifTrue:[ stream := CharacterWriteStream on: (String new: 10) ] ifFalse:[ stream := WriteStream on: (String new: 10) ]
The #respondsTo: check, while not nice, is required as at the moment not all dialects could be trusted to have these testing messages.
Putting these methods may not stick with Pharo standard (whatever it is), but Smalltalk global is probably one of the very few that are present in pretty much every Smalltalk implementation. Other option would be to place them to the class side of an Object (which is amost certainly present everywhere), however
Smalltalk isPharo
reads better than
Object isPharo.
Best, Jan