Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
Next revision Both sides next revision
complexvalues [2019/01/04 12:47]
christian [Anatomy of a Value]
complexvalues [2019/01/04 16:56]
christian [Using Values]
Line 10: Line 10:
  
 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 "moving parts", the complex stuff. Since Values are so trivial and simple, I do not need to spend much time with them - they just work very reliable. Instead I can concentrate on complicated objects at the heart of the app. By sourcing out functionalities to Values, the systems become simpler. 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 "moving parts", the complex stuff. Since Values are so trivial and simple, I do not need to spend much time with them - they just work very reliable. Instead I can concentrate on complicated objects at the heart of the app. By sourcing out functionalities to Values, the systems become simpler.
 +
 +==== Using Values ====
 +
 +To define a new Value class:
 +  - create a new subclass of Value without instance variables and "Subclass responsibilities" checked
 +  - edit he class method #localSpecification of the new class
 +    - add a pragma for each instance variable describing the variable
 +  - open the popup menu on the new class and select "add Value methods...". This generates all 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^^<numberOfDefaultVariables>) - 1 optional constructors
 +  * an example
 +
 +Lets have an example for example:
 +<code smalltalk>
 +Person
 +    name: 'Christian Haider'
 +    sex: #male
 +    birthday: (Date d: 25 m: 6 y: 1960)
 +</code>
 +
 +With it you can:
 +  * create a value with <code smalltalk>person := Person example</code>
 +  * ask for its parts <code smalltalk>person name  "returns 'Christian Haider' "</code>
 +  * print it as code <code smalltalk>person asSource  "returns
 +'Person
 +    name: ''Christian Haider''
 +    sex: #male
 +    birthday: (Date d: 25 m: 6 y: 1960)' "</code>
 +  * get the value from its code <code smalltalk>person class evaluate: person asSource "returns a value equal to person"</code>
 +  * add fancy access methods like <code smalltalk>
 +weekdayAtBirth
 +  ^self birthday weekday
 +</code>
 +
  
 ==== Anatomy of a Value ==== ==== Anatomy of a Value ====
Line 19: Line 61:
   - sex   - sex
   - birthday   - birthday
 +
 +Each variable has a simple getter method with a comment indicating the class.
 +
 +<code smalltalk>
 +Person>>name
 +  "<String>"
 +  ^name
 +
 +Person>>sex
 +  "<Symbol>"
 +  ^sex
 +
 +Person>>birthday
 +  "<Date>"
 +  ^birthday
 +</code>
  
 The variables are set all at once by an initalizing method which has all initial values as parameters. 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 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> <code smalltalk>
-Person>>initializeName: aString sex: aSymbol birthday: aDate +Person>>initializeName: nameString sex: sexSymbol birthday: birthdayDate 
-  name := aString+  name := nameString
-  sex := aSymbol+  sex := sexSymbol
-  birthday := aDate.+  birthday := birthdayDate.
   self beImmutable   self beImmutable
 </code> </code>
Line 34: Line 94:
  
 <code smalltalk> <code smalltalk>
-Person class>>name: aString sex: aSymbol birthday: aDate+Person class>>name: nameString sex: sexSymbol birthday: birthdayDate
   | inst |   | inst |
   inst := self new.   inst := self new.
-  inst initializeName: aString sex: aSymbol birthday: aDate.+  inst initializeName: nameString sex: sexSymbol birthday: birthdayDate.
   ^inst   ^inst
 </code> </code>
Line 49: Line 109:
     sex: #male     sex: #male
     birthday: (Date d: 25 m: 6 y: 1960)     birthday: (Date d: 25 m: 6 y: 1960)
 +</code>
 +
 +The initializer, the constuctor, the example, the accessor methods and a printer method (not shown) are gernerated from a specification class method containing a list of pragmas defining each variable.
 +
 +<code smalltalk>
 +Person class>>localSpecification
 +  <constant: #name class: #{String}>
 +  <constant: #sex class: #{Symbol}>
 +  <constant: #birthday class: #{Date}>
 +</code>
 +
 +=== 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>>localSpecification
 +  <constant: #name class: #{String}>
 +  <constant: #sex class: #{Symbol}>
 +  <constant: #bithday class: #{Date}>
 +  <optional: #nickname class: #{String} default: 'self name'>
 +</code>
 +
 +After generating code with: 
 +<code smalltalk>Person generateMethods</code>
 +our example responds to #nickname :
 +
 +<code smalltalk>
 +Person example nickname   "returns 'Christian Haider' ">
 +</code>
 +
 +and there is a new constructor available:
 +<code smalltalk>
 +Person class>>name: nameString sex: sexSymbol birthday: birthdayDate nickname: nicknameString>
 +</code>
 +
 +Now you can specify a nickname:
 +<code smalltalk>
 +Person name: 'Christian Haider' sex: #male birthday: (Date d: 25 m: 6 y: 1960) nickname: 'Chris'>
 +</code>
 +
 +If you use the same parameter as the default, it is ignored
 +<code smalltalk>
 +Person name: 'Christian Haider' sex: #male birthday: (Date d: 25 m: 6 y: 1960) nickname: 'Christian Haider'>
 +</code>
 +because it is equal to
 +<code smalltalk>
 +Person name: 'Christian Haider' sex: #male birthday: (Date d: 25 m: 6 y: 1960)>
 </code> </code>
  
  • complexvalues.txt
  • Last modified: 2022/03/06 08:57
  • by christian