zsh-users
 help / color / mirror / code / Atom feed
* A method to not leak unneeded functions
@ 2019-09-29 22:22 Sebastian Gniazdowski
  2019-09-29 22:25 ` Sebastian Gniazdowski
  0 siblings, 1 reply; 4+ messages in thread
From: Sebastian Gniazdowski @ 2019-09-29 22:22 UTC (permalink / raw)
  To: Zsh Users

Hello,
it's often the case when one declares sub-functions inside an autoload
function. The function will leak into the shell and also get redefined
on the next run of the main function. Here's a method to prevent this
from happening:

local -a entry_funs
entry_funs=( ${(k)functions} )
trap "unset -f \"\${(k)functions[@]:#(${(j:|:)${(q@)entry_funs}})}\"
&>/dev/null" EXIT
trap "unset -f \"\${(k)functions[@]:#(${(j:|:)${(q@)entry_funs}})}\"
&>/dev/null; return 1" INT

It will unset any newly detected functions at the moment of leaving of
the main function.
-- 
Sebastian Gniazdowski
News: https://twitter.com/ZdharmaI
IRC: https://kiwiirc.com/client/chat.freenode.net:+6697/#zplugin
Blog: http://zdharma.org

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: A method to not leak unneeded functions
  2019-09-29 22:22 A method to not leak unneeded functions Sebastian Gniazdowski
@ 2019-09-29 22:25 ` Sebastian Gniazdowski
  2019-10-03 23:18   ` Sebastian Gniazdowski
  0 siblings, 1 reply; 4+ messages in thread
From: Sebastian Gniazdowski @ 2019-09-29 22:25 UTC (permalink / raw)
  To: Zsh Users

PS. The block of code should be added at the beginning of the autoload
file, after possible emulate -L zsh, or at least after `setopt
localtraps' (which is being done by the emulate builtin). After this
the setup is complete and the functions will get automatically unset.

On Mon, 30 Sep 2019 at 00:22, Sebastian Gniazdowski
<sgniazdowski@gmail.com> wrote:
>
> Hello,
> it's often the case when one declares sub-functions inside an autoload
> function. The function will leak into the shell and also get redefined
> on the next run of the main function. Here's a method to prevent this
> from happening:
>
> local -a entry_funs
> entry_funs=( ${(k)functions} )
> trap "unset -f \"\${(k)functions[@]:#(${(j:|:)${(q@)entry_funs}})}\"
> &>/dev/null" EXIT
> trap "unset -f \"\${(k)functions[@]:#(${(j:|:)${(q@)entry_funs}})}\"
> &>/dev/null; return 1" INT
>
> It will unset any newly detected functions at the moment of leaving of
> the main function.
> --
> Sebastian Gniazdowski
> News: https://twitter.com/ZdharmaI
> IRC: https://kiwiirc.com/client/chat.freenode.net:+6697/#zplugin
> Blog: http://zdharma.org



-- 
Sebastian Gniazdowski
News: https://twitter.com/ZdharmaI
IRC: https://kiwiirc.com/client/chat.freenode.net:+6697/#zplugin
Blog: http://zdharma.org

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: A method to not leak unneeded functions
  2019-09-29 22:25 ` Sebastian Gniazdowski
@ 2019-10-03 23:18   ` Sebastian Gniazdowski
  2019-10-03 23:25     ` Sebastian Gniazdowski
  0 siblings, 1 reply; 4+ messages in thread
From: Sebastian Gniazdowski @ 2019-10-03 23:18 UTC (permalink / raw)
  To: Zsh Users

i've noticed one thing: the need of "--" passed to unset, to be able
to unset dash-starting functions. The snippet is thus:

local -a ef
ef=( ${(k)functions} )
trap "unset -f -- \"\${(k)functions[@]:#(${(j:|:)${(q@)ef}})}\"
&>/dev/null" EXIT
trap "unset -f -- \"\${(k)functions[@]:#(${(j:|:)${(q@)ef}})}\"
&>/dev/null; return 1" INT
unset ef

That said, I've also noticed that the method is somewhat slow. For
2700 functions, the trap takes 0.39 seconds. If it could use the $ef
parameter, then it could do $${(k)functions:|ef} which I measured to
take only 1 ms. However, at the time of the EXIT trap, the local
parameters are being unset.

Is there any way to speed this up?

-- 
Sebastian Gniazdowski
News: https://twitter.com/ZdharmaI
IRC: https://kiwiirc.com/client/chat.freenode.net:+6697/#zplugin
Blog: http://zdharma.org

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: A method to not leak unneeded functions
  2019-10-03 23:18   ` Sebastian Gniazdowski
@ 2019-10-03 23:25     ` Sebastian Gniazdowski
  0 siblings, 0 replies; 4+ messages in thread
From: Sebastian Gniazdowski @ 2019-10-03 23:25 UTC (permalink / raw)
  To: Zsh Users

On Thu, 3 Oct 2019 at 23:18, Sebastian Gniazdowski
<sgniazdowski@gmail.com> wrote:
> Is there any way to speed this up?

Uhm, the solution is pretty obvious - to use a global ef-parameter. It
doesn't even need to be leaked outside the function - example snippet
for a `zpview' project:

typeset -g zpview_ef
zpview_ef=( ${(k)functions} )
trap "unset -f -- \"\${(k)functions[@]:|zpview_ef}\" &>/dev/null;
unset zpview_ef" EXIT
trap "unset -f -- \"\${(k)functions[@]:|zpview_ef}\" &>/dev/null;
unset zpview_ef; return 1" INT

As said, the method is fully instant, it takes only 1 ms to do the unset.
-- 
Sebastian Gniazdowski
News: https://twitter.com/ZdharmaI
IRC: https://kiwiirc.com/client/chat.freenode.net:+6697/#zplugin
Blog: http://zdharma.org

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2019-10-03 23:26 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-09-29 22:22 A method to not leak unneeded functions Sebastian Gniazdowski
2019-09-29 22:25 ` Sebastian Gniazdowski
2019-10-03 23:18   ` Sebastian Gniazdowski
2019-10-03 23:25     ` Sebastian Gniazdowski

Code repositories for project(s) associated with this public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).