zsh-users
 help / color / mirror / code / Atom feed
* Is the function $f defined and is not an autoload stub?
@ 2016-06-15 23:24 Daniel Shahaf
  2016-06-16 16:16 ` Bart Schaefer
       [not found] ` <160616091615.ZM24804__45250.1349304386$1466093823$gmane$org@torch.brasslantern.com>
  0 siblings, 2 replies; 4+ messages in thread
From: Daniel Shahaf @ 2016-06-15 23:24 UTC (permalink / raw)
  To: zsh-users

export f=add-zle-hook-widget

I'd like to test whether the shell function $f is available (callable).

The naive solution, (( ${+functions[$f]} )), is not specific: it always
returns 1 after after 'autoload $f', even if the function is not
actually available (= calling it will fail with "zsh: $f: function
definition file not found").

The next candidate, «if autoload +X $f 2>/dev/null», is not idempotent:
it returns 'false' if «autoload +X $f» had already been run.

I suppose I could do this:
.
    if autoload +X -- $f 2>/dev/null;
       [[ "${${(@f)"$(which -- $f)"}[2]}" != $'\t'$histchars[3]' undefined' ]];
    then
    fi
.
but I'm hoping there's a saner way....

Thanks,

Daniel
(before you ask: I'd rather not use is-at-least because feature checks
are better than version checks)


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

* Re: Is the function $f defined and is not an autoload stub?
  2016-06-15 23:24 Is the function $f defined and is not an autoload stub? Daniel Shahaf
@ 2016-06-16 16:16 ` Bart Schaefer
       [not found] ` <160616091615.ZM24804__45250.1349304386$1466093823$gmane$org@torch.brasslantern.com>
  1 sibling, 0 replies; 4+ messages in thread
From: Bart Schaefer @ 2016-06-16 16:16 UTC (permalink / raw)
  To: zsh-users

On Jun 15, 11:24pm, Daniel Shahaf wrote:
}
} I'd like to test whether the shell function $f is available (callable).

I suppose for consistency "autoload xyz" should return false if the
function is already fully defined (though what to do in the case of
"autoload xyz pdq" where one is defined and the other is not is a
bit ambiguous even for the +X case).  Right now "autoload xyz" never
returns nonzero that I can tell.

Addressing the question of how to do it *now*, I think I'd choose to
do the test in a subshell so that testing doesn't change the state
of the calling shell.  If that's acceptable, then:

    if [[ "$functions[$f]" != *"builtin autoload -X" ]] ||
       ( unfunction -- "$f" && autoload +X -- "$f" ); then
        print "Hooray, $f is callable"
    fi

I prefixed the "builtin ..." with a * just in case at some point in
the future we begin including the "# undefined" comment in the body
for $functions[$f] the same way we do for $(functions $f).


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

* Re: Is the function $f defined and is not an autoload stub?
       [not found] ` <160616091615.ZM24804__45250.1349304386$1466093823$gmane$org@torch.brasslantern.com>
@ 2016-06-21  1:41   ` Daniel Shahaf
  2016-06-22 18:43     ` Bart Schaefer
  0 siblings, 1 reply; 4+ messages in thread
From: Daniel Shahaf @ 2016-06-21  1:41 UTC (permalink / raw)
  To: zsh-users

Bart Schaefer wrote on Thu, Jun 16, 2016 at 09:16:14 -0700:
> On Jun 15, 11:24pm, Daniel Shahaf wrote:
> }
> } I'd like to test whether the shell function $f is available (callable).
> 
> Addressing the question of how to do it *now*, I think I'd choose to
> do the test in a subshell so that testing doesn't change the state
> of the calling shell.  If that's acceptable, then:
> 

No objections to a subshell.  (I'd like to minimise the number of forks,
but a subshell v. a command substitution shouldn't make a difference.)

>     if [[ "$functions[$f]" != *"builtin autoload -X" ]] ||
>        ( unfunction -- "$f" && autoload +X -- "$f" ); then
>         print "Hooray, $f is callable"
>     fi
> 
> I prefixed the "builtin ..." with a * just in case at some point in
> the future we begin including the "# undefined" comment in the body
> for $functions[$f] the same way we do for $(functions $f).
> 

Thanks, this is saner.

> I suppose for consistency "autoload xyz" should return false if the
> function is already fully defined (though what to do in the case of
> "autoload xyz pdq" where one is defined and the other is not is a
> bit ambiguous even for the +X case).  Right now "autoload xyz" never
> returns nonzero that I can tell.

So, if I read you correctly, this would enable the idiom 'if autoload +X
$f; ! autoload $f; then' to test for fully-definedness?

I _would_ like having an API for this (as opposed to testing stringified
function bodies).  I don't know what it should look like, though; I just
know that I have a need for it.

The proposed would cause behaviour changes in certain cases: for
example, in the case of a plugin that calls 'autoload add-zsh-hook &&
add-zsh-hook foo bar' with errexit or printexitvalue in effect.  (Yes,
people do this: the idiom I learnt was "autoload foo && foo".)
[I'm not saying this is or isn't a problem; I'm simply stating a fact
about the proposed change.]

Cheers,

Daniel


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

* Re: Is the function $f defined and is not an autoload stub?
  2016-06-21  1:41   ` Daniel Shahaf
@ 2016-06-22 18:43     ` Bart Schaefer
  0 siblings, 0 replies; 4+ messages in thread
From: Bart Schaefer @ 2016-06-22 18:43 UTC (permalink / raw)
  To: zsh-users

On Jun 21,  1:41am, Daniel Shahaf wrote:
}
} > I suppose for consistency "autoload xyz" should return false if the
} > function is already fully defined (though what to do in the case of
} > "autoload xyz pdq" where one is defined and the other is not is a
} > bit ambiguous even for the +X case).  Right now "autoload xyz" never
} > returns nonzero that I can tell.
} 
} So, if I read you correctly, this would enable the idiom 'if autoload +X
} $f; ! autoload $f; then' to test for fully-definedness?

I was thinking more of "if ! autoload $f || autoload +X $f; then" but I
guess your way also works.  I might go so far as

  if (( $+functions[$f] )) && { ! autoload $f || autoload +X $f }; then

to avoid autoloading something that was never intended to be so, but it
depends on whether you already know $f is in $fpath or whatever.

} The proposed would cause behaviour changes in certain cases: for
} example, in the case of a plugin that calls 'autoload add-zsh-hook &&
} add-zsh-hook foo bar' with errexit or printexitvalue in effect.  (Yes,
} people do this: the idiom I learnt was "autoload foo && foo".)

Hmm.  Yes, that would be a possible issue in the case where something
else had already both autoloaded and executed $foo.

I just realized there's another way to distinguish autoloads from full
functions in current versions:

  if (( $+functions[$f] )); then
    if [[ -z ${(M)$(typeset +f -u):#$f} ]]; then
      print "$f is already fully defined"
    elif ( autoload +X $f ); then
      print "$f is callable"
    fi
  fi

Remove the subshell in the elif when you don't care whether you force
the function to load in the current shell.


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

end of thread, other threads:[~2016-06-22 18:42 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2016-06-15 23:24 Is the function $f defined and is not an autoload stub? Daniel Shahaf
2016-06-16 16:16 ` Bart Schaefer
     [not found] ` <160616091615.ZM24804__45250.1349304386$1466093823$gmane$org@torch.brasslantern.com>
2016-06-21  1:41   ` Daniel Shahaf
2016-06-22 18:43     ` Bart Schaefer

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).