Contributed by Monty Stein
#!/usr/bin/bash
## Example of OO inheritance in shell, now let us never speak of it again
## - Monty Stein Aug 3, 1998
# Function (and data) table handlers. Stores everything similarly to the
# way Python will print out a dictionary: key1:value1,key2:value2,...
# dump it in a format much like a flat file DB
function functbldump {
echo "$1"|tr , "\012"
}
# recover from flat file DB and put back into string
function functblundump {
(tr "\012" , <$1;echo )|sed 's/,,*/,/g'
}
# add a key:value pair to the string
function functbladd {
functbldump "$1" >/tmp/temp$$
echo "$2:$3" >>/tmp/temp$$
functblundump /tmp/temp$$
rm -f /tmp/temp$$
}
# get a value for a key. Note: the last named key overrides
function functblget {
functbldump "$1" >/tmp/temp$$
T=`egrep "^$2:" /tmp/temp$$|tail -1|cut -d: -f2`
if [ -z "$T" ]
then
echo "WARN: cannot get key $2 from function table:\n$1" 1>&2
fi
echo "$T"
rm -f /tmp/temp$$
}
##########
function Shape {
T=""
T=`functbladd "$T" x $1`
T=`functbladd "$T" y $2`
T=`functbladd "$T" set_x Shape_set_x`
T=`functbladd "$T" set_y Shape_set_y`
T=`functbladd "$T" relative_move Shape_relative_move`
T=`functbladd "$T" draw Shape_draw`
echo "$T"
}
function Shape_set_x {
echo `functbladd "$1" x $2`
}
function Shape_set_y {
echo `functbladd "$1" y $2`
}
function Shape_relative_move {
T="$1"
X=`functblget "$T" x`
Y=`functblget "$T" y`
X=`expr "$X" + $2`
Y=`expr "$Y" + $3`
T=`functbladd "$T" x $X`
T=`functbladd "$T" y $Y`
echo "$T"
}
function Shape_draw {
echo "default Shape draw" 1>&2
echo "$1"
}
###########
function Rectangle {
T=`Shape $1 $2`
T=`functbladd "$T" width $3`
T=`functbladd "$T" height $4`
T=`functbladd "$T" set_width Rectangle_set_width`
T=`functbladd "$T" set_height Rectangle_set_height`
T=`functbladd "$T" draw Rectangle_draw`
echo "$T"
}
function Rectangle_set_width {
echo `functbladd "$1" width $2`
}
function Rectangle_set_height {
echo `functbladd "$1" height $2`
}
function Rectangle_draw {
X=`functblget "$1" x`
Y=`functblget "$1" y`
WIDTH=`functblget "$1" width`
HEIGHT=`functblget "$1" height`
echo "drawing rectangle ($X,$Y) with width $WIDTH, height $HEIGHT" 1>&2
echo "$1"
}
###########
function Circle {
T=`Shape $1 $2`
T=`functbladd "$T" radius $3`
T=`functbladd "$T" set_radius Circle_set_radius`
T=`functbladd "$T" draw Circle_draw`
echo "$T"
}
function Circle_set_radius {
echo `functbladd "$1" radius $2`
}
function Circle_draw {
X=`functblget "$1" x`
Y=`functblget "$1" y`
RADIUS=`functblget "$1" radius`
echo "drawing circle ($X,$Y) with radius $RADIUS" 1>&2
echo "$1"
}
############
function DoSomethingWithShape {
T="$1"
T=`eval \`functblget "$T" draw\` "$T"`
T=`eval \`functblget "$T" relative_move\` "$T" 100 100`
T=`eval \`functblget "$T" draw\` "$T"`
echo "$T"
}
###################################################
# using shapes polymorphically
export SHAPES_0=`Rectangle 10 20 5 6`
export SHAPES_1=`Circle 15 25 8`
for i in 0 1
do
#the export tricks the shell into loading into a shell variabled name
#the env call does much the same, but extracts
export SHAPES_$i="`DoSomethingWithShape \`env|egrep "^SHAPES_$i="|sed 's/^.*=//g'\``"
done
# access a rectangle specific function
export RECT=`Rectangle 0 0 15 15`
RECT=`eval \`functblget "$RECT" set_width\` "$RECT" 30`
RECT=`eval \`functblget "$RECT" draw\` "$RECT"`
drawing rectangle (10,20) with width 5, height 6 drawing rectangle (110,120) with width 5, height 6 drawing circle (15,25) with radius 8 drawing circle (115,125) with radius 8 drawing rectangle (0,0) with width 30, height 15