You are not logged in.

#1 2024-09-02 06:23:25

FishBoneEK
Member
Registered: 2023-09-26
Posts: 57

[SOLVED] zsh, weird behavior if I `alias` before function definition?

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

#2 2024-09-02 06:29:06

FishBoneEK
Member
Registered: 2023-09-26
Posts: 57

Re: [SOLVED] zsh, weird behavior if I `alias` before function definition?

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

#3 2024-09-02 07:21:18

seth
Member
Registered: 2012-09-03
Posts: 60,785

Re: [SOLVED] zsh, weird behavior if I `alias` before function definition?

__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

#4 2024-09-04 07:11:20

FishBoneEK
Member
Registered: 2023-09-26
Posts: 57

Re: [SOLVED] zsh, weird behavior if I `alias` before function definition?

seth wrote:
__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?
seth wrote:
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

#5 2024-09-04 07:21:58

seth
Member
Registered: 2012-09-03
Posts: 60,785

Re: [SOLVED] zsh, weird behavior if I `alias` before function definition?

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

#6 2024-09-04 12:25:20

FishBoneEK
Member
Registered: 2023-09-26
Posts: 57

Re: [SOLVED] zsh, weird behavior if I `alias` before function definition?

seth wrote:

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

#7 2024-09-04 14:05:58

seth
Member
Registered: 2012-09-03
Posts: 60,785

Re: [SOLVED] zsh, weird behavior if I `alias` before function definition?

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

#8 2024-09-20 11:31:40

FishBoneEK
Member
Registered: 2023-09-26
Posts: 57

Re: [SOLVED] zsh, weird behavior if I `alias` before function definition?

seth wrote:

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.

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

#9 2024-09-20 13:43:03

seth
Member
Registered: 2012-09-03
Posts: 60,785

Re: [SOLVED] zsh, weird behavior if I `alias` before function definition?

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

#10 2024-09-21 08:13:56

FishBoneEK
Member
Registered: 2023-09-26
Posts: 57

Re: [SOLVED] zsh, weird behavior if I `alias` before function definition?

seth wrote:

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

Board footer

Powered by FluxBB