If I have a class with a property Phase: TrrPhase where TrrPhase is an enumeration such as (rrQuiescent, rrInitialised), is there an elegant way of extending the enumeration and overriding the property type so that a derived class can use the new values?
Mailing lists / fpc-pascal / 2010-07
Extending an enumeration
6 messages · 3 people · –
- MMark Morgan Lloyd 3
- JJetcheng Chu 2
- TThierry Coq 1
Reply by email Subscribe to this list Your subscription
Read-only archive. Use j and k to move between messages.
As far as I know, properties cannot be overridden. However, you could consider using subrange types, as the example below shows.
type
Fruit = (Apple, Banana, Cherry, Orange, Pineapple);
LimitedFruit = Apple..Cherry;You can use the full enumeration as the property's type, and then restrict its value using a custom property setter.
Earlier message 15 lines
Jetcheng Chu wrote 9 lines
Yes, I was thinking that. However if the basic class was say a round-robin scheduler with phases rrQuiescent and rrInitialised and the descendant was say an HP comms protocol handler with additional phases hpReceivingPadding, hpReceivedSync and so on it would seem to be questionable practice to have to define all possible enumerated values in the basic class.
I suppose one possibility would be to define hpPhase= (hpQuiescent:= rrQuiescent, ... ) and to forcibly disable some of the runtime type checking, but it's hardly elegant.
Which suggests that the best way is probably to have separate properties controlling the phase of execution (i.e. whether the code is properly initialised) and the state of the protocol or whatever being implemented.
Show quoted text 6 lines
It seems to me that these states are mutually exclusive, and you won't be using the SET type thereof. An enumeration type in this case doesn't seem to offer any real benefit. Instead you could consider using separate constant definitions, which will also be (mostly) syntactically compatible with your existing code.
Yes, I was thinking that. However if the basic class was say a round-robin scheduler with…
On 18/07/2010 20:56, Mark Morgan Lloyd wrote:
...
Show quoted text 7 lines
...
In this case, enumeration cannot be extended. If you look at it from an analysis point of view, you're implementing a state machine with an enumeration. If your state machine is extendable instead of fixed, and you want to add substates to it, then a possible implementation is to define a state class:
TSchedulerPhase = Class(TObject);
where the basic phases are defined as variables in the base class, and
initialized in the initialization of the base module:
var
spQuiescent: TSchedulerPhase;
spInitialized: TSchedulerPhase;
Initialization
spQuiescent := TSchedulerPhase.Create;
...The descendent class can add other states, and compute other transitions. This is a classic implementation of the state design pattern.
I hope this helps,
Thierry.
Thierry Coq wrote 15 lines
I agree, but that's more a poor choice of example on my part than an invalidation of the original question.
