#!/bin/sh
data()
{
ds="$1"
object="$2"
method="$3"
if [ "$method" = "_data" ]; then
echo "$ds"
fi
}
get_d()
{
[ $# -lt 2 ] && return
object="$1"
d="$2"
eval "echo \$$($object $d)"
}
set_d()
{
[ $# -lt 3 ] && return
object="$1"
d="$2"
new_val="$3"
eval "$($object $d)"="$new_val"
}
object_counter=0
new()
{
[ $# -lt 2 ] && return
class="$1"
object_var="$2"
ds="$($class null _data)"
eval 'object_'"$object_counter"'()
{
[ "$#" -lt 1 ] && return
method="$1"
case "$method" in
"_class")
echo '"$class"';;
'"$(for d in $ds; do
echo '"'$d'")
echo object_'$object_counter'_'$d';;'
done)"'
esac
}'
object="object_$object_counter"
object_counter="$((object_counter + 1))"
call "$object" _init
eval "$object_var=$object"
}
call()
{
[ $# -lt 2 ] && return
object="$1"
method="$2"
class="$($object _class)"
shift 2
"$class" "$object" "$method" "$@"
}
################################################################################
BaseYoba()
{
data "x y" "$@"
case "$method" in
"_init")
set_d "$object" x 0
set_d "$object" y 0 ;;
"print")
echo "x=$(get_d $object x) y=$(get_d $object y)" ;;
esac
}
DerivedYoba1()
{
BaseYoba "$@"
case "$method" in
"go")
set_d "$object" x "$(($(get_d $object x) + $3))"
set_d "$object" y "$(($(get_d $object y) + $3))" ;;
esac
}
DerivedYoba2()
{
case "$method" in
"go")
set_d "$object" x "$(($(get_d $object x) + $3 * 2))" ;;
*)
BaseYoba "$@" ;;
esac
}
DerivedYoba3()
{
data "z" "$@"
case "$method" in
"_init")
DerivedYoba1 "$@"
set_d "$object" z 0 ;;
"go")
DerivedYoba1 "$@"
set_d "$object" z "$(($(get_d $object z) + $3 * 2))" ;;
"print")
echo "x=$(get_d $object x) y=$(get_d $object y) z=$(get_d $object z)" ;;
*)
DerivedYoba1 "$@"
esac
}
fun()
{
for i in `seq 5`; do
call "$1" go $i
call "$1" print
done
}
new DerivedYoba1 yoba1
fun "$yoba1"
new DerivedYoba2 yoba2
fun "$yoba2"
new DerivedYoba3 yoba3
fun "$yoba3"