Differences
This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision Next revision Both sides next revision | ||
complexvalues [2016/09/24 08:10] dokuadmin |
complexvalues [2019/01/04 16:56] christian [Using Values] |
||
---|---|---|---|
Line 3: | Line 3: | ||
The Values package is my base library for almost everything I do. It provides Values (as opposed to Objects) which are simple, immutable objects. Values can only be created but never modified. This allows for a functional programming style and simplyfies systems, since much less state has to be maintained. Especially I like to see all structure and details (of complex values) at a glance and the ease of creating test values. | The Values package is my base library for almost everything I do. It provides Values (as opposed to Objects) which are simple, immutable objects. Values can only be created but never modified. This allows for a functional programming style and simplyfies systems, since much less state has to be maintained. Especially I like to see all structure and details (of complex values) at a glance and the ease of creating test values. | ||
- | The Smalltalk code lives in the [[storeaccess|Cincom Public Store]] as bundle **Values | + | ==== Motivation ==== |
+ | |||
+ | The project grew out of the way I model simple objects which is strongly influenced by the functional and dynamic language Lisp. I recognized a pattern and codified support infrastructure for this style. To provide the facilities, I created the class '' | ||
+ | |||
+ | With Values codified, I could write a generic printing method for values which prints them as Smalltalk source which, when evaluated, results in the same value. Values are literal. This is very useful for example and test instances as well as for writing and reading them (files or sockets). But the nicest property of this is the you can see a value with all details at a glance. | ||
+ | |||
+ | Now, I use Values for more than 10 years and I cannot do without it anymore. Most of the classes I define are Values. Objects are used for the " | ||
+ | |||
+ | ==== Using Values ==== | ||
+ | |||
+ | To define a new Value class: | ||
+ | - create a new subclass of Value without instance variables and " | ||
+ | - edit he class method # | ||
+ | - add a pragma for each instance variable describing the variable | ||
+ | - open the popup menu on the new class and select "add Value methods..." | ||
+ | - edit the class method #example to provide a useful value | ||
+ | |||
+ | Done. | ||
+ | |||
+ | Now you have: | ||
+ | * a class with the specified instance variables | ||
+ | * an accessor for each variable with the same name | ||
+ | * an initializer with all parameters which sets up a fresh value | ||
+ | * a constructor taking all parameters and the sole caller of the initializer | ||
+ | * (2^^< | ||
+ | * an example | ||
+ | |||
+ | Lets have an example for example: | ||
+ | <code smalltalk> | ||
+ | Person | ||
+ | name: ' | ||
+ | sex: #male | ||
+ | birthday: (Date d: 25 m: 6 y: 1960) | ||
+ | </ | ||
+ | |||
+ | With it you can: | ||
+ | * create a value with <code smalltalk> | ||
+ | * ask for its parts <code smalltalk> | ||
+ | * print it as code <code smalltalk> | ||
+ | ' | ||
+ | name: '' | ||
+ | sex: #male | ||
+ | birthday: (Date d: 25 m: 6 y: 1960)' "</ | ||
+ | * get the value from its code <code smalltalk> | ||
+ | * add fancy access methods like <code smalltalk> | ||
+ | weekdayAtBirth | ||
+ | ^self birthday weekday | ||
+ | </ | ||
+ | |||
+ | |||
+ | ==== Anatomy of a Value ==== | ||
+ | |||
+ | A value has instance variables which can only contain values. The order of the variables is relevant and is used extensively. It is recommended to order the variables by importance. | ||
+ | |||
+ | Example: Class Person (subclass of Value) | ||
+ | - name | ||
+ | - sex | ||
+ | - birthday | ||
+ | |||
+ | Each variable has a simple getter method with a comment indicating the class. | ||
+ | |||
+ | <code smalltalk> | ||
+ | Person>> | ||
+ | "< | ||
+ | ^name | ||
+ | |||
+ | Person>> | ||
+ | "< | ||
+ | ^sex | ||
+ | |||
+ | Person>> | ||
+ | "< | ||
+ | ^birthday | ||
+ | </ | ||
+ | |||
+ | The variables are set all at once by an initalizing method which has all initial values as parameters. | ||
+ | The object becomes immutable after initialization and all instance variables are effectively constants. | ||
+ | |||
+ | The parameter names are the concatenated name and its class. This prevents name clashes, is systematic and still readable. | ||
+ | |||
+ | <code smalltalk> | ||
+ | Person>> | ||
+ | name := nameString. | ||
+ | sex := sexSymbol. | ||
+ | birthday := birthdayDate. | ||
+ | self beImmutable | ||
+ | </ | ||
+ | |||
+ | The one initializer is called by the constructor on the class side. The constructor returns a fully initialized immutable instance. | ||
+ | |||
+ | <code smalltalk> | ||
+ | Person class>> | ||
+ | | inst | | ||
+ | inst := self new. | ||
+ | inst initializeName: | ||
+ | ^inst | ||
+ | </ | ||
+ | |||
+ | Every value class has an #example mthod. This serves for test cases and as nice place to copy code from. | ||
+ | |||
+ | <code smalltalk> | ||
+ | Person class>> | ||
+ | ^Person | ||
+ | name: ' | ||
+ | sex: #male | ||
+ | birthday: (Date d: 25 m: 6 y: 1960) | ||
+ | </ | ||
+ | |||
+ | The initializer, | ||
+ | |||
+ | <code smalltalk> | ||
+ | Person class>> | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | </ | ||
+ | |||
+ | === Defaults === | ||
+ | |||
+ | The simple values above are not very interesting. But when you define defaults for some of the variables, Values become more useful. Lets add a nickname to the specification: | ||
+ | |||
+ | <code smalltalk> | ||
+ | Person class>> | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | < | ||
+ | </ | ||
+ | |||
+ | After generating code with: | ||
+ | <code smalltalk> | ||
+ | our example responds to #nickname : | ||
+ | |||
+ | <code smalltalk> | ||
+ | Person example nickname | ||
+ | </ | ||
+ | |||
+ | and there is a new constructor available: | ||
+ | <code smalltalk> | ||
+ | Person class>> | ||
+ | </ | ||
+ | |||
+ | Now you can specify a nickname: | ||
+ | <code smalltalk> | ||
+ | Person name: ' | ||
+ | </ | ||
+ | |||
+ | If you use the same parameter as the default, it is ignored | ||
+ | <code smalltalk> | ||
+ | Person name: ' | ||
+ | </ | ||
+ | because it is equal to | ||
+ | <code smalltalk> | ||
+ | Person name: ' | ||
+ | </ | ||
+ | |||
+ | |||
+ | ==== Get it ==== | ||
+ | |||
+ | The Smalltalk code lives in the [[:storeaccess|Cincom Public Store]] as bundle **Values | ||
+ | |||
+ | ==== References ==== | ||
I wrote a (scientific) dry paper about it and presented it at [[http:// | I wrote a (scientific) dry paper about it and presented it at [[http:// |