> xx. <( and >( can now be used in function names. What is the background of this change? This was added in commit 315095ad, and to the best of my knowledge, an email on the mailing list in the same period and related to this change would be Ref. [1] from kre.
[1] https://lists.gnu.org/archive/html/bug-bash/2023-02/msg00007.html > There is a very good reason to allow function names to contain almost > any character at all. [...] However, the interpretation of the bare `<(' and `>(' in Bash 5.3 seems to contradict the design discussed in Ref. [1]. Bash 5.3 interprets the bare <( and >( as an introducer of process substitutions, and the defined function has the source code of the parsed process substitution. $ bash-devel -c '<(echo hello) () { echo hello; }; declare -F' declare -f <(echo hello) However, Ref. [1] discusses the function definition of the form like « '<()' () { ...; } » (instead of « <() () { ...; } » which was Implemented in Bash 5.3): > Now extract the following script, which uses functions of the > same names, instead of file system commands > [...] > > eval "${Q}${name}${Q}() { printf $Q..${name_of_name}().. works %s\n$Q > \"$*\"; }" > > [...] > The code to build the function is different to the code which creates > the file, but that part is irrelevant, and mostly caused by the desired > name being a variable, which normally would not be the case, usually > you'd just write something like > > '()'() { : whatever code should be run; } > [...] > Note that no expansions are specified to happen on the function name > in a function definition, so $var() isn't ever going to create a function > named by the value of var - you need eval for that. Because of that > the NetBSD shell requires any function definition which contains something > that looks like a var/command/arith expansion to be quoted such as to make > it clear the user knows that isn't going to happen - we'd reject the $var() > case, but allow '$var'() or \$var() (but not "$var"() - "\$var"() works > however.) ie: if it would expand if used as as a normal shell word > eg: as a command arg, then we forbid it as a function name, but with quoting > to prevent that, the same name is just fine. In Bash 5.3, the defined function name isn't even the literal process substitution, but a somewhat prettified version (which is non-trivial to predict): $ bash-devel -c $'<(\n # ignored\necho hello\n) () { echo hello; }; declare -F' declare -f <(echo hello) What would be the use case of this feature, and what is the rationale for this design? The current behavior doesn't seem to make sense to me. If it was implemented after Ref. [1], « '<(echo hello)' () { echo hello; } » should have been supported but not « <(echo hello) () { echo hello; }.». Ref. [1] argued that "$" expansions should not happen in the function name in the function definition, but in my opinion, there is room to optionally support expansions in the function names of function definitions (such as « "$namespace::func"() { ...; } » as I suggested a few times on the mailing list in the past). Then, if the syntax of the form « <(echo hello) () { ...; } » would really be implemented, I think its behavior should be to expand the word in the place of the function name as if it were in a context of a normal argument, and the function name becomes the shell-expansion result (i.e., the path to the named pipe in the present case) for consistency. Although I'm not sure if there would be use cases for the function name being the path to the named pipe, it seems even less likely that there are use cases for function names being the prettified source code. I feel the function definition of the form « <(echo hello) () { ...; } » shouldn't create a function of the name `<(echo hello)'. It should rather become a syntax error. If the syntax would be supported, it should define a function with the name being the path to the named pipe for the principle of least astonishment. -- Koichi