Skip to content

Commit

Permalink
started refactoring current low-level functions into a proper 'implem…
Browse files Browse the repository at this point in the history
…entation' so I can start working on the new filestore implementation
  • Loading branch information
remi committed Oct 11, 2010
1 parent 85e7302 commit e41b507
Show file tree
Hide file tree
Showing 2 changed files with 100 additions and 63 deletions.
147 changes: 84 additions & 63 deletions shash.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,81 +2,80 @@
# ======================================

# Public API
#
# These functions are NOT implementation dependent.
# They should all use the current shash_implementation

# TODO move all of the implementation dependent methods into a default "implementation"
SHASH_IMPLEMENTATIONS="crappy_vars experimental_filestore"
SHASH_IMPLEMENTATION=crappy_vars

shash() {
hash=$1; key=$2; value=$3
shash() { hash=$1; key=$2; value=$3;

if [ -z "$hash" ]; then
printf "Usage: shash hash_name [key] [value]"
elif [ -z "$key" ]; then
shash_keys_and_values "$hash"
elif [ -z "$value" ]; then
__shash_get "$hash" "$key"
shash_call get "$hash" "$key"
else
__shash_set "$hash" "$key" "$value"
fi
}

shash_keys() {
hash=$1
keys_varname=`__shash_variable_name_for_hash_keys "$hash"`
eval "printf \"\$$keys_varname\""
shash_implementation() { implementation=$1;
if [ -z "$implementation" ]; then
for available_implementation in $SHASH_IMPLEMENTATIONS; do
if [ "$available_implementation" = "$SHASH_IMPLEMENTATION" ]; then
printf "* $available_implementation\n"
else
printf " $available_implementation\n"
fi
done
else
SHASH_IMPLEMENTATION="$implementation"
fi
}

shash_values() {
hash=$1
shash_call() {
"shash_${SHASH_IMPLEMENTATION}" "$@"
}

shash_keys() { hash=$1;
__shash_get_all_keys "$hash"
}

shash_values() { hash=$1;
shash_echo "$hash" '$value'
}

shash_keys_and_values() {
hash=$1
shash_keys_and_values() { hash=$1;
shash_echo "$hash" '$key: $value'
}

shash_length() {
hash=$1
shash_length() { hash=$1;
printf "`shash_keys "$hash" | wc -l`"
}

shash_each() {
hash=$1; code=$2

shash_each() { hash=$1; code=$2;
old_ifs=$IFS
IFS='
'
'
for key in `shash_keys "$hash"`; do
value=`__shash_get "$hash" "$key"`
value=`shash_call get "$hash" "$key"`
eval "$code"
done
IFS=$old_ifs
}

shash_echo() {
hash=$1; code=$2
shash_echo() { hash=$1; code=$2;
shash_each "$hash" "echo \"$code\""
}

shash_delete() {
hash=$1; key=$2

# unset the actual variable
hash_and_key_variable=`__shash_variable_name_for_hash_and_key "$hash" "$key"`
eval "unset $hash_and_key_variable"

# remove the key from our list of keys
keys_varname=`__shash_variable_name_for_hash_keys "$hash"`
old_keys=`shash_keys "$hash"`
new_keys=`echo "$old_keys" | grep -v "^${key}$"`
eval "${keys_varname}=\"$new_keys\""
shash_delete() { hash=$1; key=$2;
__shash_delete "$@"
}

# Defining your own Hash helper function

shash_declare() {
hash=$1

shash_declare() { hash=$1;
# Defines the main function, eg. 'dogs'
eval "${hash}() { shash \"${hash}\" \"\$@\"; }"

Expand All @@ -86,36 +85,33 @@ shash_declare() {
done
}

shash_unset() {
hash=$1
shash_unset() { hash=$1;
__shash_unset "$hash"
}

# this is very implementation dependent!
# when we have many implementations, the implementation will have to be responsible for doing this itself.
# IMPLEMENTATIONS

# unset each hash/key variable
for key in `shash_keys "$hash"`; do
unset `__shash_variable_name_for_hash_and_key "$hash" "$key"`
done
# crappy_vars

# unset the variable that holds all key names
unset `__shash_variable_name_for_hash_keys "$hash"`
shash_crappy_vars() {
method=$1; shift
"shash_crappy_vars__$method" "$@"
}

# unset all of the functions
unset -f "$hash"
for method in keys values delete each echo length; do
unset -f "${hash}_${method}"
done
shash_crappy_vars__get() { hash=$1; key=$2

varname=`__shash_variable_name_for_hash_and_key "$hash" "$key"`
eval "echo \$${varname}"
}

# Private functions
# BELOW IS OLD DEPRECATED CODE THAT IS BEING REFACTORED INTO A PROPER IMPLEMENTATION

__shash_variable_name_for_hash_keys() {
varname=`__shash_safe_variable_name "$1"`
printf "__shash__${varname}__keys"
}

__shash_variable_name_for_hash_and_key() {
hash=$1; key=$2
__shash_variable_name_for_hash_and_key() { hash=$1; key=$2:
safe_hash=`__shash_safe_variable_name "$hash"`
safe_key=` __shash_safe_variable_name "$key"`
printf "__shash__${safe_hash}__${safe_key}"
Expand All @@ -125,9 +121,7 @@ __shash_safe_variable_name() {
printf "`printf "$1" | sed 's/[^[:alnum:]]//g'`"
}

__shash_set() {
hash=$1; key=$2; value=$3

__shash_set() { hash=$1; key=$2; value=$3;
# set variable for this key
varname=`__shash_variable_name_for_hash_and_key "$hash" "$key"`
eval "$varname='$value'"
Expand All @@ -137,8 +131,35 @@ __shash_set() {
eval "${keys_varname}=\"\${${keys_varname}}${key}\n\""
}

__shash_get() {
hash=$1; key=$2
varname=`__shash_variable_name_for_hash_and_key "$hash" "$key"`
eval "echo \$${varname}"
__shash_get_all_keys() { hash=$1;
keys_varname=`__shash_variable_name_for_hash_keys "$hash"`
eval "printf \"\$$keys_varname\""
}

__shash_delete() { hash=$1; key=$2;
# unset the actual variable
hash_and_key_variable=`__shash_variable_name_for_hash_and_key "$hash" "$key"`
eval "unset $hash_and_key_variable"

# remove the key from our list of keys
keys_varname=`__shash_variable_name_for_hash_keys "$hash"`
old_keys=`shash_keys "$hash"`
new_keys=`echo "$old_keys" | grep -v "^${key}$"`
eval "${keys_varname}=\"$new_keys\""
}

__shash_unset() { hash=$1;
# unset each hash/key variable
for key in `shash_keys "$hash"`; do
unset `__shash_variable_name_for_hash_and_key "$hash" "$key"`
done

# unset the variable that holds all key names
unset `__shash_variable_name_for_hash_keys "$hash"`

# unset all of the functions
unset -f "$hash"
for method in keys values delete each echo length; do
unset -f "${hash}_${method}"
done
}
16 changes: 16 additions & 0 deletions test/shash-functions-test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,22 @@

describe "shash"

before() {
shash_implementation crappy_vars
}

it_can_display_the_current_implementation() { # $ shash_implementation
test "`shash_implementation`" "=" "* crappy_vars${CR} experimental_filestore"
}

it_can_switch_implementations() { # $ shash_implementation
test "`shash_implementation | grep '*'`" "=" "* crappy_vars"

shash_implementation experimental_filestore

test "`shash_implementation | grep '*'`" "=" "* experimental_filestore"
}

it_displays_usage_without_arguments() { # $ shash
usage=`shash | head -n 1`
test "$usage" "=" "Usage: shash hash_name [key] [value]"
Expand Down

0 comments on commit e41b507

Please sign in to comment.