One major topic of many software systems is the configuration of the system. Typically there are APIs with key/value pairings, maybe with groups. Another way are more or less complex XML based systems accessed by specific classes for a defined part of the application.
My intention has been to provide a generic hierarchical system, easy to read and use, with a seamless integration into Smalltalk and the possibility to read and write XML. Yes, me too. *smile* But XML is not the major access language, it's only an additional feature to read and store external configurations in closed applications. My typical way to use the configuration shall be the Smalltalk API.
Result is the set of the three classes
My intention has been to provide a generic hierarchical system, easy to read and use, with a seamless integration into Smalltalk and the possibility to read and write XML. Yes, me too. *smile* But XML is not the major access language, it's only an additional feature to read and store external configurations in closed applications. My typical way to use the configuration shall be the Smalltalk API.
Result is the set of the three classes
CslConfiguration, CslConfigurationValue and CslConfigurationError. The entry class is just a wrapper with nil as superclass, passing almost all message sends to the wrapped configuration value. But it has the own message withDefault: which expects a block as argument. What is the idea behind it? Imagine an access to a configuration value that doesn't exist. The call would befoo := cfg foo withDefault: [#bar].
In this case foo would get the value #bar and the configuration value would also be set to #bar. A second call
foo := cfg foo withDefault: [#yadda].
would now still return #bar. To set it to #yadda the statement has to be
cfg foo: #yadda.
A simple get without a default should not surprise you:
foo := cfg foo.
But
CslConfiguration has no methods foo: or foo. It just uses doesNotUnderstand: to map the message to a setter or getter of an internal dictionary key. And if the key doesn't exist and a getter is called it returns a new nested CslConfiguration instance. So you can also do things likecfg database connection poolSize: 10.
even if the configuration is empty at this time. Also
CslConfiguration understands isNil, ifNil:, and ifNil:ifNotNil: and behaves like nil if is empty. So it's no problem to perform statements likecfg foo bar isNil ifTrue: [...].
As a result configuration can be setup very easy, no subclassing or similar is needed and the using classes can also define default values inside the getter statement. Static languages don't even allow the compilation. *laugh*
0 Comments:
Post a Comment