I would like to create an object to represent some electrical readings, such as input voltage. To do this, I want to create a basic class structure to handle different types of readings -- say, current as well as voltage.
The pseudo-code (well, Python actually) for what I want to do is this:
# Create base class as a subclass of a common class to all other classes
class PowerReading(object):
# Defining word to initialize instance variables using the given input
def __init__(self, current_value, units):
# instance variables
self.value = current_value
self.units = units
# Define new class based on our generic class above
class Voltage(PowerReading):
# Call the parent class word with an input value, and constant units string
def __init__(self, current_value):
super(Voltage, self).__init__(current_value, 'volts')
# Create another class based on the same parent class as Voltage
class Current(PowerReading):
def __init__(self, current_value):
# Call the parent word with current units
super(Voltage, self).__init__(current_value, 'amps')
# input_voltage_atod() is defined elsewhere: gives an instant reading
# from the ATOD pin on the power input rail, already converted to units of volts.
# Create instance object variable using our new Voltage class.
input_voltage = Voltage(input_voltage_atod())
# Use the object's instance variables
print input_voltage.value, input_voltage.units
# 3.25 volts
I'm using Gforth
and the oof.fs
extension.
With some simple gforth symbols:
: symbol ( "name" -- )
create lastxt , does> ( -- xt ) @ ;
: .symbol ( xt -- )
>name name>string 1 /string type ;
symbol 'volts
symbol 'amps
Here's an oof.fs equivalent of your Python:
require oof.fs
object class power-reading
float var value
cell var units
method .
how:
: init ( r-value units -- ) units ! value f! ;
: . ( -- ) value f@ f. units @ .symbol space ;
class;
power-reading class voltage
how:
: init ( r-value -- ) 'volts super init ;
class;
power-reading class current
how:
: init ( r-value -- ) 'amps super init ;
class;
3.25e voltage : input-voltage
input-voltage . \ Output: 3.25 volts
That's pretty similar, isn't it?
These days I use mini-oof2.fs, which is much lower level than oof.fs, and which does a lot less. In that:
object class
ffield: value
field: units
method init ( value units -- )
method show ( -- )
end-class power-reading
[: ( r-value units -- ) units ! value f! ;] power-reading to init
[: ( -- ) value f@ f. units @ .symbol space ;] power-reading to show
power-reading class
end-class voltage
[: ( r-value -- ) value f! 'volts units ! ;] voltage to init
power-reading class
end-class current
[: ( r-value -- ) value f! 'amps units ! ;] current to init
voltage new constant input-voltage
3.25e input-voltage .init
input-voltage .show \ Output: 3.25 volts
The [: ... ;]
aren't special mini-oof2.fs syntax. They're just
gforth quotations, used here as synonyms of :NONAME .
The .init
and .show
macro-expand (sort of) into >o init o>
and >o show o>
, respectively.
Rather than have an INIT method, I often have a non-OO word that constructs the object:
: >current ( r -- o )
current new >o value f! 'amps units ! o o> ;
: current, ( r -- )
here >o [ current >osize @ ]L allot value f! 'amps units ! o> ;
But of course this doesn't play as well with complex object orientation and SUPER methods and such. It's a 90% solution as opposed to the 100% OO solutions provided by oof.fs and SWOOP and FMS.