You are not logged in.
Take a look at this script (test.sh):
alias func='__init_func'
function __init_func() {
unalias func
function func ()
{
echo "func $@"
}
func "$@"
}
Then:
source test.sh
func
Then the `func` call at the end of `__init_func` is still directed to `__init_func`, which causes nested call:
__init_func:unalias:1: no such hash table element: func
...
__init_func:unalias:1: no such hash table element: func
__init_func:6: maximum nested function level reached; increase FUNCNEST?
I expect the `func` call to be directed to the function `func`?
zsh version is 5.9-5.
Last edited by FishBoneEK (2024-11-07 02:41:10)
Offline
Interestingly though if I put the `alias` at the end of the script it will work.
function __init_func() {
unalias func
function func () {
echo "func $@"
}
func "$@"
}
alias func='__init_func'
source test.sh
func
Result:
func
Offline
__init_func:unalias:1: no such hash table element: func
alias func='__init_func'
function __init_func() {
printf "__init_func: "; type -a func
unalias func
printf "=> "; type -a func
function func ()
{
printf "inside func: "; type -a func
echo "func $@"
}
printf "==> "; type -a func
func "$@"
}
function __init_func() {
printf "__init_func: "; type -a func
unalias func
printf "=> "; type -a func
function func ()
{
printf "inside func: "; type -a func
echo "func $@"
}
printf "==> "; type -a func
func "$@"
}
alias func='__init_func'
Online
__init_func:unalias:1: no such hash table element: func
alias func='__init_func' function __init_func() { printf "__init_func: "; type -a func unalias func printf "=> "; type -a func function func () { printf "inside func: "; type -a func echo "func $@" } printf "==> "; type -a func func "$@" }
__init_func: func is an alias for __init_func
=> func not found
==> func is a shell function
__init_func: func is a shell function
__init_func:unalias:2: no such hash table element: func
=> func is a shell function
==> func is a shell function
__init_func: func is a shell function
__init_func:unalias:2: no such hash table element: func
=> func is a shell function
==> func is a shell function
...
__init_func:10: maximum nested function level reached; increase FU
NEST?
function __init_func() { printf "__init_func: "; type -a func unalias func printf "=> "; type -a func function func () { printf "inside func: "; type -a func echo "func $@" } printf "==> "; type -a func func "$@" } alias func='__init_func'
__init_func: func is an alias for __init_func
=> func not found
==> func is a shell function
inside func: func is a shell function
func
Offline
I know what that prints, the plan was for you to look at that and understand what's going on and why that doesn't work.
You're (maybe?) trying to create a dynamic function, but that does't work this way (and there's probably no way to do this avoiding eval or source)
Online
I know what that prints, the plan was for you to look at that and understand what's going on and why that doesn't work.
You're (maybe?) trying to create a dynamic function, but that does't work this way (and there's probably no way to do this avoiding eval or source)
I still don't get it?
In the first case (where I alias first), at the "==>", `func` is the shell function, like what `type` has said, so calling `func` should call the function itself, but it's still `__init_func` that gets called.
And yeah, I was a bit annoyed by conda's slow init, so I tried to init conda implicitly at the first conda cmd execution.
Offline
func starts out as alias for __init_func, gets unaliased and then turned into a shell function.
Then 'func "$@"' gets executed, but that doesn't get resolved to the function, but the previous alias because [drummroll, suspension, magic, surprise, tadaaa]: https://www.chiark.greenend.org.uk/~sgt … iases.html
At this point shit hits the fan and __init_func just calls itself recursively, spamming the inability to unalias func along the way.
Trailing the alias works because now func doesn't get expanded to __init_func before anything else happens.
Online
func starts out as alias for __init_func, gets unaliased and then turned into a shell function.
Then 'func "$@"' gets executed, but that doesn't get resolved to the function, but the previous alias because [drummroll, suspension, magic, surprise, tadaaa]: https://www.chiark.greenend.org.uk/~sgt … iases.htmlAt this point shit hits the fan and __init_func just calls itself recursively, spamming the inability to unalias func along the way.
Trailing the alias works because now func doesn't get expanded to __init_func before anything else happens.
Oh
My
God
What a big suprise...
Alright, thanks!
EDIT:
Wait I still don't get it, why is it related?
Magic alias is that alias is expanded before anything else, so we can do tricks with this feature.
But this doesn't explain why my 'func' is still expanded to '__init_func'? Just right before the 'func' call inside '__init_func', 'type' already says it's a shell function, and if I use 'which' instead of 'type', 'which' would say 'func' is exactly the func shell function ('which' even displays the function code). But in the end 'func' is still expanded to '__init_func'.
Last edited by FishBoneEK (2024-09-20 12:24:47)
Offline
The moment you execute
alias func='__init_func'
the
func "$@"
gets replaced w/
__init_func "$@"
Even if you redefine func() later on, that replacement remains.
Online
The moment you execute
alias func='__init_func'
the
func "$@"
gets replaced w/
__init_func "$@"
Even if you redefine func() later on, that replacement remains.
Oh I seem to understand, the alias replaces 'func' inside the funciton body too???? I really didn't expect that, i thought the code inside function bodies are kept as-is.
Offline