patternbashMinor
Two similar shell functions that run different programs
Viewed 0 times
shelldifferenttwothatprogramsfunctionssimilarrun
Problem
I have a script that contains two shell functions:
which obviously is a repeat of each other except for the fact that it calls a different program in each function. The first function calls the
How can I DRY this script (either
runhaskells() {
local DIR=$PWD
local TARGET="cabal.sandbox.config"
while [[ ! -e $DIR/$TARGET -a $DIR != "/" ]]; do
DIR=$(dirname $DIR)
done
if [[ $DIR != "/" ]]; then
local DB=$(sed -ne '/^package-db: */{s///p;q;}' "$DIR/$TARGET")
runhaskell -no-user-package-db -package-db="$DB" "$@"
else
runhaskell "$@"
fi
}
ghcs() {
local DIR=$PWD
local TARGET="cabal.sandbox.config"
while [[ ! -e $DIR/$TARGET -a $DIR != "/" ]]; do
DIR=$(dirname $DIR)
done
if [[ $DIR != "/" ]]; then
local DB=$(sed -ne '/^package-db: */{s///p;q;}' "$DIR/$TARGET")
ghc -no-user-package-db -package-db="$DB" "$@"
else
ghc "$@"
fi
}which obviously is a repeat of each other except for the fact that it calls a different program in each function. The first function calls the
runhaskell program while the second function calls the ghc program.How can I DRY this script (either
zsh or bash syntax is fine for me) with the end goal that I should be able to call either function at the command line?Solution
Two simple bash solutions I can think of are:
-
Use a shell script and
-
Two small wrapper functions.
Slightly
-
Use a shell script and
$0/$BASH_SOURCE to determine the calling name and a symlink from one name to the other.-
Two small wrapper functions.
h() {
local DIR=$PWD
local TARGET="cabal.sandbox.config"
while [[ ! -e $DIR/$TARGET -a $DIR != "/" ]]; do
DIR=$(dirname $DIR)
done
if [[ $DIR != "/" ]]; then
local DB=$(sed -ne '/^package-db: */{s///p;q;}' "$DIR/$TARGET")
set -- "${@:1:1}" -no-user-package-db -package-db="$DB" "${@:2}"
# or this is the order of original arguments and added arguments don't matter
set -- "$@" -no-user-package-db -package-db="$DB"
fi
"$@"
}
runhaskells() {
h runhaskell "$@"
}
ghcs() {
h ghc "$@"
}Slightly
DRYier version of the above which uses bash's FUNCNAME array.h() {
local DIR=$PWD
local TARGET="cabal.sandbox.config"
while [[ ! -e $DIR/$TARGET -a $DIR != "/" ]]; do
DIR=$(dirname $DIR)
done
if [[ $DIR != "/" ]]; then
local DB=$(sed -ne '/^package-db: */{s///p;q;}' "$DIR/$TARGET")
set -- "${@:1:1}" -no-user-package-db -package-db="$DB" "${@:2}"
# or this is the order of original arguments and added arguments don't matter
set -- "$@" -no-user-package-db -package-db="$DB"
fi
"${FUNCNAME[1]%s}" "$@"
}
runhaskells() {
h "$@"
}
ghcs() {
h "$@"
}Code Snippets
h() {
local DIR=$PWD
local TARGET="cabal.sandbox.config"
while [[ ! -e $DIR/$TARGET -a $DIR != "/" ]]; do
DIR=$(dirname $DIR)
done
if [[ $DIR != "/" ]]; then
local DB=$(sed -ne '/^package-db: */{s///p;q;}' "$DIR/$TARGET")
set -- "${@:1:1}" -no-user-package-db -package-db="$DB" "${@:2}"
# or this is the order of original arguments and added arguments don't matter
set -- "$@" -no-user-package-db -package-db="$DB"
fi
"$@"
}
runhaskells() {
h runhaskell "$@"
}
ghcs() {
h ghc "$@"
}h() {
local DIR=$PWD
local TARGET="cabal.sandbox.config"
while [[ ! -e $DIR/$TARGET -a $DIR != "/" ]]; do
DIR=$(dirname $DIR)
done
if [[ $DIR != "/" ]]; then
local DB=$(sed -ne '/^package-db: */{s///p;q;}' "$DIR/$TARGET")
set -- "${@:1:1}" -no-user-package-db -package-db="$DB" "${@:2}"
# or this is the order of original arguments and added arguments don't matter
set -- "$@" -no-user-package-db -package-db="$DB"
fi
"${FUNCNAME[1]%s}" "$@"
}
runhaskells() {
h "$@"
}
ghcs() {
h "$@"
}Context
StackExchange Code Review Q#75613, answer score: 3
Revisions (0)
No revisions yet.