4
\$\begingroup\$

I have a script that contains two shell functions:

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?

200_success
145k22 gold badges190 silver badges478 bronze badges
asked Jan 4, 2015 at 4:49
\$\endgroup\$
0

1 Answer 1

3
\$\begingroup\$

Two simple bash solutions I can think of are:

  1. Use a shell script and 0ドル/$BASH_SOURCE to determine the calling name and a symlink from one name to the other.

  2. 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 "$@"
 }
answered Jan 4, 2015 at 19:59
\$\endgroup\$
0

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.