I was trying to mimic a module system in my bash scripts separate files containing utility functions for string, date, system, etc. which I can import in my main script and do my work. The only thing I miss is, I want to create a namespace style separation on import. So for example, if I import the string-utils file, all functions defined in it should work only when I prepend a string.
at the beginning of each function name in my main script. I realize I could just name all my functions as for example string.contains
rather than only contains
in the utility file itself, but it's not clean and I don't want to do that. I want to somehow declare the function prefix at the time of import. Something like import * from utils/string as string
. Is there a way I can do that? Thanks!
CodePudding user response:
From a practical view point, you are trying to eat your soup using a fork. Bash is not meant for employing name spaces. If you insist in doing something similar, I suggest that the autor of your sourced file cooperates in establishing your idea of a "namespace". For instance, if you your sourced file starts with
# This is file function_library.sh
: ${module:=''} # Default: No namespace
$fun1() { # Define function without namespace
....
}
# Rename the function to be in namespace, based on the answer in
# https://stackoverflow.com/questions/1203583/how-do-i-rename-a-bash-function
eval "$(echo "${module}_fun1()"; declare -f fun1 | tail -n 2)"
and so on. When sourcing the file, you do a
module=my_name # set namespace
. function_library.sh
This is not only cumbersome, it is also odd that the importer defines the namespace of a library. A more common concept in namespaces is that the imported module itselt fould define, which namespace it is in, and this would make the awkward renaming unnecessary.
CodePudding user response:
You will need to modify the content of the files where your functions are defined. You could do this on the fly with a text processor like awk
, for example, but this depends on how your functions are declared. Example if they are always declared starting on a separate line with syntax:
function foo {
...
}
Then, you can preprocess the file with:
$ source <(awk -v prefix="foo." '$1 == "function" {$2 = prefix $2} 1' foo.sh)
If your function declarations are less regular you will have to use a more complicated preprocessor. And, more importantly, this is very fragile. If the functions declared in the sourced file are themselves called in the sourced file, or their name used in one way or another (aliases, arrays of function names, whatever), things will get much more complex: you will need to catch all these references and update them too.