Discussion:
[ANN] Preference pragmas
(too old to reply)
Andreas Raab
2012-01-28 12:23:25 UTC
Permalink
Folks -

I wanted to make the property whether to show individual processes in
MessageTally a preference and couldn't recall any of the three gazillion
methods to create one ;-) So I decided enough is enough and added the
ability to register a preference via Pragma. In other words, you specify
two class side accessors (using MessageTally as example):

showProcesses
"Indicates whether to show each process separately or cumulatively."
<preference: 'Show Processes in MessageTally'
category: 'debug'
balloonHelp: 'If enabled, each profiled process is shown individually
in MessageTally'
type: #Boolean>
^ShowProcesses

showProcesses: aBool
"Indicates whether to show each process separately or cumulatively."
ShowProcesses := aBool.

and then register the preference in the class initialization method via:

initialize
"MessageTally initialize"
"By default, show each process separately"
ShowProcesses := true.
"Register preferences"
Preferences addPreferencesFor: self.

The nice thing about this scheme is that the preference is local to the
code where it's used and that there are no more generated accessors
which mess up Monticello packages etc. What could probably be improved
is the self-registration; I left it that way for now since I don't know
how expensive it would be to scan all classes for new preferences when
one opens a preference browser. There is also an example class
PreferenceExample that illustrates the different types of preferences
(textual, numeric, color, boolean) you can use.

To install, just execute the following from Squeak 3.10.2:

Installer mantis fixBug: 7306.

Enjoy!
- Andreas
Eliot Miranda
2012-01-28 12:23:25 UTC
Permalink
Post by Andreas Raab
Folks -
I wanted to make the property whether to show individual processes in
MessageTally a preference and couldn't recall any of the three gazillion
methods to create one ;-) So I decided enough is enough and added the
ability to register a preference via Pragma. In other words, you specify two
Great to see you drinking the kool aid :) This is cool. Somehow "all"
(many) preferences ought to be defined this way.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20090303/f84dbcdd/attachment.htm
Michael Rueger
2012-01-28 12:23:27 UTC
Permalink
Post by Andreas Raab
Folks -
I wanted to make the property whether to show individual processes in
MessageTally a preference and couldn't recall any of the three gazillion
methods to create one ;-) So I decided enough is enough and added the
ability to register a preference via Pragma. In other words, you specify
showProcesses
"Indicates whether to show each process separately or cumulatively."
<preference: 'Show Processes in MessageTally'
category: 'debug'
balloonHelp: 'If enabled, each profiled process is shown
individually in MessageTally'
type: #Boolean>
^ShowProcesses
Looking at your version I see you made some slightly different design
choices than in the design that has been in design discussion and worked
on in the last couple of weeks on the Pharo list.

Can you elaborate what motivated the different design? Meaning what
parts of the Pharo version could be made better? Or, sorry for basically
asking the same thing three times, what would it take to adopt the Pharo
version for Squeak?

Michael
Bert Freudenberg
2012-01-28 12:23:27 UTC
Permalink
Post by Michael Rueger
Post by Andreas Raab
Folks -
I wanted to make the property whether to show individual processes
in MessageTally a preference and couldn't recall any of the three
gazillion methods to create one ;-) So I decided enough is enough
and added the ability to register a preference via Pragma. In other
words, you specify two class side accessors (using MessageTally as
showProcesses
"Indicates whether to show each process separately or
cumulatively."
<preference: 'Show Processes in MessageTally'
category: 'debug'
balloonHelp: 'If enabled, each profiled process is shown
individually in MessageTally'
type: #Boolean>
^ShowProcesses
Looking at your version I see you made some slightly different
design choices than in the design that has been in design discussion
and worked on in the last couple of weeks on the Pharo list.
Can you elaborate what motivated the different design? Meaning what
parts of the Pharo version could be made better? Or, sorry for
basically asking the same thing three times, what would it take to
adopt the Pharo version for Squeak?
Hmm, at least I am not aware of what is going on in Pharoland. I'm
reluctant to subscribe to the Pharo list. Not because I'm not
interested, but because for one my spare time is already filled up by
Etoys+Squeak+OLPC+Sugar, and also because the Pharo creators went to
their own playground specifically to get away from certain opinions on
squeak-dev. I feel like I shouldn't haunt them uninvitedly.

I wonder if someone could summarize what's going on on the greener
side, like the weekly excerpts we sometimes get for squeak-dev ... or
is there such a thing for Pharo already?

Anyway, I think it's great you point out this existing design.
Duplication of effort is not something we should put up with in our
small community. Do you have a direct pointer to the code in question?

- Bert -
Igor Stasenko
2012-01-28 12:23:28 UTC
Permalink
- Show quoted text -
Post by Michael Rueger
Post by Andreas Raab
Folks -
I wanted to make the property whether to show individual processes in
MessageTally a preference and couldn't recall any of the three gazillion
methods to create one ;-) So I decided enough is enough and added the
ability to register a preference via Pragma. In other words, you specify two
showProcesses
? "Indicates whether to show each process separately or cumulatively."
? <preference: 'Show Processes in MessageTally'
? ? ? category: 'debug'
? ? ? balloonHelp: 'If enabled, each profiled process is shown
individually in MessageTally'
? ? ? type: #Boolean>
? ^ShowProcesses
Looking at your version I see you made some slightly different design
choices than in the design that has been in design discussion and worked on
in the last couple of weeks on the Pharo list.
Can you elaborate what motivated the different design? Meaning what parts
of the Pharo version could be made better? Or, sorry for basically asking
the same thing three times, what would it take to adopt the Pharo version
for Squeak?
Hmm, at least I am not aware of what is going on in Pharoland. I'm reluctant
to subscribe to the Pharo list. Not because I'm not interested, but because
for one my spare time is already filled up by Etoys+Squeak+OLPC+Sugar, and
also because the Pharo creators went to their own playground specifically to
get away from certain opinions on squeak-dev. I feel like I shouldn't haunt
them uninvitedly.
I wonder if someone could summarize what's going on on the greener side,
like the weekly excerpts we sometimes get for squeak-dev ... or is there
such a thing for Pharo already?
Anyway, I think it's great you point out this existing design. Duplication
of effort is not something we should put up with in our small community. Do
you have a direct pointer to the code in question?
Well, it can be seen at different angle - a competition. If so, then
this is good as well - both vendors will try best to make own
framework better than others :)
And of course, if they decide to join efforts, both will win.
- Bert -
--
Best regards,
Igor Stasenko AKA sig.
Keith Hodges
2012-01-28 12:23:28 UTC
Permalink
Post by Michael Rueger
Post by Andreas Raab
Folks -
I wanted to make the property whether to show individual processes in
MessageTally a preference and couldn't recall any of the three
gazillion methods to create one ;-) So I decided enough is enough and
added the ability to register a preference via Pragma. In other
words, you specify two class side accessors (using MessageTally as
showProcesses
"Indicates whether to show each process separately or cumulatively."
<preference: 'Show Processes in MessageTally'
category: 'debug'
balloonHelp: 'If enabled, each profiled process is shown
individually in MessageTally'
type: #Boolean>
^ShowProcesses
Looking at your version I see you made some slightly different design
choices than in the design that has been in design discussion and
worked on in the last couple of weeks on the Pharo list.
Can you elaborate what motivated the different design? Meaning what
parts of the Pharo version could be made better? Or, sorry for
basically asking the same thing three times, what would it take to
adopt the Pharo version for Squeak?
Michael
Hallelujah,

thank you Michael

Keith
Andreas Raab
2012-01-28 12:23:28 UTC
Permalink
Post by Michael Rueger
Looking at your version I see you made some slightly different design
choices than in the design that has been in design discussion and worked
on in the last couple of weeks on the Pharo list.
Can you elaborate what motivated the different design? Meaning what
parts of the Pharo version could be made better? Or, sorry for basically
asking the same thing three times, what would it take to adopt the Pharo
version for Squeak?
Good question. I'm not (yet?) in a position to answer it. But it would
be good if you could point people to the code so they can look at it.
And if you would like to get it into 3.11 have please follow the process
described here:

http://lists.squeakfoundation.org/pipermail/squeak-dev/2009-February/134095.html

As for my variant, I wouldn't actually call it much of design ;-) More
like the simplest thing that I could possibly come up with and that
would work in the time frame that I had myself allowed to do it. If I
would have allowed myself a bit more time on it I would have done things
differently: I was thinking about exposing the actual class variable as
the preference object. In other words, the spec would've looked like:

<preference: #ClassVarName
label: 'Preference label'
category: 'PrefCategory'
balloonHelp: 'Your help goes here'
type: #TypeName>

and it would result in Preferences looking up the class var and using it
directly. The reason I like this better is that it allows the preference
to be implicitly synchronized. Since preference and class variable are
the same object, they cannot get out of sync (the version I posted
allows setting the value without updating the preference).

Exposing the class variable as preference also allows some interesting
uses like project- (or process-) local preferences simply by using a
different type of variable binding. I have recently been playing with
ProjectLocalBindings which redirect access to Project current to allow
for different values of our old friends Display and Sensor and it has
proven very fruitful. Preferences would be another very natural
application for these bindings. But obviously, this is more work (and it
didn't look pretty when I checked PreferenceValue and friends) so I just
wasn't up for it so I choose the easy way out ;-)

In any case, I'm not wed to my implementation. It's simple and
non-intrusive (which is good), it doesn't expose any of the internals
like PreferenceValue, PreferenceViewRegistry etc (which is good) but
other than that I have zero attachment to it. If there is a better
implementation that's out there let's just use that. The one desire I
would have for that implementation is that it allows taking out all the
preferences stuff for systems which don't provide a UI for it. I would
like to be able to add preferences in this form to some fairly low level
parts of the system and tying it into the presentation layer would be a
mistake for that.

Cheers,
- Andreas

PS. I'm only posting this to Squeak-dev since I have a distinct feeling
that my comments wouldn't be very welcome on the Pharo list. Please feel
free to forward it and correct me if I am mistaken.
Norbert Hartl
2012-01-28 12:23:28 UTC
Permalink
Post by Andreas Raab
PS. I'm only posting this to Squeak-dev since I have a distinct feeling
that my comments wouldn't be very welcome on the Pharo list. Please feel
free to forward it and correct me if I am mistaken.
Come on, guys! To be honest for me there are too much subtle things
floating around here the last weeks. How can we think about building a
common base for squeak, pharo et al. if there is so much emotional
cruft lying in the way?

I personally regard your posts quite well. There is always much sense
in there. And...sometimes I do not agree. And that is the same for the
other "old guys".

So I don't see any reason why you should not post such things on pharo
because the topic was already cross-squeak-pharoish.

You know it's just.....

...I don't like cross-posting ;)

Norbert
Andreas Raab
2012-01-28 12:23:28 UTC
Permalink
Post by Norbert Hartl
Post by Andreas Raab
PS. I'm only posting this to Squeak-dev since I have a distinct feeling
that my comments wouldn't be very welcome on the Pharo list. Please feel
free to forward it and correct me if I am mistaken.
Come on, guys! To be honest for me there are too much subtle things
floating around here the last weeks. How can we think about building a
common base for squeak, pharo et al. if there is so much emotional
cruft lying in the way?
From my side it is not emotional cruft. It is respect for their
decision. Anyone should be allowed to do what they'd like to do with the
people they'd like to do it. I don't feel invited (for good reasons I
think) and I don't want to intrude other people's private space. If this
is mistaken I'm open to changing it, but until I see evidence for that I
think it is wiser to leave the Pharo folks their own space.

Cheers,
- Andreas
Andreas Raab
2012-01-28 12:23:29 UTC
Permalink
Hi -
Post by Michael Rueger
Looking at your version I see you made some slightly different design
choices than in the design that has been in design discussion and worked
on in the last couple of weeks on the Pharo list.
Can you elaborate what motivated the different design? Meaning what
parts of the Pharo version could be made better?
Now that I've looked at Alain's code I can make a clearer statement
about it. I was misled a little at first by the similarities in the
pragma spec but the philosophy behind both implementations is actually
fairly different.

Alain's implementation of preferences is an improvement on the current
preference system but it is effectively replacing one set of
dependencies with a different set of dependencies. Where previously
Preferences would be registered and stored via Preferences
addPreference:... in Alain's approach preferences get created via (the
old version):

gradientButtonLook
<preference: 'Gradient look for buttons' type: #Boolean set:
#gradientButtonLook: defaultValue: true description: 'Gradient look for
buttons'>
^ GradientButtonLook
ifNil: [GradientButtonLook := PreferenceValue
value: true
location: self
selector: #gradientButtonLook]

or, with the latest:

gradientButtonLook
<preference>
^ GradientButtonLook
ifNil: [GradientButtonLook := PreferenceValue
name: 'Gradient look for buttons'
description: 'Gradient look for buttons'
parent: #uiPreferenceNode
type: #Boolean
default: false]

In other words, a dependency (to either PreferenceNode, PreferenceValue,
RangePreferenceValue, MultiplePreferenceValue etc) is created and stored
client-side.

My approach differs in such that it is aimed at being discoverable
without introducing any dependencies. To illustrate, please load the
latest (updated) version via:

Installer mantis bug: 7306 fix: 'PreferencePragmas.2.cs'.
Preferences registerForEvents.

And then do the following. Go into class MessageTally (to stay on-topic
;-) and change the method #defaultPollPeriod to read:

defaultPollPeriod
"Answer the number of milliseconds between interrupts for spyOn: and
friends.
This should be faster for faster machines."
<preference: 'Default Poll Period'
category: 'Profiling'
description: 'The default poll period (msecs) MessageTally uses'
type: #Number>
^DefaultPollPeriod ifNil: [ DefaultPollPeriod _ 1 ]

(yes, the spec has changed a tiny bit; I like Alain's 'description'
terminology better) Accept the method and open a preference browser.
Voila! There is a brand new "Profiling" category which allows you to set
MessageTally's default poll period. No further changes required.

However, since this was discovered via pragmas, no dependency between
Preferences and MessageTally has been created. You can remove or replace
the preferences implementation in the image without any side effects
whatsoever on MessageTally or its code. A different preference
implementation can discover the same preference and present it
accordingly. This allows adding preferences wherever is convenient
without needlessly introducing dependencies on a particular preference
implementation or UI.

In Alain's version this would not be possible without actually changing
code since it is directly coupled to a particular preference class and API.

Bottom line: I think my approach is a necessity before Alain's
preference implementation can be usefully deployed. It allows us to
define preferences without introducing dependencies to specific
implementations, while allowing different implementations to discover
the same preferences.

I hope this makes the conceptual difference clear.

Cheers,
- Andreas
Keith Hodges
2012-01-28 12:23:29 UTC
Permalink
Post by Andreas Raab
In Alain's version this would not be possible without actually
changing code since it is directly coupled to a particular preference
class and API.
Bottom line: I think my approach is a necessity before Alain's
preference implementation can be usefully deployed. It allows us to
define preferences without introducing dependencies to specific
implementations, while allowing different implementations to discover
the same preferences.
I hope this makes the conceptual difference clear.
Cheers,
- Andreas
Sounds good,

I will definitely be adopting this in a few packages.

Keith
Alain Plantec
2012-01-28 12:23:30 UTC
Permalink
Hi Andreas,
Post by Andreas Raab
Alain's implementation of preferences is an improvement on the current
preference system but it is effectively replacing one set of
dependencies with a different set of dependencies. Where previously
Preferences would be registered and stored via Preferences
addPreference:... in Alain's approach preferences get created via (the
...
Post by Andreas Raab
gradientButtonLook
<preference>
^ GradientButtonLook
ifNil: [GradientButtonLook := PreferenceValue
name: 'Gradient look for buttons'
description: 'Gradient look for buttons'
parent: #uiPreferenceNode
type: #Boolean
default: false]
In other words, a dependency (to either PreferenceNode,
PreferenceValue, RangePreferenceValue, MultiplePreferenceValue etc) is
created and stored client-side.
With Pharo approach, your code depends on a unique small hierarchy of
classes exactly as it can depend on Collection one.
It does not depend on a global object (Preferences) as it is now.
For me, it is not a problem since preferences are declared locally in
packages (exactly as in your pragma approach)
Post by Andreas Raab
My approach differs in such that it is aimed at being discoverable
without introducing any dependencies.
I don't think so, you are introducing a dependency on a particular
syntax wich is <preference: something: somethingelse: >
I think it is better to rely on classes and not to depend on a flat syntax.
Post by Andreas Raab
defaultPollPeriod
and friends.
This should be faster for faster machines."
<preference: 'Default Poll Period'
category: 'Profiling'
description: 'The default poll period (msecs) MessageTally uses'
type: #Number>
^DefaultPollPeriod ifNil: [ DefaultPollPeriod _ 1 ]
You also need
defaultPollPeriod: aNumber
DefaultPollPeriod := aNumber

and maybe another method for the default and maybe something else for
system level notification.

Only a detail maybe but In our implementation, for one preference, you
need to set only one declaration:
and you use the preference like this:
v := UIPreferences gradientButtonLook value.
UIPreferences gradientButtonLook value: false.

It allows system level notification because #PreferenceValue>>value:
triggers a #PreferenceChanged events.
An object can be declared as listener to a particular preference value
like this:
MyObject>>initialize
super initialize.
UIPreferences gradientButtonLook whenChangedSend:
#gradientButtonLookIsNow: to: self.

the opposite is #forget:
MyObject>>release
UIPreferences gradientButtonLook forget: self

You can see it as a replacement for changeInformee: informeeSymbol
changeSelector: aChangeSelector.
Post by Andreas Raab
However, since this was discovered via pragmas, no dependency between
Preferences and MessageTally has been created.
again, the dependency is on the syntax of the pragma
Post by Andreas Raab
You can remove or replace the preferences implementation in the image
without any side effects whatsoever on MessageTally or its code. A
different preference implementation can discover the same preference
and present it accordingly. This allows adding preferences wherever is
convenient without needlessly introducing dependencies on a particular
preference implementation or UI.
Pharo preference do not depends on a particular UI. PreferenceSupport is
removeable without any side effect on the system.
But I agree that it depends on the PreferenceNode hierarchy.
Post by Andreas Raab
In Alain's version this would not be possible without actually
changing code since it is directly coupled to a particular preference
class and API.
ok but the pragma-only declaration is poor: only flat syntax which
allows only literals as parameters.
the consequence is that you can't deal with one-to-many or range
preference or something else you can discover later.
Two examples:
here the value domain is explicitly given with the help of a
MultiplePreferenceValue. Each possible value of the preference is given
with FixedPreferenceValue instances.
themePreference
<preference>
^ ThemePreference
ifNil: [ThemePreference := MultiplePreferenceValue
name: 'UITheme'
description: 'The theme to use for UI look and feel'
parent: #uiPreferenceNode
type: #UITheme
default: UIThemeWatery2
values: {
FixedPreferenceValue
name: 'Standard Squeak'
description: 'Standard Squeak style'
type: #UITheme

value: UIThemeStandardSqueak.
FixedPreferenceValue
name: 'Watery 2'
description: 'Similar to a nice OS'
type: #UITheme
value: UIThemeWatery2}]

here a range preference value, again, the value domain is explicitly given.
glyphContrast
<preference>
^ GlyphContrast
ifNil: [GlyphContrast := RangePreferenceValue
name: 'Glyph contrast'
description: 'Change the contrast level for
glyphs. This is an integer between 1 and 100. (the default value is 50)'
parent: #freeTypePreferenceNode
type: #Integer
default: 50
range: (1 to: 100)]

If you only make use of a poor preference declaration (I consider
preference pragma flat declaration as a poor flat textual declaration)
it can have bad effects on the quality of the code which is using
the preference.
See how freetype hinting preference are currently handled.
You have 4 boolean preferences wheras following declaration better fits:

hintingPreference
<preference>
^ HintingPreference
ifNil: [HintingPreference := MultiplePreferenceValue
name: 'Hinting'
description: 'Changes the glyph shapes'
parent: #freeTypePreferenceNode
type: #Symbol
default: #Light
values: {
FixedPreferenceValue
name: 'Light'
description: 'Light hinting, bla bla bla
....'
type: #Symbol

value: #Light.
FixedPreferenceValue
name: 'Full'
description: 'Full hinting bla bla bla ....'
type: #Symbol
value: #Full.
FixedPreferenceValue
name: 'None'
description: 'None hinting bla bla bla ....'
type: #Symbol

value: #None.
FixedPreferenceValue
name: 'Normal'
description: 'Normal hinting bla bla bla
....'
type: #Symbol
value: #Normal}]

FixedPreferenceValue instance can be also bound to more complex values
than simple symbol (#Light, #Full ...)
FixedPreferenceValue
name: 'Light'
description: 'Light hinting, bla bla bla
....'
type: #FreeTypeHinting

value: [FreeTypeLightHinting new].
or
FixedPreferenceValue
name: 'Light'
description: 'Light hinting, bla bla bla
....'
type: #FreeTypeHinting

value: (MessageSend receiver:
FreeTypeLightHinting selector: #new).


Thus, the declaration is more rich. As a consequence, also with the help
of the system level notification,
a client code can be much more simple and well designed.
I mean avoiding code like:

FreeTypeSettings>>hintingFullPreferenceChanged
Preferences HintingFull
ifTrue:[Preferences disable: #HintingNone; disable:
#HintingLight; disable: #HintingNormal]
ifFalse:[
(Preferences HintingNone or:[Preferences HintingLight
or:[Preferences HintingNormal]])
ifFalse:[
"turn it back on again"
^Preferences enable: #HintingFull]].
monoHinting := Preferences HintingFull.
lightHinting := Preferences HintingLight.
hinting := monoHinting or:[lightHinting or:[Preferences HintingNormal]].
FreeTypeCache current removeAll.
FreeTypeFont allSubInstances do:[:each | each clearCachedMetrics].
NewParagraph allSubInstances do:[:each | each composeAll].
World restoreMorphicDisplay.

The last point you maybe missed (which is maybe not so important) is
that what we are declaring is a tree of preferences.
See Snapshot attached (For now, only a poor tool version,
"PreferenceTree open" to see it in action), it ilustrates well the point.
An again, this kind of tool is NOT mandatory. Related package can be
removed without side effect on the system because
it also makes use of dynamic preference discovering with the help of Pragma.

ah, the real last point is the default value: in your point of view,
default values depend on value type.
I can't agree with that point of view. It would mean, as an example,
that every boolean preferences have false, or true as the default.
The problem with non-literals then arises if you want to declare default
value with pragma...

ah, again. If your system relies on a <preference:truc:...> syntax. What
about evolution of the system ?
If you want to change all declarations, you have to find them all. As
far as I know, you can't rely on standard code browser for it.
And what about external tools and user application ?

Gary Chambers quote: -------------------------
Post by Andreas Raab
The simple pragma approach I described would make it easier for the
tools though since they wouldn't need a separate model (or hang onto
the pragma) in order to work.
Also, for user applications. Our ReportBuilder, for instance, also has
an end-user ui for preferences local to itself. Having acccess to the
default value/description withough having to find the pragma would be
easier. (Just an example, the ReportBuilder actually uses xml config
files for its prefs).
------------------------- End of Gary quote
Post by Andreas Raab
Bottom line: I think my approach is a necessity before Alain's
preference implementation can be usefully deployed. It allows us to
define preferences without introducing dependencies to specific
implementations, while allowing different implementations to discover
the same preferences.
I do not really understand.
Post by Andreas Raab
I hope this makes the conceptual difference clear.
Thanks for it.
...and remarks, critics, idea, improvements are welcomed.

Cheers
alain
Post by Andreas Raab
Cheers,
- Andreas
-------------- next part --------------
A non-text attachment was scrubbed...
Name: Preference tree.png
Type: image/png
Size: 43018 bytes
Desc: not available
Url : Loading Image...
Keith Hodges
2012-01-28 12:23:30 UTC
Permalink
I would like to see a simpler approach that may still be effective in
Kernel images with the minimal of scafolding, and I am still slightly
edgy about pragmas. (can anyone remember how Smalltalk Agents used to
use "directives"? I cant, but I seem to recall they were a similar idea).

Here is an idea:

Have classes PreferenceDefaults, PreferenceOptions, and
PreferenceValues, and have your package add method extensions to it. So
Monticello adds

PreferenceDefaults-#prefUseAtomicLoading

^ true


PreferenceDefaults subclass: PreferenceValues-#prefUseAtomicLoading

^ true

PreferenceOptions-#prefUseAtomicLoading

^ {

'Enable atomic loading' -> true.
'Disable atomic loading' -> false.

}

If you want to subclass PreferenceValues, for PreferenceUIValues, so
that a number of your UI packages become aware of PreferenceValues ui
prefScrollBarsOnRight (still use only one global in your client code if
possible)

Implementers of #prefUseAtomicLoading tells you all there is to know, -
who defined it, default value, possible values, current value.

You can save the preferences form the image in a file out of the class
Preferences.

If you have a subdomain that wants to use different values, define a
subclass of PreferenceValues, and inherit the defaults and current
setting, or inherit PreferenceDefaults and provide your own, (overriding
#ui to return ^self if you want to provide values for the
PreferenceUIValues).

You can easily have one preference depend upon the value of another, or
upon simple rules.

PreferenceDefaults-prefUseAtomicLoading ^ (Smalltalk classNamed:
#SystemEditor) notNil

In this manner you have a preferences system which needs "no code".
Discovery is a simple walk of the tree of PreferenceValues.

If you want to watch for preference changes, you can simply subscribe to
whatever system changes modification event mechanism is in place.

Keith
Andreas Raab
2012-01-28 12:23:30 UTC
Permalink
Hi Alain -
Post by Alain Plantec
With Pharo approach, your code depends on a unique small hierarchy of
classes exactly as it can depend on Collection one.
To me there is a big difference: From my perspective all preferences
code is UI code. Why? Because at the system level we use class variables
and messages, not preferences. At the system level if you want to
broadcast an event you use announcements or some other event system.

The sole purposes of preferences is to expose certain system variables
to the end-user. Consequently, preferences are part of the UI layer.
Post by Alain Plantec
It does not depend on a global object (Preferences) as it is now.
For me, it is not a problem since preferences are declared locally in
packages (exactly as in your pragma approach)
Yes, we agree on that.
Post by Alain Plantec
Post by Andreas Raab
My approach differs in such that it is aimed at being discoverable
without introducing any dependencies.
I don't think so, you are introducing a dependency on a particular
syntax wich is <preference: something: somethingelse: >
I think it is better to rely on classes and not to depend on a flat syntax.
There is no dependency on syntax. A dependency exists if some code
requires some other code to be present in order to function correctly.
In other words, if you load code that uses your preferences into some
other image it will not function until your preference implementation is
loaded. That is a dependency.

With preference pragmas as I have proposed them, the code can be loaded
into any image that supports pragmas. Put differently, I can load that
MessageTally class into Pharo, and it will continue to function
precisely the same. There is no dependency other than pragmas.
Post by Alain Plantec
Post by Andreas Raab
defaultPollPeriod
and friends.
This should be faster for faster machines."
<preference: 'Default Poll Period'
category: 'Profiling'
description: 'The default poll period (msecs) MessageTally uses'
type: #Number>
^DefaultPollPeriod ifNil: [ DefaultPollPeriod _ 1 ]
You also need
defaultPollPeriod: aNumber
DefaultPollPeriod := aNumber
The point here is that these methods exist already. What I demonstrated
in the above is that you can decide after the fact that you'd like to
expose a variable from your code to the end-user simply by putting a
preference pragma into it. With your implementation this would requires
rewriting several methods with mine it is simply marking up the method
to be discovered by preferences.

Actually, do me a favour and make a change that exposes
defaultPollPeriod via your implementation. This will allow us to compare
notes and also put the dependency discussion into context.
Post by Alain Plantec
triggers a #PreferenceChanged events.
Obviously, if you'd like notifications about something like it you would
use, e.g.,

MessageTally class>>defaultPollPeriod: aNumber

DefaultPollPeriod := aNumber.
self announce: (DefaultPollPeriodChanged value: aNumber).

so it's simply a regular event that notifies listeners about the change
if that is desired (and of course, if you'd want to present this as a
preference event you could do that too).
Post by Alain Plantec
Post by Andreas Raab
However, since this was discovered via pragmas, no dependency between
Preferences and MessageTally has been created.
again, the dependency is on the syntax of the pragma
There is no dependency on syntax. The FFI has a dependency on syntax as
in ulong 'SomeMethod' (ulong long char*) etc. Tweak has a dependency on
syntax, such as remote assignments as in anObject value := 42.

Preference pragmas have no dependency on syntax. Preference pragmas mark
up methods so that they can be discovered by a preference implementation.
Post by Alain Plantec
Pharo preference do not depends on a particular UI. PreferenceSupport is
removeable without any side effect on the system.
But I agree that it depends on the PreferenceNode hierarchy.
See above. To me it's all UI code.
Post by Alain Plantec
ok but the pragma-only declaration is poor: only flat syntax which
allows only literals as parameters.
the consequence is that you can't deal with one-to-many or range
preference or something else you can discover later.
Ah, but you can. That is a major advantage of it. For example, consider
range:

glyphContrast
<preference: 'Glyph contrast'
category: 'Freetype'
description: 'Change the contrast level for glyphs. This is an integer
between 1 and 100. (the default value is 50)'
type: #Number
min: 1
max: 100>
^GlyphContrast

Now, what is going to happen? A preference implementation will ignore
any preference pattern that it doesn't recognize. The code will still
continue to function, the preferences implementation will simply not be
able to make sense of the markup but nothing will get broken. So you get
even forward compatibility for free! (if the preference implementation
is smart it might be able to display this as grayed out to help people
giving feedback that there is something odd about it)

You can invent more complex patterns, custom patterns that only your
preference browser supports. Without breaking anyones code, without
introducing dependencies.
Post by Alain Plantec
here the value domain is explicitly given with the help of a
MultiplePreferenceValue. Each possible value of the preference is given
with FixedPreferenceValue instances.
Simplicity rules. At the point where you start wanting to have complex
UIs for setting preferences, I would offer the option to embed such UIs
directly, along the lines of:

uiTheme
<preference: 'UI Theme'
panelMorph: #uiThemeChooserMorph
description: 'The UI Theme'>

The panelMorph would describe a selector that is called by the
preference implementation to provide a custom preference panel. This
allows for maximum flexibility without the need to complicate the
implementation.

However, this just emphasizes that all of this is UI code. All you do is
providing instructions for the UI how to present things. Nothing wrong
with it, but goes to the heart of why I think all of this is really UI code.
Post by Alain Plantec
If you only make use of a poor preference declaration (I consider
preference pragma flat declaration as a poor flat textual declaration)
it can have bad effects on the quality of the code which is using
the preference.
How so? The preference isn't even visible to code. Code only uses what
code has ever used: Variables and Messages.
Post by Alain Plantec
See how freetype hinting preference are currently handled.
Okay. How about this:

hintingPreference
<preference: 'Hinting Preference'
category: 'FreeType'
description: 'How glyphs should be rendered'
type: #Choice
values: #(light medium heavy)>

^HintingPreference

hintingPreference: aSymbol
aSymbol = #light ifTrue:[
"set light hinting values"
].
"..."
Post by Alain Plantec
Thus, the declaration is more rich. As a consequence, also with the help
of the system level notification,
a client code can be much more simple and well designed.
I'm not sure why your example would be simpler or better designed than
what I am showing above. I mean my point here is that you provide the
methods that are being required, that you actually write the code that
other client code would use. And once you've done this you just tell the
system that it also can present that as a preference.
Post by Alain Plantec
The last point you maybe missed (which is maybe not so important) is
that what we are declaring is a tree of preferences.
Yes. But again, extensibility is a major advantage of pragma
preferences. See above.
Post by Alain Plantec
ah, the real last point is the default value: in your point of view,
default values depend on value type.
No! Absolutely not. From my point of view there is no "default" value
(well, you could add this if you needed it but I think it's completely
pointless). There is only the current value which is the value of some
variable.

[I will admit that my implementation is incomplete in this regard; it
should not use the Preference's value but rather fetch the value
straight from the source. I'll fix that eventually]
Post by Alain Plantec
I can't agree with that point of view. It would mean, as an example,
that every boolean preferences have false, or true as the default.
The problem with non-literals then arises if you want to declare default
value with pragma...
Once more, there is no "default". If one needed it it could be added
(cf. extensibility above) but I don't see a need. A preference is some
variable that has a value, no more.
Post by Alain Plantec
ah, again. If your system relies on a <preference:truc:...> syntax. What
about evolution of the system ?
And for a third time, there is no dependency, so there is no issue with
evolution of the system. If you load code that has a preference pragma
into a system that doesn't know what to do with it, it will just ignore
it. Your code will continue to function without any modifications.
Post by Alain Plantec
If you want to change all declarations, you have to find them all. As
far as I know, you can't rely on standard code browser for it.
And what about external tools and user application ?
I don't understand that. You can browse pragmas like regular messages,
you can edit them in regular browsers. There is no issue that I am aware
about.
Post by Alain Plantec
Gary Chambers quote: -------------------------
Post by Andreas Raab
The simple pragma approach I described would make it easier for the
tools though since they wouldn't need a separate model (or hang onto
the pragma) in order to work.
Also, for user applications. Our ReportBuilder, for instance, also has
an end-user ui for preferences local to itself. Having acccess to the
default value/description withough having to find the pragma would be
easier. (Just an example, the ReportBuilder actually uses xml config
files for its prefs).
------------------------- End of Gary quote
That seems to be a very specific implementation request. I wouldn't base
a framework decision on some report builder using xml config files for
prefs ;-)

But besides that, you probably haven't looked at my code, no? ;-) I can
tell because if you had, you would have seen that what the discovery
does, is taking the preference pragma and translate it into the current
preferences system.

In other words, there is no hanging on to pragmas. Your preferences
implementation could be *easily* made to pick up the preference pragmas
that I am proposing. This is my point after all, having the ability to
replace preference implementations!

Finally, the code that I got was incomplete. At least one class
(AbstractPreferenceValue) was missing. Can you point me to some code
that I can actually load and play with? Thanks.

Cheers,
- Andreas
Michael Rueger
2012-01-28 12:23:30 UTC
Permalink
Post by Andreas Raab
Hi Alain -
Post by Alain Plantec
With Pharo approach, your code depends on a unique small hierarchy of
classes exactly as it can depend on Collection one.
To me there is a big difference: From my perspective all preferences code is
UI code. Why? Because at the system level we use class variables and
messages, not preferences. At the system level if you want to broadcast an
event you use announcements or some other event system.
The sole purposes of preferences is to expose certain system variables to
the end-user. Consequently, preferences are part of the UI layer.
Currently traveling, so only a brief remark ;-)

I have to disagree with this assumption. For me preferences are also a
way to control non UI and also non end user settings in a system. A
simple example (maybe not even a good one) would be settings for a
server environment that I need to keep outside the image so I can drop
in a deployment image on every server. You don't want to have to run
special initialize do-its on a headless server image.

I also have a deep mistrust against all automagical gathering of
things (e.g via pragmas) as you loose control over the mechanism. I
like explicit registration of e.g. preferences, but that might be a
matter of style.

Michael
Gary Chambers
2012-01-28 12:23:30 UTC
Permalink
----- Original Message -----
Post by Andreas Raab
Hi Alain -
To me there is a big difference: From my perspective all preferences code
is UI code. Why? Because at the system level we use class variables and
messages, not preferences. At the system level if you want to broadcast an
event you use announcements or some other event system.
I disagree that preferences "as a concept" are UI level (in terms of
graphical and/or point and click).
It is quite valid that a preference exists for use with or without a user
means of setting/changing.

Regards, Gary.
Steve Wart
2012-01-28 12:23:31 UTC
Permalink
Well it's an interface between a user and the system, even if it's in a
config file. In that sense it's a UI component. Not all user interfaces are
graphical.

OTOH, that doesn't mean that a preferences mechanism isn't core in some way.
Even the most basic loader will need some way of indicating its preferred
data sources, etc.
Post by Gary Chambers
----- Original Message -----
Post by Andreas Raab
Hi Alain -
To me there is a big difference: From my perspective all preferences code
is UI code. Why? Because at the system level we use class variables and
messages, not preferences. At the system level if you want to broadcast an
event you use announcements or some other event system.
I disagree that preferences "as a concept" are UI level (in terms of
graphical and/or point and click).
It is quite valid that a preference exists for use with or without a user
means of setting/changing.
Regards, Gary.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20090306/3c4414a1/attachment.htm
Gary Chambers
2012-01-28 12:23:31 UTC
Permalink
Of course, from that perspective, all code is UI... :-)

Regards, Gary

----- Original Message -----
From: Steve Wart
To: The general-purpose Squeak developers list
Sent: Friday, March 06, 2009 6:09 PM
Subject: Re: [squeak-dev] Re: [ANN] Preference pragmas


Well it's an interface between a user and the system, even if it's in a config file. In that sense it's a UI component. Not all user interfaces are graphical.

OTOH, that doesn't mean that a preferences mechanism isn't core in some way. Even the most basic loader will need some way of indicating its preferred data sources, etc.


On Fri, Mar 6, 2009 at 9:46 AM, Gary Chambers <***@btinternet.com> wrote:

----- Original Message -----

Hi Alain -

To me there is a big difference: From my perspective all preferences code is UI code. Why? Because at the system level we use class variables and messages, not preferences. At the system level if you want to broadcast an event you use announcements or some other event system.




I disagree that preferences "as a concept" are UI level (in terms of graphical and/or point and click).
It is quite valid that a preference exists for use with or without a user means of setting/changing.

Regards, Gary.
Steve Wart
2012-01-28 12:23:31 UTC
Permalink
I don't think so. You have a file with some bytes in it that can do
things. The configuration of those things is conceptually separate.

Steve
Post by Gary Chambers
Of course, from that perspective, all code is UI... :-)
Regards, Gary
----- Original Message -----
From: Steve Wart
To: The general-purpose Squeak developers list
Sent: Friday, March 06, 2009 6:09 PM
Subject: Re: [squeak-dev] Re: [ANN] Preference pragmas
Well it's an interface between a user and the system, even if it's
in a config file. In that sense it's a UI component. Not all user
interfaces are graphical.
OTOH, that doesn't mean that a preferences mechanism isn't core in
some way. Even the most basic loader will need some way of
indicating its preferred data sources, etc.
----- Original Message -----
Hi Alain -
To me there is a big difference: From my perspective all preferences
code is UI code. Why? Because at the system level we use class
variables and messages, not preferences. At the system level if you
want to broadcast an event you use announcements or some other event
system.
I disagree that preferences "as a concept" are UI level (in
terms of graphical and/or point and click).
It is quite valid that a preference exists for use with or without a
user means of setting/changing.
Regards, Gary.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.squeakfoundation.org/pipermail/squeak-dev/attachments/20090306/360de83c/attachment.htm
Gary Chambers
2012-01-28 12:23:31 UTC
Permalink
Exactly my point...

Regards, Gary

----- Original Message -----
From: Steve Wart
To: The general-purpose Squeak developers list
Sent: Friday, March 06, 2009 6:38 PM
Subject: Re: [squeak-dev] Re: [ANN] Preference pragmas


I don't think so. You have a file with some bytes in it that can do things. The configuration of those things is conceptually separate.

Steve

On 6 Mar 2009, at 10:17, "Gary Chambers" <***@btinternet.com> wrote:


Of course, from that perspective, all code is UI... :-)

Regards, Gary

----- Original Message -----
From: Steve Wart
To: The general-purpose Squeak developers list
Sent: Friday, March 06, 2009 6:09 PM
Subject: Re: [squeak-dev] Re: [ANN] Preference pragmas


Well it's an interface between a user and the system, even if it's in a config file. In that sense it's a UI component. Not all user interfaces are graphical.

OTOH, that doesn't mean that a preferences mechanism isn't core in some way. Even the most basic loader will need some way of indicating its preferred data sources, etc.


On Fri, Mar 6, 2009 at 9:46 AM, Gary Chambers <***@btinternet.com> wrote:

----- Original Message -----

Hi Alain -

To me there is a big difference: From my perspective all preferences code is UI code. Why? Because at the system level we use class variables and messages, not preferences. At the system level if you want to broadcast an event you use announcements or some other event system.




I disagree that preferences "as a concept" are UI level (in terms of graphical and/or point and click).
It is quite valid that a preference exists for use with or without a user means of setting/changing.

Regards, Gary.






--------------------------------------------------------------------------
Alain Plantec
2012-01-28 12:23:32 UTC
Permalink
Post by Andreas Raab
Hi Alain -
The sole purposes of preferences is to expose certain system variables
to the end-user. Consequently, preferences are part of the UI layer.
It a point of view which I can agree on, but what now ?
Post by Andreas Raab
Post by Alain Plantec
Post by Andreas Raab
My approach differs in such that it is aimed at being discoverable
without introducing any dependencies.
I don't think so, you are introducing a dependency on a particular
syntax wich is <preference: something: somethingelse: >
I think it is better to rely on classes and not to depend on a flat syntax.
There is no dependency on syntax. A dependency exists if some code
requires some other code to be present in order to function correctly.
In other words, if you load code that uses your preferences into some
other image it will not function until your preference implementation
is loaded. That is a dependency.
ok but your tools which discover the preferences depends on the syntax.
Post by Andreas Raab
With preference pragmas as I have proposed them, the code can be
loaded into any image that supports pragmas. Put differently, I can
load that MessageTally class into Pharo, and it will continue to
function precisely the same. There is no dependency other than pragmas.
ok
Post by Andreas Raab
Post by Alain Plantec
Post by Andreas Raab
defaultPollPeriod
and friends.
This should be faster for faster machines."
<preference: 'Default Poll Period'
category: 'Profiling'
description: 'The default poll period (msecs) MessageTally uses'
type: #Number>
^DefaultPollPeriod ifNil: [ DefaultPollPeriod := 1 ]
You also need
defaultPollPeriod: aNumber
DefaultPollPeriod := aNumber
Actually, do me a favour and make a change that exposes
defaultPollPeriod via your implementation. This will allow us to
compare notes and also put the dependency discussion into context.
MessageTally>>defaultPollPeriod
<preference>
^ DefaultPollPeriod ifNil: [ DefaultPollPeriod :=
PreferenceValue
name: 'Default Poll Period'
description: 'The default poll period (msecs)
MessageTally uses'
parent: #httpProxyPreferenceNode
type: #Number
default: 1]
Post by Andreas Raab
Post by Alain Plantec
triggers a #PreferenceChanged events.
Obviously, if you'd like notifications about something like it you
would use, e.g.,
MessageTally class>>defaultPollPeriod: aNumber
DefaultPollPeriod := aNumber.
self announce: (DefaultPollPeriodChanged value: aNumber).
I can also use Announcement. In fact, this part is hidden, it is
encapsulated by PreferenceValue>>value:
the developper does not have to deal with it. From my point of view,
this is a good thing.
PreferenceValue>>valueSilently: can also be used if the announce is useless.
Post by Andreas Raab
so it's simply a regular event that notifies listeners about the
change if that is desired (and of course, if you'd want to present
this as a preference event you could do that too).
Post by Alain Plantec
Post by Andreas Raab
However, since this was discovered via pragmas, no dependency
between Preferences and MessageTally has been created.
again, the dependency is on the syntax of the pragma
There is no dependency on syntax. The FFI has a dependency on syntax
as in ulong 'SomeMethod' (ulong long char*) etc. Tweak has a
dependency on syntax, such as remote assignments as in anObject value
:= 42.
Preference pragmas have no dependency on syntax. Preference pragmas
mark up methods so that they can be discovered by a preference
implementation.
maybe "dependency on syntax" is not the good way to say that but you
have to deal with several pragma syntaxes, at least from discovering
tools point of view.
Post by Andreas Raab
Post by Alain Plantec
ok but the pragma-only declaration is poor: only flat syntax which
allows only literals as parameters.
the consequence is that you can't deal with one-to-many or range
preference or something else you can discover later.
Ah, but you can. That is a major advantage of it. For example,
glyphContrast
<preference: 'Glyph contrast'
category: 'Freetype'
description: 'Change the contrast level for glyphs. This is an
integer between 1 and 100. (the default value is 50)'
type: #Number
min: 1
max: 100>
^GlyphContrast
again another way of using pragmas (yet another syntax). I really prefer
objects and messages.
Post by Andreas Raab
Now, what is going to happen? A preference implementation will ignore
any preference pattern that it doesn't recognize. The code will still
continue to function, the preferences implementation will simply not
be able to make sense of the markup but nothing will get broken. So
you get even forward compatibility for free! (if the preference
implementation is smart it might be able to display this as grayed out
to help people giving feedback that there is something odd about it)
with the risk that a pragma form or syntax is not used or recognized
anymore and so completely useless.
Post by Andreas Raab
Simplicity rules. At the point where you start wanting to have complex
UIs for setting preferences, I would offer the option to embed such
uiTheme
<preference: 'UI Theme'
panelMorph: #uiThemeChooserMorph
description: 'The UI Theme'>
The panelMorph would describe a selector that is called by the
preference implementation to provide a custom preference panel. This
allows for maximum flexibility without the need to complicate the
implementation.
However, this just emphasizes that all of this is UI code. All you do
is providing instructions for the UI how to present things. Nothing
wrong with it, but goes to the heart of why I think all of this is
really UI code.
This is also the solution I used when I was trying an implementation
like yours, I mean with <preference:xxx:yyyy:...>
Post by Andreas Raab
Post by Alain Plantec
If you only make use of a poor preference declaration (I consider
preference pragma flat declaration as a poor flat textual declaration)
it can have bad effects on the quality of the code which is using
the preference.
How so? The preference isn't even visible to code. Code only uses what
code has ever used: Variables and Messages.
Post by Alain Plantec
See how freetype hinting preference are currently handled.
hintingPreference
<preference: 'Hinting Preference'
category: 'FreeType'
description: 'How glyphs should be rendered'
type: #Choice
values: #(light medium heavy)>
^HintingPreference
hintingPreference: aSymbol
aSymbol = #light ifTrue:[
"set light hinting values"
].
"..."
ok but again #(light medium heavy) is low level.
maybe the programmer wants the preference value to be a complex object
on which a strategy pattern can rely on as an example.
If you use symbols, the strategy can not be directly used, then the code
is more complex
Post by Andreas Raab
Post by Alain Plantec
Thus, the declaration is more rich. As a consequence, also with the
help of the system level notification,
a client code can be much more simple and well designed.
I'm not sure why your example would be simpler or better designed than
what I am showing above. I mean my point here is that you provide the
methods that are being required, that you actually write the code that
other client code would use. And once you've done this you just tell
the system that it also can present that as a preference.
the use of symbols implies the use of alternatives. From my point of
view, it can be a bad practice:
v = #light ifTrue: [ ... ]
v = #medium ifTrue: [...]
v = #heavy ifTrue: [...]
can reveal a bad design (I don't say it is always bad)
Post by Andreas Raab
Post by Alain Plantec
The last point you maybe missed (which is maybe not so important) is
that what we are declaring is a tree of preferences.
Yes. But again, extensibility is a major advantage of pragma
preferences. See above.
Post by Alain Plantec
ah, the real last point is the default value: in your point of view,
default values depend on value type.
No! Absolutely not. From my point of view there is no "default" value
(well, you could add this if you needed it but I think it's completely
pointless). There is only the current value which is the value of some
variable.
at least UI code need default values.
^DefaultPollPeriod ifNil: [ DefaultPollPeriod := 1 ]
here, 1 represents a start value.
suppose a user changes this to 3 and suppose that later he wants to come
back to the start value.
in that case the default is useful.
Post by Andreas Raab
[I will admit that my implementation is incomplete in this regard; it
should not use the Preference's value but rather fetch the value
straight from the source. I'll fix that eventually]
Post by Alain Plantec
I can't agree with that point of view. It would mean, as an example,
that every boolean preferences have false, or true as the default.
The problem with non-literals then arises if you want to declare
default value with pragma...
Once more, there is no "default". If one needed it it could be added
(cf. extensibility above) but I don't see a need. A preference is some
variable that has a value, no more.
Post by Alain Plantec
ah, again. If your system relies on a <preference:truc:...> syntax.
What about evolution of the system ?
And for a third time, there is no dependency, so there is no issue
with evolution of the system. If you load code that has a preference
pragma into a system that doesn't know what to do with it, it will
just ignore it. Your code will continue to function without any
modifications.
I think it is not desirable to have something useless in code.
If I understand well, you say that methods can contain
<preference:glorp:> and that is
doesn't matter is the system doesn't know how to handle or use it,
and if it is usable or not. Even the code continues to work, I would not
like it.
Post by Andreas Raab
Post by Alain Plantec
If you want to change all declarations, you have to find them all.
As far as I know, you can't rely on standard code browser for it.
And what about external tools and user application ?
I don't understand that. You can browse pragmas like regular messages,
you can edit them in regular browsers. There is no issue that I am
aware about.
What I mean is that there is no way to query methods which contain
pragma from regular browsers.
You have to write the tool with Pragma class.
With pharo solution, withsimply the help of regular Browser, you can
query all senders of #name:description:parent:type:default: in order
to get all PreferenceValue users and then to get preference methods.
Post by Andreas Raab
Post by Alain Plantec
Gary Chambers quote: -------------------------
Post by Andreas Raab
The simple pragma approach I described would make it easier for the
tools though since they wouldn't need a separate model (or hang onto
the pragma) in order to work.
Also, for user applications. Our ReportBuilder, for instance, also
has an end-user ui for preferences local to itself. Having acccess
to the default value/description withough having to find the pragma
would be easier. (Just an example, the ReportBuilder actually uses
xml config files for its prefs).
------------------------- End of Gary quote
That seems to be a very specific implementation request. I wouldn't
base a framework decision on some report builder using xml config
files for prefs ;-)
yes, ok, it was only an example and it is a small quote.
Post by Andreas Raab
But besides that, you probably haven't looked at my code, no? ;-) I
can tell because if you had, you would have seen that what the
discovery does, is taking the preference pragma and translate it into
the current preferences system.*
I've almost done it myself as a first implementation (with
<preference:xxx:yyy:> pragma).
The link with current PreferenceBrowser was not done but I had a
PreferenceCollector which was collecting all preferences.
Post by Andreas Raab
In other words, there is no hanging on to pragmas. Your preferences
implementation could be *easily* made to pick up the preference
pragmas that I am proposing.
yes
Post by Andreas Raab
This is my point after all, having the ability to replace preference
implementations!
Finally, the code that I got was incomplete. At least one class
(AbstractPreferenceValue) was missing.
oups ! sorry
Post by Andreas Raab
Can you point me to some code that I can actually load and play with?
ok, I will send the packages with some explanations.

Thanks
alain
Post by Andreas Raab
Thanks.
Cheers,
- Andreas
Travis Griggs
2012-01-28 12:23:31 UTC
Permalink
Post by Alain Plantec
Hi Andreas,
Post by Andreas Raab
Alain's implementation of preferences is an improvement on the
current preference system but it is effectively replacing one set
of dependencies with a different set of dependencies. Where
previously Preferences would be registered and stored via
Preferences addPreference:... in Alain's approach preferences get
...
Post by Andreas Raab
gradientButtonLook
<preference>
^ GradientButtonLook
ifNil: [GradientButtonLook := PreferenceValue
name: 'Gradient look for buttons'
description: 'Gradient look for buttons'
parent: #uiPreferenceNode
type: #Boolean
default: false]
In other words, a dependency (to either PreferenceNode,
PreferenceValue, RangePreferenceValue, MultiplePreferenceValue etc)
is created and stored client-side.
<rest snipped>

I've just been lurking, didn't even see the front of this thread. But
when I saw the lengthy method tag (pragma) in the previous post, it
caught my attention. And now, at least part of this discussion seems
to be on how much meta data to put in the method tag.

In my experience, you should use the strength of Smalltalk to build
objects and send messages between them to the utmost here. You should
use method tags (pragmas) to provide only enough information to help
you discover *which* methods to send for a particular service.

I wrote about what I see as a long running fiasco with the VisualWorks
menu pragmas and how that "syntax" got completely out of control. And
how we have moved beyond it.

http://www.cincomsmalltalk.com/userblogs/travis/blogView?showComments=true&printTitle=Menu_Items_Are_Objects_Too&entry=3354355944

That was more than a year ago, and I still stand, more than ever,
behind the assertions made there. Having simplified the menu pragmas
down to the bare essentials of "method discovery" and put the actual
code in, uh, code, has been great. I don't see a reason Squeak/Pharoa
Preferences wouldn't benefit in the same way.

Apologies if I misunderstood the jst of this thread and am off topic.

--
Travis Griggs
Objologist
For every adage, there is an equal and contrary un-adage
Igor Stasenko
2012-01-28 12:23:31 UTC
Permalink
Post by Travis Griggs
Post by Alain Plantec
Hi Andreas,
Post by Andreas Raab
Alain's implementation of preferences is an improvement on the current
preference system but it is effectively replacing one set of dependencies
with a different set of dependencies. Where previously Preferences would be
registered and stored via Preferences addPreference:... in Alain's approach
...
Post by Andreas Raab
gradientButtonLook
? <preference>
? ^ GradientButtonLook
? ? ? ifNil: [GradientButtonLook := PreferenceValue
? ? ? ? ? ? ? ? ? ? ? name: 'Gradient look for buttons'
? ? ? ? ? ? ? ? ? ? ? description: 'Gradient look for buttons'
? ? ? ? ? ? ? ? ? ? ? parent: #uiPreferenceNode
? ? ? ? ? ? ? ? ? ? ? type: #Boolean
? ? ? ? ? ? ? ? ? ? ? default: false]
In other words, a dependency (to either PreferenceNode, PreferenceValue,
RangePreferenceValue, MultiplePreferenceValue etc) is created and stored
client-side.
<rest snipped>
I've just been lurking, didn't even see the front of this thread. But when I
saw the lengthy method tag (pragma) in the previous post, it caught my
attention. And now, at least part of this discussion seems to be on how much
meta data to put in the method tag.
In my experience, you should use the strength of Smalltalk to build objects
and send messages between them to the utmost here. You should use method
tags (pragmas) to provide only enough information to help you discover
*which* methods to send for a particular service.
I wrote about what I see as a long running fiasco with the VisualWorks menu
pragmas and how that "syntax" got completely out of control. And how we have
moved beyond it.
http://www.cincomsmalltalk.com/userblogs/travis/blogView?showComments=true&printTitle=Menu_Items_Are_Objects_Too&entry=3354355944
That was more than a year ago, and I still stand, more than ever, behind the
assertions made there. Having simplified the menu pragmas down to the bare
essentials of "method discovery" and put the actual code in, uh, code, has
been great. I don't see a reason Squeak/Pharoa Preferences wouldn't benefit
in the same way.
Apologies if I misunderstood the jst of this thread and am off topic.
No, your post were strictly on topic.
I read a blog post and now i think that the main argument against
using declarative pragma syntax is:

"Doing this, you lose all the benefits of having a real object that
you can send real messages to. Which means you've avoided using
Smalltalks halmark strength."

And counter argument is:

"Alain's implementation of preferences is an improvement on the
current preference system but it is effectively replacing one set of
dependencies with a different set of dependencies , like
PreferenceValue and so on.."

Then how about compromise:

gradientButtonLookPreference: preferenceManager
<preference>
| prefDeclaration |
prefDeclaration := preferenceManager preferenceName: 'Gradient look for buttons'
description: 'Gradient look for buttons'
type: #Boolean
default: false;
getter: #gradientButtonLook setter: #gradientButtonLook: .

^ prefDeclaration foo bar zork.

.... etc...

In the example above, i just wanted to illustrate , that there is no
need to be dependent on global names, like PreferenceValue etc.
We could define a protocol which can be used to declare a preference,
and all methods with <preference> pragma should follow it.
a preferenceManager can be anything, can use any classes what it needs
to give user a way to define/change preferences.
Still no direct dependency between code which declaring preference and
preference management framework, except that it expects a
preferenceManager to support a certain protocol.
Post by Travis Griggs
--
Travis Griggs
Objologist
For every adage, there is an equal and contrary un-adage
--
Best regards,
Igor Stasenko AKA sig.
Gary Chambers
2012-01-28 12:23:31 UTC
Permalink
Still a dependancy (unavoidable) on whatever preferenceManager points to...
Better than direct class reference, I agree. (c.f. UIManager delegation).

Regards, Gary

----- Original Message -----
From: "Igor Stasenko" <***@gmail.com>
To: "The general-purpose Squeak developers list"
<squeak-***@lists.squeakfoundation.org>
Sent: Friday, March 06, 2009 7:25 PM
Subject: Re: [squeak-dev] Re: [ANN] Preference pragmas
Post by Travis Griggs
Post by Alain Plantec
Hi Andreas,
Post by Andreas Raab
Alain's implementation of preferences is an improvement on the current
preference system but it is effectively replacing one set of
dependencies
with a different set of dependencies. Where previously Preferences would be
registered and stored via Preferences addPreference:... in Alain's approach
...
Post by Andreas Raab
gradientButtonLook
<preference>
^ GradientButtonLook
ifNil: [GradientButtonLook := PreferenceValue
name: 'Gradient look for buttons'
description: 'Gradient look for buttons'
parent: #uiPreferenceNode
type: #Boolean
default: false]
In other words, a dependency (to either PreferenceNode, PreferenceValue,
RangePreferenceValue, MultiplePreferenceValue etc) is created and stored
client-side.
<rest snipped>
I've just been lurking, didn't even see the front of this thread. But when I
saw the lengthy method tag (pragma) in the previous post, it caught my
attention. And now, at least part of this discussion seems to be on how much
meta data to put in the method tag.
In my experience, you should use the strength of Smalltalk to build objects
and send messages between them to the utmost here. You should use method
tags (pragmas) to provide only enough information to help you discover
*which* methods to send for a particular service.
I wrote about what I see as a long running fiasco with the VisualWorks menu
pragmas and how that "syntax" got completely out of control. And how we have
moved beyond it.
http://www.cincomsmalltalk.com/userblogs/travis/blogView?showComments=true&printTitle=Menu_Items_Are_Objects_Too&entry=3354355944
That was more than a year ago, and I still stand, more than ever, behind the
assertions made there. Having simplified the menu pragmas down to the bare
essentials of "method discovery" and put the actual code in, uh, code, has
been great. I don't see a reason Squeak/Pharoa Preferences wouldn't benefit
in the same way.
Apologies if I misunderstood the jst of this thread and am off topic.
No, your post were strictly on topic.
I read a blog post and now i think that the main argument against
using declarative pragma syntax is:

"Doing this, you lose all the benefits of having a real object that
you can send real messages to. Which means you've avoided using
Smalltalks halmark strength."

And counter argument is:

"Alain's implementation of preferences is an improvement on the
current preference system but it is effectively replacing one set of
dependencies with a different set of dependencies , like
PreferenceValue and so on.."

Then how about compromise:

gradientButtonLookPreference: preferenceManager
<preference>
| prefDeclaration |
prefDeclaration := preferenceManager preferenceName: 'Gradient look for
buttons'
description: 'Gradient look for buttons'
type: #Boolean
default: false;
getter: #gradientButtonLook setter:
#gradientButtonLook: .

^ prefDeclaration foo bar zork.

.... etc...

In the example above, i just wanted to illustrate , that there is no
need to be dependent on global names, like PreferenceValue etc.
We could define a protocol which can be used to declare a preference,
and all methods with <preference> pragma should follow it.
a preferenceManager can be anything, can use any classes what it needs
to give user a way to define/change preferences.
Still no direct dependency between code which declaring preference and
preference management framework, except that it expects a
preferenceManager to support a certain protocol.
Post by Travis Griggs
--
Travis Griggs
Objologist
For every adage, there is an equal and contrary un-adage
--
Best regards,
Igor Stasenko AKA sig.
Igor Stasenko
2012-01-28 12:23:32 UTC
Permalink
Post by Gary Chambers
Still a dependancy (unavoidable) on whatever preferenceManager points to...
Better than direct class reference, I agree. (c.f. UIManager delegation).
A more revised variant is:

describeGradientButtonPreferende: prefDesc

prefDesc name: 'Gradient button look'
prefDesc description: 'blablabla'
....
prefDesc unusualMessage: foo with: bar


It is simple to put in prefDesc class, whatever it may be, the DNU
handler which will simply ignore all unknown messages,
and maybe note that it may be not fully/validly described:

PredDescClass>>doesNotUnderstand: aMessage
self usingUnknownProtocol: true.
^ self

Dependency is unavoidable ( use a specific protocol to define preference)
but unlike the pragmas, which statically defining preference , and
obviously using another protocol for it,
we sending a messages to a real object and hence could use the
strengths of Smalltalk.
Post by Gary Chambers
Regards, Gary
To: "The general-purpose Squeak developers list"
Sent: Friday, March 06, 2009 7:25 PM
Subject: Re: [squeak-dev] Re: [ANN] Preference pragmas
- Show quoted text -
Post by Travis Griggs
Post by Alain Plantec
Hi Andreas,
Post by Andreas Raab
Alain's implementation of preferences is an improvement on the current
preference system but it is effectively replacing one set of dependencies
with a different set of dependencies. Where previously Preferences would be
registered and stored via Preferences addPreference:... in Alain's approach
...
Post by Andreas Raab
gradientButtonLook
<preference>
^ GradientButtonLook
ifNil: [GradientButtonLook := PreferenceValue
name: 'Gradient look for buttons'
description: 'Gradient look for buttons'
parent: #uiPreferenceNode
type: #Boolean
default: false]
In other words, a dependency (to either PreferenceNode, PreferenceValue,
RangePreferenceValue, MultiplePreferenceValue etc) is created and stored
client-side.
<rest snipped>
I've just been lurking, didn't even see the front of this thread. But when I
saw the lengthy method tag (pragma) in the previous post, it caught my
attention. And now, at least part of this discussion seems to be on how much
meta data to put in the method tag.
In my experience, you should use the strength of Smalltalk to build objects
and send messages between them to the utmost here. You should use method
tags (pragmas) to provide only enough information to help you discover
*which* methods to send for a particular service.
I wrote about what I see as a long running fiasco with the VisualWorks menu
pragmas and how that "syntax" got completely out of control. And how we have
moved beyond it.
http://www.cincomsmalltalk.com/userblogs/travis/blogView?showComments=true&printTitle=Menu_Items_Are_Objects_Too&entry=3354355944
That was more than a year ago, and I still stand, more than ever, behind the
assertions made there. Having simplified the menu pragmas down to the bare
essentials of "method discovery" and put the actual code in, uh, code, has
been great. I don't see a reason Squeak/Pharoa Preferences wouldn't benefit
in the same way.
Apologies if I misunderstood the jst of this thread and am off topic.
No, your post were strictly on topic.
I read a blog post and now i think that the main argument against
"Doing this, you lose all the benefits of having a real object that
you can send real messages to. Which means you've avoided using
Smalltalks halmark strength."
"Alain's implementation of preferences is an improvement on the
current preference system but it is effectively replacing one set of
dependencies with a different set of dependencies , like
PreferenceValue and so on.."
gradientButtonLookPreference: preferenceManager
<preference>
| prefDeclaration |
prefDeclaration := preferenceManager preferenceName: 'Gradient look for buttons'
? ? ? ? ? ? ? ? ? ? description: 'Gradient look for buttons'
? ? ? ? ? ? ? ? ? ? type: #Boolean
? ? ? ? ? ? ? ? ? ? default: false;
.
^ prefDeclaration foo bar zork.
? ?.... etc...
In the example above, i just wanted to illustrate , that there is no
need to be dependent on global names, like PreferenceValue etc.
We could define a protocol which can be used to declare a preference,
and all methods with <preference> pragma should follow it.
a preferenceManager can be anything, can use any classes what it needs
to give user a way to define/change preferences.
Still no direct dependency between code which declaring preference and
preference management framework, except that it expects a
preferenceManager to support a certain protocol.
Post by Travis Griggs
--
Travis Griggs
Objologist
For every adage, there is an equal and contrary un-adage
--
Best regards,
Igor Stasenko AKA sig.
--
Best regards,
Igor Stasenko AKA sig.
Igor Stasenko
2012-01-28 12:23:32 UTC
Permalink
Post by Igor Stasenko
Post by Gary Chambers
Still a dependancy (unavoidable) on whatever preferenceManager points to...
Better than direct class reference, I agree. (c.f. UIManager delegation).
describeGradientButtonPreferende: prefDesc
<preference> "forgot it - should be here :)"
Post by Igor Stasenko
?prefDesc name: 'Gradient button look'
?prefDesc description: 'blablabla'
?....
?prefDesc unusualMessage: foo with: bar
It is simple to put in prefDesc class, whatever it may be, the DNU
handler which will simply ignore all unknown messages,
PredDescClass>>doesNotUnderstand: aMessage
? self usingUnknownProtocol: true.
?^ self
Dependency is unavoidable ( use a specific protocol to define preference)
but unlike the pragmas, which statically defining preference , and
obviously using another protocol for it,
we sending a messages to a real object and hence could use the
strengths of Smalltalk.
Post by Gary Chambers
Regards, Gary
To: "The general-purpose Squeak developers list"
Sent: Friday, March 06, 2009 7:25 PM
Subject: Re: [squeak-dev] Re: [ANN] Preference pragmas
- Show quoted text -
- Show quoted text -
Post by Gary Chambers
Post by Travis Griggs
Post by Alain Plantec
Hi Andreas,
Post by Andreas Raab
Alain's implementation of preferences is an improvement on the current
preference system but it is effectively replacing one set of dependencies
with a different set of dependencies. Where previously Preferences would be
registered and stored via Preferences addPreference:... in Alain's approach
...
Post by Andreas Raab
gradientButtonLook
<preference>
^ GradientButtonLook
ifNil: [GradientButtonLook := PreferenceValue
name: 'Gradient look for buttons'
description: 'Gradient look for buttons'
parent: #uiPreferenceNode
type: #Boolean
default: false]
In other words, a dependency (to either PreferenceNode, PreferenceValue,
RangePreferenceValue, MultiplePreferenceValue etc) is created and stored
client-side.
<rest snipped>
I've just been lurking, didn't even see the front of this thread. But when I
saw the lengthy method tag (pragma) in the previous post, it caught my
attention. And now, at least part of this discussion seems to be on how much
meta data to put in the method tag.
In my experience, you should use the strength of Smalltalk to build objects
and send messages between them to the utmost here. You should use method
tags (pragmas) to provide only enough information to help you discover
*which* methods to send for a particular service.
I wrote about what I see as a long running fiasco with the VisualWorks menu
pragmas and how that "syntax" got completely out of control. And how we have
moved beyond it.
http://www.cincomsmalltalk.com/userblogs/travis/blogView?showComments=true&printTitle=Menu_Items_Are_Objects_Too&entry=3354355944
That was more than a year ago, and I still stand, more than ever, behind the
assertions made there. Having simplified the menu pragmas down to the bare
essentials of "method discovery" and put the actual code in, uh, code, has
been great. I don't see a reason Squeak/Pharoa Preferences wouldn't benefit
in the same way.
Apologies if I misunderstood the jst of this thread and am off topic.
No, your post were strictly on topic.
I read a blog post and now i think that the main argument against
"Doing this, you lose all the benefits of having a real object that
you can send real messages to. Which means you've avoided using
Smalltalks halmark strength."
"Alain's implementation of preferences is an improvement on the
current preference system but it is effectively replacing one set of
dependencies with a different set of dependencies , like
PreferenceValue and so on.."
gradientButtonLookPreference: preferenceManager
<preference>
| prefDeclaration |
prefDeclaration := preferenceManager preferenceName: 'Gradient look for buttons'
? ? ? ? ? ? ? ? ? ? description: 'Gradient look for buttons'
? ? ? ? ? ? ? ? ? ? type: #Boolean
? ? ? ? ? ? ? ? ? ? default: false;
.
^ prefDeclaration foo bar zork.
? ?.... etc...
In the example above, i just wanted to illustrate , that there is no
need to be dependent on global names, like PreferenceValue etc.
We could define a protocol which can be used to declare a preference,
and all methods with <preference> pragma should follow it.
a preferenceManager can be anything, can use any classes what it needs
to give user a way to define/change preferences.
Still no direct dependency between code which declaring preference and
preference management framework, except that it expects a
preferenceManager to support a certain protocol.
Post by Travis Griggs
--
Travis Griggs
Objologist
For every adage, there is an equal and contrary un-adage
--
Best regards,
Igor Stasenko AKA sig.
--
Best regards,
Igor Stasenko AKA sig.
--
Best regards,
Igor Stasenko AKA sig.
Gary Chambers
2012-01-28 12:23:32 UTC
Permalink
----- Original Message -----
From: "Igor Stasenko" <***@gmail.com>
To: "The general-purpose Squeak developers list"
<squeak-***@lists.squeakfoundation.org>
Sent: Friday, March 06, 2009 7:52 PM
Subject: Re: [squeak-dev] Re: [ANN] Preference pragmas
Post by Gary Chambers
Still a dependancy (unavoidable) on whatever preferenceManager points to...
Better than direct class reference, I agree. (c.f. UIManager delegation).
A more revised variant is:

describeGradientButtonPreferende: prefDesc

prefDesc name: 'Gradient button look'
prefDesc description: 'blablabla'
....
prefDesc unusualMessage: foo with: bar


It is simple to put in prefDesc class, whatever it may be, the DNU
handler which will simply ignore all unknown messages,
and maybe note that it may be not fully/validly described:

PredDescClass>>doesNotUnderstand: aMessage
self usingUnknownProtocol: true.
^ self

Dependency is unavoidable ( use a specific protocol to define preference)
but unlike the pragmas, which statically defining preference , and
obviously using another protocol for it,
we sending a messages to a real object and hence could use the
strengths of Smalltalk.


****

I agree, that's why I think Alain's implementation is better... OO is all
about modelling things rather than flatly describing things in a syntactic
sense... There is a concept of "preference" to it should be modelled.
Post by Gary Chambers
Regards, Gary
To: "The general-purpose Squeak developers list"
Sent: Friday, March 06, 2009 7:25 PM
Subject: Re: [squeak-dev] Re: [ANN] Preference pragmas
- Show quoted text -
Post by Travis Griggs
Post by Alain Plantec
Hi Andreas,
Post by Andreas Raab
Alain's implementation of preferences is an improvement on the current
preference system but it is effectively replacing one set of dependencies
with a different set of dependencies. Where previously Preferences
would
be
registered and stored via Preferences addPreference:... in Alain's approach
...
Post by Andreas Raab
gradientButtonLook
<preference>
^ GradientButtonLook
ifNil: [GradientButtonLook := PreferenceValue
name: 'Gradient look for buttons'
description: 'Gradient look for buttons'
parent: #uiPreferenceNode
type: #Boolean
default: false]
In other words, a dependency (to either PreferenceNode,
PreferenceValue,
RangePreferenceValue, MultiplePreferenceValue etc) is created and stored
client-side.
<rest snipped>
I've just been lurking, didn't even see the front of this thread. But
when
I
saw the lengthy method tag (pragma) in the previous post, it caught my
attention. And now, at least part of this discussion seems to be on how much
meta data to put in the method tag.
In my experience, you should use the strength of Smalltalk to build objects
and send messages between them to the utmost here. You should use method
tags (pragmas) to provide only enough information to help you discover
*which* methods to send for a particular service.
I wrote about what I see as a long running fiasco with the VisualWorks menu
pragmas and how that "syntax" got completely out of control. And how we have
moved beyond it.
http://www.cincomsmalltalk.com/userblogs/travis/blogView?showComments=true&printTitle=Menu_Items_Are_Objects_Too&entry=3354355944
That was more than a year ago, and I still stand, more than ever, behind the
assertions made there. Having simplified the menu pragmas down to the bare
essentials of "method discovery" and put the actual code in, uh, code, has
been great. I don't see a reason Squeak/Pharoa Preferences wouldn't benefit
in the same way.
Apologies if I misunderstood the jst of this thread and am off topic.
No, your post were strictly on topic.
I read a blog post and now i think that the main argument against
"Doing this, you lose all the benefits of having a real object that
you can send real messages to. Which means you've avoided using
Smalltalks halmark strength."
"Alain's implementation of preferences is an improvement on the
current preference system but it is effectively replacing one set of
dependencies with a different set of dependencies , like
PreferenceValue and so on.."
gradientButtonLookPreference: preferenceManager
<preference>
| prefDeclaration |
prefDeclaration := preferenceManager preferenceName: 'Gradient look for buttons'
description: 'Gradient look for buttons'
type: #Boolean
default: false;
.
^ prefDeclaration foo bar zork.
.... etc...
In the example above, i just wanted to illustrate , that there is no
need to be dependent on global names, like PreferenceValue etc.
We could define a protocol which can be used to declare a preference,
and all methods with <preference> pragma should follow it.
a preferenceManager can be anything, can use any classes what it needs
to give user a way to define/change preferences.
Still no direct dependency between code which declaring preference and
preference management framework, except that it expects a
preferenceManager to support a certain protocol.
Post by Travis Griggs
--
Travis Griggs
Objologist
For every adage, there is an equal and contrary un-adage
--
Best regards,
Igor Stasenko AKA sig.
--
Best regards,
Igor Stasenko AKA sig.
Matthew Fulmer
2012-01-28 12:23:32 UTC
Permalink
Post by Igor Stasenko
Post by Andreas Raab
gradientButtonLook
  <preference>
  ^ GradientButtonLook
      ifNil: [GradientButtonLook := PreferenceValue
                      name: 'Gradient look for buttons'
                      description: 'Gradient look for buttons'
                      parent: #uiPreferenceNode
                      type: #Boolean
                      default: false]
"Alain's implementation of preferences is an improvement on the
current preference system but it is effectively replacing one set of
dependencies with a different set of dependencies , like
PreferenceValue and so on.."
gradientButtonLookPreference: preferenceManager
<preference>
| prefDeclaration |
prefDeclaration := preferenceManager preferenceName: 'Gradient look for buttons'
description: 'Gradient look for buttons'
type: #Boolean
default: false;
getter: #gradientButtonLook setter: #gradientButtonLook: .
^ prefDeclaration foo bar zork.
There is nothing wrong with a direct class refference. If
PreferenceValue is not loaded, and you reference
PreferenceValue, it will bind to Undeclared until such time as
you load PreferenceValue into your image. In the meantime,
nobody will be calling the method, as the method is only useful
for preferences to call, and it is not loaded.

So, no need to make a big fuss about direct class references.

The dependencies we do want to avoid are storing the value of
the preferences *inside* the global Preferences, rather than
using it as a view into the system. Because then Preferences are
stateful, and you will lose data if you unload them.

The whole point of this excercise is to make Preferences
stateless.
--
Matthew Fulmer -- http://mtfulmer.wordpress.com/
Edgar J. De Cleene
2012-01-28 12:23:28 UTC
Permalink
Post by Andreas Raab
PS. I'm only posting this to Squeak-dev since I have a distinct feeling
that my comments wouldn't be very welcome on the Pharo list. Please feel
free to forward it and correct me if I am mistaken.
I trust you and your implementation should go to current .image ASAP.
If at some point some guy of different secta come with a better code, we don
reject for "heretic" =:)

Edgar
Andreas Raab
2012-01-28 12:23:28 UTC
Permalink
Post by Edgar J. De Cleene
I trust you and your implementation should go to current .image ASAP.
If at some point some guy of different secta come with a better code, we don
reject for "heretic" =:)
To the contrary. Let's give collaboration a chance. It would be stupid
if we ended up with just enough difference to make us incompatible at
such a superficial level. At the very least we should be waiting for a
week or two to see if there's any reaction from the Pharo folks. Even if
there is no reaction we should try to make it compatible at the
interface (pragma) level. I'd be willing to do at least that but I'd
need to know what their pragma spec actually looks like (can anyone
subscribed to Pharo post an example or point me to ti?)

Cheers,
- Andreas
Igor Stasenko
2012-01-28 12:23:28 UTC
Permalink
http://n2.nabble.com/Preference-refactoring-again-tt2403814.html
Post by Edgar J. De Cleene
I trust you and your implementation should go to current .image ASAP.
If at some point some guy of different secta come with a better code, we don
reject for "heretic" =:)
To the contrary. Let's give collaboration a chance. It would be stupid if we
ended up with just enough difference to make us incompatible at such a
superficial level. At the very least we should be waiting for a week or two
to see if there's any reaction from the Pharo folks. Even if there is no
reaction we should try to make it compatible at the interface (pragma)
level. I'd be willing to do at least that but I'd need to know what their
pragma spec actually looks like (can anyone subscribed to Pharo post an
example or point me to ti?)
Cheers,
?- Andreas
--
Best regards,
Igor Stasenko AKA sig.
Andreas Raab
2012-01-28 12:23:28 UTC
Permalink
Post by Igor Stasenko
http://n2.nabble.com/Preference-refactoring-again-tt2403814.html
Oh. That is indeed quite similar. Two comments:

* There is really no need to specify a #setter: in the pragma - the name
of the setter can be derived from the getter (read-only preferences
would be pointless, no? ;-)

* There is really no need to specify the default explicitly - it can be
derived from the current value when the preference is registered.

Other than that it looks good. It would be trivial to adjust my version
to use this pragma pattern but I would still prefer it if we could
collaborate on the implementation.

Cheers,
- Andreas
Post by Igor Stasenko
Post by Edgar J. De Cleene
I trust you and your implementation should go to current .image ASAP.
If at some point some guy of different secta come with a better code, we don
reject for "heretic" =:)
To the contrary. Let's give collaboration a chance. It would be stupid if we
ended up with just enough difference to make us incompatible at such a
superficial level. At the very least we should be waiting for a week or two
to see if there's any reaction from the Pharo folks. Even if there is no
reaction we should try to make it compatible at the interface (pragma)
level. I'd be willing to do at least that but I'd need to know what their
pragma spec actually looks like (can anyone subscribed to Pharo post an
example or point me to ti?)
Cheers,
- Andreas
Cédrick Béler
2012-01-28 12:23:29 UTC
Permalink
Post by Igor Stasenko
http://n2.nabble.com/Preference-refactoring-again-tt2403814.html
there's only this suggestion:
http://n2.nabble.com/A-few-more-ideas-about-preferences-td2428084.html

--
C?drick
Edgar J. De Cleene
2012-01-28 12:23:30 UTC
Permalink
Post by Keith Hodges
Post by Andreas Raab
In Alain's version this would not be possible without actually
changing code since it is directly coupled to a particular preference
class and API.
Bottom line: I think my approach is a necessity before Alain's
preference implementation can be usefully deployed. It allows us to
define preferences without introducing dependencies to specific
implementations, while allowing different implementations to discover
the same preferences.
I hope this makes the conceptual difference clear.
Cheers,
- Andreas
Sounds good,
I will definitely be adopting this in a few packages.
Keith
I beg you do a .cs and put in the updates with all Andreas say about this
and about Announcements.

Squeak newbies like hit the updates button and have the up to day
3.10.x.nnnn.image

Edgar
Andreas Raab
2012-01-28 12:23:34 UTC
Permalink
Folks -

After the flurry of replies to something that was intended just to be a
small goodie I decided to allow the situation to calm down a little then
sit and think about what a good way to go forward is.

I think of all the things that were said, Travis comment was the most
relevant as far as practical applicability is concerned. I certainly do
see the problem of proliferation that he's raising (it has been a
problem in other situations that I've been in). However, after having an
extensive lunch discussion with Eliot on Friday about the use of
VisualWorks menu pragmas and what went wrong with them, I think there
are two options to address this problem and I am planning to use both:

1) Restrain yourself. One of the problems with VW menu pragmas appears
to be the complexity of menu specifications (which is understandable).
However, for preferences handling I think it is fair to provide a
solution that covers 98% of the common cases and give users that require
the additional 2% to bind to the preferences implementation directly
(this wouldn't be an option for the VW menu pragma problem since it is
used differently than what we're talking about for preferences).

2) Don't permutate selectors. It is natural for us to extend the
selector if we need a variant or an additional argument since this is
the way you do it in Smalltalk. However, with pragmas you can have
additional pragmas that specify extra information that are not in the
base pragma. For example, instead of having a variant:

<preference: 'Slider Value'
category: 'Slider'
description: 'The default slider value'
type: #Number
min: 0
max: 100>

one can do this:

<preference: 'Slider Value'
category: 'Slider'
description: 'The default slider value'
type: #Number>
<preferenceRangeMin: 0 max: 100>

This leaves the base pragma intact while being able to specify "extended
attributes" for cases that aren't covered.

Another insightful issue in the discussion with Eliot is that he pointed
out that in his perspective pragmas are "executable" meaning that there
should be a method that has the signature of the pragma and that handles
whatever the pragma is supposed to describe. The obvious advantage here
is that by using "senders of" you can find the users of a pragma and by
looking at "implementors of" you can find the handlers for a pragma.

I fully agree with Eliot on this and will change the implementation such
that there is a findable #preference:category:description:type: method.

This brings me to my conclusions: After all that's been said I'm more
than ever in favor of having a simple, straightforward menu pragma which
by design doesn't try to be everything for everybody. It should allow us
to cover the basic cases that make up 98% of all preferences but no
more. Consequently, I am proposing that the simple preferences
implementation should handle the following types: Boolean, Numbers,
Strings, Colors, Fonts, and choices (i.e, an element of a literal list)
and no more.

This will cover all existing cases in Squeak today. I am at this point
against proposing any additional attributes, but I will make a few
proposals about how to handle specific issues:

1) Ranges. Ranges should be handled by the accessor method. In other
words, instead of specifying a range in the pragma you would implement this:

spyPriority
<preference: 'Spy Priority'
category: 'Debug'
description: 'Sets the priority for MessageTally'
type: #Number>

spyPriority: aNumber
SpyPriority := aNumber truncated min: 79 max: 40.

This is a natural and straightforward guard that avoids complicating the
preference specification.

2) Nested Categories. Nested categories could be specified by using a
period as delimiter, for example:

spyPriority
<preference: 'Spy Priority'
category: 'Debug.MessageTally'
description: 'Sets the priority for MessageTally'
type: #Number>

3) Multiple Categories. Multiple categories can already be specified by
putting in the pragma twice in its respective categories. An alternative
to this could be to allow providing a literal array of categories, for
example:

spyPriority
<preference: 'Spy Priority'
category: #('Debug' 'MessageTally')
description: 'Sets the priority for MessageTally'
type: #Number>

None of the latter two are implemented at this point, and I am not
planning to implement them any time soon so let's not get hung up with a
discussion of the particular benefits of either approach. They are here
to show that some features could be easily added even within the
restrained approach provided here.

Anything that cannot be handled in the simple pragma scope described
here is by definition out of scope for the simple preference pragma. If
you need more complexity, you will require a specific preference
implementation such as Alain's.

Which brings me to my final comments here: I think that combining both
approaches, a simple preference pragma with a more fully developed
preference implementation is really the way forward since it allows us
to rewrite all the current uses in a way that will be forward compatible
with Alain's (or someone else's) implementation.

I will update my implementation to comply with the above rules ASAP.

Cheers,
- Andreas
Gary Chambers
2012-01-28 12:23:34 UTC
Permalink
----- Original Message -----
From: "Andreas Raab" <***@gmx.de>
To: "The general-purpose Squeak developers list"
<squeak-***@lists.squeakfoundation.org>
Sent: Sunday, March 08, 2009 9:10 PM
Subject: [squeak-dev] Re: [ANN] Preference pragmas
Post by Andreas Raab
spyPriority
<preference: 'Spy Priority'
category: 'Debug'
description: 'Sets the priority for MessageTally'
type: #Number>
spyPriority: aNumber
SpyPriority := aNumber truncated min: 79 max: 40.
This is a natural and straightforward guard that avoids complicating the
preference specification.
The use of "extended" pragmas is interesting, although, to my mind it
doesn't address the problem/benefit of complex preference values
(non-literal).

As for the value guard, good, but the ranges etc. are not exposed to
potential tools (would be nice to NOT be able to input 99, for instance).

I think, at this stage, I still believe the "modelling of a preference"
approach more flexible.

Thoughts welcome, naturally.

Regards, Gary.
Andreas Raab
2012-01-28 12:23:34 UTC
Permalink
Post by Gary Chambers
The use of "extended" pragmas is interesting, although, to my mind it
doesn't address the problem/benefit of complex preference values
(non-literal).
As for the value guard, good, but the ranges etc. are not exposed to
potential tools (would be nice to NOT be able to input 99, for instance).
I think, at this stage, I still believe the "modelling of a preference"
approach more flexible.
I agree with this statement. It is more flexible to model the preference
explicitly. And I am not proposing to make the preference pragma achieve
that level of flexibility. What I'm proposing is to keep the pragma as
simple as possible, use it in the cases where it's useful and model the
preference explicitly if more flexibility is required.

This way, the dependency on a specific preference implementation will be
greatly reduced and for many uses preferences can be added to low-level
code without introducing a dependency on the implementation. Plus it
makes shipping preferences between implementations reasonably easy; much
of the code that would otherwise be incompatible between Pharo and
Squeak (and beyond, for example VW) can be compatible.

Cheers,
- Andreas
Gary Chambers
2012-01-28 12:23:35 UTC
Permalink
Indeed, I see the point you are making.

I just have a "feeling" that making this as restrictive will mean we'll be
having the same discussion soon again!
Always tricky to get any decisions made without a solution that satisfies
all viewpoints...

What I will say in favour of David's work is that it is extensible and, like
your approach, deals with the localisation vs. general kackness that is the
current situation.

I could live with "extension methods" on a Preference class, I think
(probably)... just a bit nasty with it dynamically compiling code etc.

We should all discuss some more, perhaps, to get the best solution we can,
given that this is quite fundamental (Squeakers are *used* to having
choice...).

Regards, Gary

----- Original Message -----
From: "Andreas Raab" <***@gmx.de>
To: "The general-purpose Squeak developers list"
<squeak-***@lists.squeakfoundation.org>
Sent: Monday, March 09, 2009 1:40 AM
Subject: [squeak-dev] Re: [ANN] Preference pragmas
Post by Andreas Raab
Post by Gary Chambers
The use of "extended" pragmas is interesting, although, to my mind it
doesn't address the problem/benefit of complex preference values
(non-literal).
As for the value guard, good, but the ranges etc. are not exposed to
potential tools (would be nice to NOT be able to input 99, for instance).
I think, at this stage, I still believe the "modelling of a preference"
approach more flexible.
I agree with this statement. It is more flexible to model the preference
explicitly. And I am not proposing to make the preference pragma achieve
that level of flexibility. What I'm proposing is to keep the pragma as
simple as possible, use it in the cases where it's useful and model the
preference explicitly if more flexibility is required.
This way, the dependency on a specific preference implementation will be
greatly reduced and for many uses preferences can be added to low-level
code without introducing a dependency on the implementation. Plus it makes
shipping preferences between implementations reasonably easy; much of the
code that would otherwise be incompatible between Pharo and Squeak (and
beyond, for example VW) can be compatible.
Cheers,
- Andreas
Andreas Raab
2012-01-28 12:23:35 UTC
Permalink
Hi Gary -

Let me throw in one additional thought: I'm not sure how one would deal
with migration in Alain's case (I don't know David's work; I'm assuming
you misspoke, but if not please point me to it). One of the issues is
that there are currently some 694 (!) references to Preferences in a
3.10.2 image. There will be more in external code.

One of the advantages of using a pragma for the simple cases is that we
can start the migration today, without having sorted out all the details
for the next-gen preferences implementation. People who want their code
to work both in Squeak and Pharo can start doing this as soon as have a
reasonable implementation for both (which I am willing to provide). I
also don't expect the migration to be quick as there will be discussion
where certain preferences should live etc.

A drop-dead conversion of saying "the day we load the new preferences
implementation all old code will be broken" just won't work. So having a
way that we know will be forward-compatible strikes me as absolutely
necessary for any migration process. This is what I meant when I was
saying that I think having something that abstracts from the preference
implementation is absolutely necessary before we can consider adopting
an alternative.

Cheers,
- Andreas
Post by Gary Chambers
Indeed, I see the point you are making.
I just have a "feeling" that making this as restrictive will mean we'll
be having the same discussion soon again!
Always tricky to get any decisions made without a solution that
satisfies all viewpoints...
What I will say in favour of David's work is that it is extensible and,
like your approach, deals with the localisation vs. general kackness
that is the current situation.
I could live with "extension methods" on a Preference class, I think
(probably)... just a bit nasty with it dynamically compiling code etc.
We should all discuss some more, perhaps, to get the best solution we
can, given that this is quite fundamental (Squeakers are *used* to
having choice...).
Regards, Gary
To: "The general-purpose Squeak developers list"
Sent: Monday, March 09, 2009 1:40 AM
Subject: [squeak-dev] Re: [ANN] Preference pragmas
Post by Andreas Raab
Post by Gary Chambers
The use of "extended" pragmas is interesting, although, to my mind it
doesn't address the problem/benefit of complex preference values
(non-literal).
As for the value guard, good, but the ranges etc. are not exposed to
potential tools (would be nice to NOT be able to input 99, for instance).
I think, at this stage, I still believe the "modelling of a
preference" approach more flexible.
I agree with this statement. It is more flexible to model the
preference explicitly. And I am not proposing to make the preference
pragma achieve that level of flexibility. What I'm proposing is to
keep the pragma as simple as possible, use it in the cases where it's
useful and model the preference explicitly if more flexibility is
required.
This way, the dependency on a specific preference implementation will
be greatly reduced and for many uses preferences can be added to
low-level code without introducing a dependency on the implementation.
Plus it makes shipping preferences between implementations reasonably
easy; much of the code that would otherwise be incompatible between
Pharo and Squeak (and beyond, for example VW) can be compatible.
Cheers,
- Andreas
Gary Chambers
2012-01-28 12:23:35 UTC
Permalink
Yes, was Alain (sorry there...).

Any of the proposed strategies are, I think, in a "moving forward" sense.
Each approach doesn't deal with migration of the existing state of play,
that is, I believe, taken for-granted as something that will be migrated at
some point.

Either proposal has the "advantage" of moving forward, pragmas one way, or
the other, or something entirely different. Let us get the best possible
implementation of the concept of preferences sorted between us before even
thinking of the migration.

Nothing is finalised yet, but, I'm not convinced by the pragmas-only
approach.

Just as a "fun" expression... "when is a preference not a preference" (when
it is a pragma seems the obvious answer to me).
Nothing wrong with using pragmas to identify things though, I feel.

Regards, Gary

----- Original Message -----
From: "Andreas Raab" <***@gmx.de>
To: "The general-purpose Squeak developers list"
<squeak-***@lists.squeakfoundation.org>
Sent: Monday, March 09, 2009 2:19 AM
Subject: [squeak-dev] Re: [ANN] Preference pragmas
Post by Andreas Raab
Hi Gary -
Let me throw in one additional thought: I'm not sure how one would deal
with migration in Alain's case (I don't know David's work; I'm assuming
you misspoke, but if not please point me to it). One of the issues is that
there are currently some 694 (!) references to Preferences in a 3.10.2
image. There will be more in external code.
One of the advantages of using a pragma for the simple cases is that we
can start the migration today, without having sorted out all the details
for the next-gen preferences implementation. People who want their code to
work both in Squeak and Pharo can start doing this as soon as have a
reasonable implementation for both (which I am willing to provide). I also
don't expect the migration to be quick as there will be discussion where
certain preferences should live etc.
A drop-dead conversion of saying "the day we load the new preferences
implementation all old code will be broken" just won't work. So having a
way that we know will be forward-compatible strikes me as absolutely
necessary for any migration process. This is what I meant when I was
saying that I think having something that abstracts from the preference
implementation is absolutely necessary before we can consider adopting an
alternative.
Cheers,
- Andreas
Post by Gary Chambers
Indeed, I see the point you are making.
I just have a "feeling" that making this as restrictive will mean we'll
be having the same discussion soon again!
Always tricky to get any decisions made without a solution that satisfies
all viewpoints...
What I will say in favour of David's work is that it is extensible and,
like your approach, deals with the localisation vs. general kackness that
is the current situation.
I could live with "extension methods" on a Preference class, I think
(probably)... just a bit nasty with it dynamically compiling code etc.
We should all discuss some more, perhaps, to get the best solution we
can, given that this is quite fundamental (Squeakers are *used* to having
choice...).
Regards, Gary
To: "The general-purpose Squeak developers list"
Sent: Monday, March 09, 2009 1:40 AM
Subject: [squeak-dev] Re: [ANN] Preference pragmas
Post by Andreas Raab
Post by Gary Chambers
The use of "extended" pragmas is interesting, although, to my mind it
doesn't address the problem/benefit of complex preference values
(non-literal).
As for the value guard, good, but the ranges etc. are not exposed to
potential tools (would be nice to NOT be able to input 99, for instance).
I think, at this stage, I still believe the "modelling of a preference"
approach more flexible.
I agree with this statement. It is more flexible to model the preference
explicitly. And I am not proposing to make the preference pragma achieve
that level of flexibility. What I'm proposing is to keep the pragma as
simple as possible, use it in the cases where it's useful and model the
preference explicitly if more flexibility is required.
This way, the dependency on a specific preference implementation will be
greatly reduced and for many uses preferences can be added to low-level
code without introducing a dependency on the implementation. Plus it
makes shipping preferences between implementations reasonably easy; much
of the code that would otherwise be incompatible between Pharo and
Squeak (and beyond, for example VW) can be compatible.
Cheers,
- Andreas
Andreas Raab
2012-01-28 12:23:36 UTC
Permalink
Hi -

Yet another update on preference pragmas [1]. The main difference to
previous versions is that it now fetches the value straight from the
source so that manipulations of the class var are reflected accordingly.
It also provides the #preference:category:description:type: method which
allows you to browse senders and implementors of said pragma.

[1] http://bugs.squeak.org/view.php?id=7306

To me, this feels like a reasonably simple choice to go with.

Cheers,
- Andreas

Bert Freudenberg
2012-01-28 12:23:35 UTC
Permalink
Post by Gary Chambers
Indeed, I see the point you are making.
I just have a "feeling" that making this as restrictive will mean
we'll be having the same discussion soon again!
Always tricky to get any decisions made without a solution that
satisfies all viewpoints...
What I will say in favour of David's work is that it is extensible
and, like your approach, deals with the localisation vs. general
kackness that is the current situation.
Now while even urbandictionary.com does not know the term "kackness" I
agree that I'd value a preference system that allows localization much
higher than one that does not.

- Bert -
Post by Gary Chambers
I could live with "extension methods" on a Preference class, I think
(probably)... just a bit nasty with it dynamically compiling code etc.
We should all discuss some more, perhaps, to get the best solution
we can, given that this is quite fundamental (Squeakers are *used*
to having choice...).
Regards, Gary
----- Original Message ----- From: "Andreas Raab"
Sent: Monday, March 09, 2009 1:40 AM
Subject: [squeak-dev] Re: [ANN] Preference pragmas
Post by Andreas Raab
Post by Gary Chambers
The use of "extended" pragmas is interesting, although, to my mind
it doesn't address the problem/benefit of complex preference
values (non-literal).
As for the value guard, good, but the ranges etc. are not exposed
to potential tools (would be nice to NOT be able to input 99, for
instance).
I think, at this stage, I still believe the "modelling of a
preference" approach more flexible.
I agree with this statement. It is more flexible to model the
preference explicitly. And I am not proposing to make the
preference pragma achieve that level of flexibility. What I'm
proposing is to keep the pragma as simple as possible, use it in
the cases where it's useful and model the preference explicitly if
more flexibility is required.
This way, the dependency on a specific preference implementation
will be greatly reduced and for many uses preferences can be added
to low-level code without introducing a dependency on the
implementation. Plus it makes shipping preferences between
implementations reasonably easy; much of the code that would
otherwise be incompatible between Pharo and Squeak (and beyond, for
example VW) can be compatible.
Cheers,
- Andreas
Julian Fitzell
2012-01-28 12:23:35 UTC
Permalink
Post by Bert Freudenberg
Now while even urbandictionary.com does not know the term "kackness"
Not one I've heard either, but my brain parses it as being a
derivative form of caca:
http://www.urbandictionary.com/define.php?term=caca

Julian
Terry Raymond
2012-01-28 12:23:35 UTC
Permalink
Keep in mind that pragmas are operated on and do not have to
become message selectors themselves.

You can reduce the number of selector permutations if you
do not use the pragma symbol as a single selector, but use
the first keyword part to detect the pragma and the
additional parts as separate parameter arguments.
Post by Andreas Raab
<preference: 'Slider Value'
category: 'Slider'
description: 'The default slider value'
type: #Number
min: 0
max: 100>
When you do a pragma search you would look for the pattern
'preference:*'

If you try to use multiple pragmas to set additional parameters
you may make it harder to use the pragmas in a different manner.
In VW sometimes multiple menu pragmas are used in one method
to make the menu command appear in multiple menus.

Terry

===========================================================
Terry Raymond
Crafted Smalltalk
80 Lazywood Ln.
Tiverton, RI 02878
(401) 624-4517 ***@craftedsmalltalk.com
<http://www.craftedsmalltalk.com>
===========================================================
Post by Andreas Raab
-----Original Message-----
Sent: Sunday, March 08, 2009 5:10 PM
To: The general-purpose Squeak developers list
Subject: [squeak-dev] Re: [ANN] Preference pragmas
Folks -
After the flurry of replies to something that was intended just to be a
small goodie I decided to allow the situation to calm down a little then
sit and think about what a good way to go forward is.
I think of all the things that were said, Travis comment was the most
relevant as far as practical applicability is concerned. I certainly do
see the problem of proliferation that he's raising (it has been a
problem in other situations that I've been in). However, after having an
extensive lunch discussion with Eliot on Friday about the use of
VisualWorks menu pragmas and what went wrong with them, I think there
1) Restrain yourself. One of the problems with VW menu pragmas appears
to be the complexity of menu specifications (which is understandable).
However, for preferences handling I think it is fair to provide a
solution that covers 98% of the common cases and give users that require
the additional 2% to bind to the preferences implementation directly
(this wouldn't be an option for the VW menu pragma problem since it is
used differently than what we're talking about for preferences).
2) Don't permutate selectors. It is natural for us to extend the
selector if we need a variant or an additional argument since this is
the way you do it in Smalltalk. However, with pragmas you can have
additional pragmas that specify extra information that are not in the
<preference: 'Slider Value'
category: 'Slider'
description: 'The default slider value'
type: #Number
min: 0
max: 100>
<preference: 'Slider Value'
category: 'Slider'
description: 'The default slider value'
type: #Number>
<preferenceRangeMin: 0 max: 100>
This leaves the base pragma intact while being able to specify "extended
attributes" for cases that aren't covered.
Another insightful issue in the discussion with Eliot is that he pointed
out that in his perspective pragmas are "executable" meaning that there
should be a method that has the signature of the pragma and that handles
whatever the pragma is supposed to describe. The obvious advantage here
is that by using "senders of" you can find the users of a pragma and by
looking at "implementors of" you can find the handlers for a pragma.
I fully agree with Eliot on this and will change the implementation such
that there is a findable #preference:category:description:type: method.
This brings me to my conclusions: After all that's been said I'm more
than ever in favor of having a simple, straightforward menu pragma which
by design doesn't try to be everything for everybody. It should allow us
to cover the basic cases that make up 98% of all preferences but no
more. Consequently, I am proposing that the simple preferences
implementation should handle the following types: Boolean, Numbers,
Strings, Colors, Fonts, and choices (i.e, an element of a literal list)
and no more.
This will cover all existing cases in Squeak today. I am at this point
against proposing any additional attributes, but I will make a few
1) Ranges. Ranges should be handled by the accessor method. In other
spyPriority
<preference: 'Spy Priority'
category: 'Debug'
description: 'Sets the priority for MessageTally'
type: #Number>
spyPriority: aNumber
SpyPriority := aNumber truncated min: 79 max: 40.
This is a natural and straightforward guard that avoids complicating the
preference specification.
2) Nested Categories. Nested categories could be specified by using a
spyPriority
<preference: 'Spy Priority'
category: 'Debug.MessageTally'
description: 'Sets the priority for MessageTally'
type: #Number>
3) Multiple Categories. Multiple categories can already be specified by
putting in the pragma twice in its respective categories. An alternative
to this could be to allow providing a literal array of categories, for
spyPriority
<preference: 'Spy Priority'
category: #('Debug' 'MessageTally')
description: 'Sets the priority for MessageTally'
type: #Number>
None of the latter two are implemented at this point, and I am not
planning to implement them any time soon so let's not get hung up with a
discussion of the particular benefits of either approach. They are here
to show that some features could be easily added even within the
restrained approach provided here.
Anything that cannot be handled in the simple pragma scope described
here is by definition out of scope for the simple preference pragma. If
you need more complexity, you will require a specific preference
implementation such as Alain's.
Which brings me to my final comments here: I think that combining both
approaches, a simple preference pragma with a more fully developed
preference implementation is really the way forward since it allows us
to rewrite all the current uses in a way that will be forward compatible
with Alain's (or someone else's) implementation.
I will update my implementation to comply with the above rules ASAP.
Cheers,
- Andreas
Continue reading on narkive:
Loading...