Enumeration type implementation

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
6 messages Options
Reply | Threaded
Open this post in threaded view
|

Enumeration type implementation

Ben Coman
(Resending since it didn't show up on the list overnight)

What is the best way to implement "enumerations" in Smalltalk. For
instance, for a UML definition of...
<<enumeration>> Currency
  <<enum>> USD   'US dollar'
  <<enum>> EUR   'Eueropean euro'
  <<enum>> AUD    'Australian dollar'

here is my guess, consisting of 2 instance side methods and 3 class side
methods...
-------------------------
Object subclass: #EpcimCurrency
   instanceVariableNames: 'value'
   classVariableNames: ''
   poolDictionaries: ''
   category: 'IEC61970-Domain-Enumerations'

EpcimCurrency >> value: aCurrency
   ( (self class) validate: aCurrency) ifTrue:
       [ value := aCurrency
       ].

EpcimCurrency >> value
   ^value
-----------------------------------

EpcimCurrency class
   instanceVariableNames: 'enums'

EpcimCurrency class >> validate: aString
   enums ifNil: [ self initialize ].
   ^ enums includesKey: aString.

EpcimCurrency class >>  enums   "for displaying in pulldown menus"
   enums ifNil: [ self initialize ].
   ^enums copy

EpcimCurrency class >> initalize
   (enums := Dictionary new)
               add: 'USD'-> 'US dollar' ;
               add: 'EUR'-> 'European euro' ;
               add: 'AUD'-> 'Australian dollar' ;
               add: 'CAD'-> 'Canadian dollar' ;
               add: 'CHF'-> 'Swiss francs' ;
               add: 'CNY'-> 'Chinese yuan renminbi' ;
               add: 'DKK'-> 'Danish crown' ;
               add: 'GBP'-> 'British pound' ;
               add: 'JPY'-> 'Japanese yen' ;
               add: 'NOK'-> 'Norwegian crown' ;
               add: 'RUR'-> 'Russian ruble' ;
               add: 'SEK'-> 'Swedish crown' ;
               add: 'INR'-> 'India rupees' ;
               add: 'other'-> 'Another type of currency' .
----------------------
Examples
   " (EpcimCurrency new value: 'AUD' ) value inspect  "      ----> 'AUD'
   " (EpcimCurrency new value: 'XXX') value  inspect  "      ----> nil
   " EpcimCurrency initialize  "
   " EpcimCurrency enums inspect "   ---> aDictionary
------
The other way I thought might be like `Color blue`, but I'm not sure what is gained.

Your feedback would be appreciated.


_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

Re: Enumeration type implementation

Ralph Johnson
That is not bad.   However, EpcimCurrency needs more behavior on the
instance side.   In particular, a currency should know both its name
and its description.   i think "value" is just the name.   The
dictionary should map names to currencies instead of names to strings
(or descriptions), and the instance should have instance variables
"name" and "description" instead of "value".   If you do it this way
then there will only be one instance of each currency and checking for
equality will be very easy.  But the overall design is on target.

On Wed, Jan 4, 2012 at 5:21 AM, Ben Coman <[hidden email]> wrote:

> (Resending since it didn't show up on the list overnight)
>
> What is the best way to implement "enumerations" in Smalltalk. For instance,
> for a UML definition of...
> <<enumeration>> Currency
>  <<enum>> USD   'US dollar'
>  <<enum>> EUR   'Eueropean euro'
>  <<enum>> AUD    'Australian dollar'
>
> here is my guess, consisting of 2 instance side methods and 3 class side
> methods...
> -------------------------
> Object subclass: #EpcimCurrency
>  instanceVariableNames: 'value'
>  classVariableNames: ''
>  poolDictionaries: ''
>  category: 'IEC61970-Domain-Enumerations'
>
> EpcimCurrency >> value: aCurrency
>  ( (self class) validate: aCurrency) ifTrue:
>      [ value := aCurrency
>      ].
>
> EpcimCurrency >> value
>  ^value
> -----------------------------------
>
> EpcimCurrency class
>  instanceVariableNames: 'enums'
>
> EpcimCurrency class >> validate: aString
>  enums ifNil: [ self initialize ].
>  ^ enums includesKey: aString.
>
> EpcimCurrency class >>  enums   "for displaying in pulldown menus"
>  enums ifNil: [ self initialize ].
>  ^enums copy
>
> EpcimCurrency class >> initalize
>  (enums := Dictionary new)
>              add: 'USD'-> 'US dollar' ;
>              add: 'EUR'-> 'European euro' ;
>              add: 'AUD'-> 'Australian dollar' ;
>              add: 'CAD'-> 'Canadian dollar' ;
>              add: 'CHF'-> 'Swiss francs' ;
>              add: 'CNY'-> 'Chinese yuan renminbi' ;
>              add: 'DKK'-> 'Danish crown' ;
>              add: 'GBP'-> 'British pound' ;
>              add: 'JPY'-> 'Japanese yen' ;
>              add: 'NOK'-> 'Norwegian crown' ;
>              add: 'RUR'-> 'Russian ruble' ;
>              add: 'SEK'-> 'Swedish crown' ;
>              add: 'INR'-> 'India rupees' ;
>              add: 'other'-> 'Another type of currency' .
> ----------------------
> Examples
>  " (EpcimCurrency new value: 'AUD' ) value inspect  "      ----> 'AUD'
>  " (EpcimCurrency new value: 'XXX') value  inspect  "      ----> nil
>  " EpcimCurrency initialize  "
>  " EpcimCurrency enums inspect "   ---> aDictionary
> ------
> The other way I thought might be like `Color blue`, but I'm not sure what is
> gained.
>
> Your feedback would be appreciated.
>
>
> _______________________________________________
> Beginners mailing list
> [hidden email]
> http://lists.squeakfoundation.org/mailman/listinfo/beginners
_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

Re: Enumeration type implementation

Göran Krampe
I would in this case use a so called SharedPool. If you are using Squeak
then take for example a look at GZipConstants (inherits from SharedPool,
has classVariablesNames for each key, initialize them in class side
initialize method) and a use of it in GZipReadStream (it just lists it
in the class definition under poolDictionaries: and then just use those
keys directly as if they were globals.

regards, Göran
_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

Re: Enumeration type implementation

Göran Krampe
On 01/04/2012 01:01 PM, Göran Krampe wrote:
> I would in this case use a so called SharedPool. If you are using Squeak
> then take for example a look at GZipConstants (inherits from SharedPool,
> has classVariablesNames for each key, initialize them in class side
> initialize method) and a use of it in GZipReadStream (it just lists it
> in the class definition under poolDictionaries: and then just use those
> keys directly as if they were globals.

And another idea is to extend Number with one method for each currency
so that you can use them just like you can use "seconds" or "minutes" today:

5 minutes

10 USD

regards, Göran
_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

Re: Enumeration type implementation

Edwin Castro
In reply to this post by Ralph Johnson
In addition, you might consider using symbols for the name rather than strings.

On Wed, Jan 4, 2012 at 3:33 AM, Ralph Johnson <[hidden email]> wrote:
That is not bad.   However, EpcimCurrency needs more behavior on the
instance side.   In particular, a currency should know both its name
and its description.   i think "value" is just the name.   The
dictionary should map names to currencies instead of names to strings
(or descriptions), and the instance should have instance variables
"name" and "description" instead of "value".   If you do it this way
then there will only be one instance of each currency and checking for
equality will be very easy.  But the overall design is on target.

On Wed, Jan 4, 2012 at 5:21 AM, Ben Coman <[hidden email]> wrote:
> (Resending since it didn't show up on the list overnight)
>
> What is the best way to implement "enumerations" in Smalltalk. For instance,
> for a UML definition of...
> <<enumeration>> Currency
>  <<enum>> USD   'US dollar'
>  <<enum>> EUR   'Eueropean euro'
>  <<enum>> AUD    'Australian dollar'
>
> here is my guess, consisting of 2 instance side methods and 3 class side
> methods...
> -------------------------
> Object subclass: #EpcimCurrency
>  instanceVariableNames: 'value'
>  classVariableNames: ''
>  poolDictionaries: ''
>  category: 'IEC61970-Domain-Enumerations'
>
> EpcimCurrency >> value: aCurrency
>  ( (self class) validate: aCurrency) ifTrue:
>      [ value := aCurrency
>      ].
>
> EpcimCurrency >> value
>  ^value
> -----------------------------------
>
> EpcimCurrency class
>  instanceVariableNames: 'enums'
>
> EpcimCurrency class >> validate: aString
>  enums ifNil: [ self initialize ].
>  ^ enums includesKey: aString.
>
> EpcimCurrency class >>  enums   "for displaying in pulldown menus"
>  enums ifNil: [ self initialize ].
>  ^enums copy
>
> EpcimCurrency class >> initalize
>  (enums := Dictionary new)
>              add: 'USD'-> 'US dollar' ;
>              add: 'EUR'-> 'European euro' ;
>              add: 'AUD'-> 'Australian dollar' ;
>              add: 'CAD'-> 'Canadian dollar' ;
>              add: 'CHF'-> 'Swiss francs' ;
>              add: 'CNY'-> 'Chinese yuan renminbi' ;
>              add: 'DKK'-> 'Danish crown' ;
>              add: 'GBP'-> 'British pound' ;
>              add: 'JPY'-> 'Japanese yen' ;
>              add: 'NOK'-> 'Norwegian crown' ;
>              add: 'RUR'-> 'Russian ruble' ;
>              add: 'SEK'-> 'Swedish crown' ;
>              add: 'INR'-> 'India rupees' ;
>              add: 'other'-> 'Another type of currency' .
> ----------------------
> Examples
>  " (EpcimCurrency new value: 'AUD' ) value inspect  "      ----> 'AUD'
>  " (EpcimCurrency new value: 'XXX') value  inspect  "      ----> nil
>  " EpcimCurrency initialize  "
>  " EpcimCurrency enums inspect "   ---> aDictionary
> ------
> The other way I thought might be like `Color blue`, but I'm not sure what is
> gained.
>
> Your feedback would be appreciated.
>
>
> _______________________________________________
> Beginners mailing list
> [hidden email]
> http://lists.squeakfoundation.org/mailman/listinfo/beginners
_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners



--
Edwin G. Castro


_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners
Reply | Threaded
Open this post in threaded view
|

Re: Enumeration type implementation

Ben Coman
Edwin Castro wrote:
> In addition, you might consider using symbols for the name rather than
> strings.
>  
I will do that.

> On Wed, Jan 4, 2012 at 3:33 AM, Ralph Johnson <[hidden email]> wrote:
>  
>> That is not bad.   However, EpcimCurrency needs more behavior on the
>> instance side.   In particular, a currency should know both its name
>> and its description.   i think "value" is just the name.   The
>> dictionary should map names to currencies instead of names to strings
>> (or descriptions), and the instance should have instance variables
>> "name" and "description" instead of "value".   If you do it this way
>> then there will only be one instance of each currency and checking for
>> equality will be very easy.  But the overall design is on target.
>>    
I see some benefit in adding more "intelligence" to Currency, but I'm
not sure if I should do that at this stage.   I am in the very initial
stages of implementing an IEC published UML model.  There is a class
"Money" with three attributes "value, unit, multiplier" with the type of
'unit' being the "Currency"  enumeration.  It seems the enumeration is
quite dumb and used only to constrain values that are exchanged with
other applications.   Perhaps I end up rolling it into the "Money"
class.  I definitely look at refactoring as you suggest after my first
pass through the rest of the model and I get a chance to play with usage
of the model.

>> On Wed, Jan 4, 2012 at 5:21 AM, Ben Coman <[hidden email]> wrote:
>>    
>>> What is the best way to implement "enumerations" in Smalltalk. For instance, for a UML definition of...
>>> <<enumeration>> Currency
>>>  <<enum>> USD   'US dollar'
>>>  <<enum>> EUR   'Eueropean euro'
>>>  <<enum>> AUD    'Australian dollar'
>>>
>>> here is my guess, consisting of 2 instance side methods and 3 class side
>>> methods...
>>> -------------------------
>>> Object subclass: #EpcimCurrency
>>>  instanceVariableNames: 'value'
>>>  classVariableNames: ''
>>>  poolDictionaries: ''
>>>  category: 'IEC61970-Domain-Enumerations'
>>>
>>> EpcimCurrency >> value: aCurrency
>>>  ( (self class) validate: aCurrency) ifTrue:
>>>      [ value := aCurrency
>>>      ].
>>>
>>> EpcimCurrency >> value
>>>  ^value
>>> -----------------------------------
>>>
>>> EpcimCurrency class
>>>  instanceVariableNames: 'enums'
>>>
>>> EpcimCurrency class >> validate: aString
>>>  enums ifNil: [ self initialize ].
>>>  ^ enums includesKey: aString.
>>>
>>> EpcimCurrency class >>  enums   "for displaying in pulldown menus"
>>>  enums ifNil: [ self initialize ].
>>>  ^enums copy
>>>
>>> EpcimCurrency class >> initalize
>>>  (enums := Dictionary new)
>>>              add: 'USD'-> 'US dollar' ;
>>>              add: 'EUR'-> 'European euro' ;
>>>              add: 'AUD'-> 'Australian dollar' ;
>>>              add: 'CAD'-> 'Canadian dollar' ;
>>>              add: 'CHF'-> 'Swiss francs' ;
>>>              add: 'CNY'-> 'Chinese yuan renminbi' ;
>>>              add: 'DKK'-> 'Danish crown' ;
>>>              add: 'GBP'-> 'British pound' ;
>>>              add: 'JPY'-> 'Japanese yen' ;
>>>              add: 'NOK'-> 'Norwegian crown' ;
>>>              add: 'RUR'-> 'Russian ruble' ;
>>>              add: 'SEK'-> 'Swedish crown' ;
>>>              add: 'INR'-> 'India rupees' ;
>>>              add: 'other'-> 'Another type of currency' .
>>> ----------------------
>>> Examples
>>>  " (EpcimCurrency new value: 'AUD' ) value inspect  "      ----> 'AUD'
>>>  " (EpcimCurrency new value: 'XXX') value  inspect  "      ----> nil
>>>  " EpcimCurrency initialize  "
>>>  " EpcimCurrency enums inspect "   ---> aDictionary
>>> ------
>>> The other way I thought might be like `Color blue`, but I'm not sure what is gained.
>>>
>>> Your feedback would be appreciated.
>>>
>>>      

> Göran Krampe wrote:
>> On 01/04/2012 01:01 PM, Göran Krampe wrote:
>>> I would in this case use a so called SharedPool. If you are using
>>> Squeak
>>> then take for example a look at GZipConstants (inherits from
>>> SharedPool,
>>> has classVariablesNames for each key, initialize them in class side
>>> initialize method) and a use of it in GZipReadStream (it just lists it
>>> in the class definition under poolDictionaries: and then just use those
>>> keys directly as if they were globals.
>> And another idea is to extend Number with one method for each
>> currency so that you can use them just like you can use "seconds" or
>> "minutes" today:
>>
>> 5 minutes
>>
>> 10 USD
>>
>> regards, Göran
>>
>
I've looked and that is a very interesting idea.  At this stage I'll
keep it simple though and try to factor that in later.

Thanks Ralph, Goran and Edwin for your advice.  It really helps to
bounce ideas.  I will have a couple more coming :)
cheers, Ben
_______________________________________________
Beginners mailing list
[hidden email]
http://lists.squeakfoundation.org/mailman/listinfo/beginners