* activate alias inside subshell
@ 2018-04-06 16:29 Ray Andrews
2018-04-07 19:57 ` Ray Andrews
0 siblings, 1 reply; 8+ messages in thread
From: Ray Andrews @ 2018-04-06 16:29 UTC (permalink / raw)
To: Zsh Users
Sourcing this:
mag=$'\e[35;1m'
cyn=$'\e[36;1m'
nrm=$'\e[0m'
alias msg='echo $cyn alias outside $nrm'
whence -v msg
msg "called outside"
function test1 ()
{
(
msg "called inside"
unalias msg
alias msg='echo $mag alias inside $nrm'
whence -v msg
msg "called inside function"
)
}
echo "\nnow test:\n"
test1
whence -v msg
msg "called outside function"
echo "\n==================================\n"
I get:
15 /aWorking/Zsh/Source/Wk 7 $ . test1
msg is an alias for echo $cyn alias outside $nrm << fine
alias outside called outside << fine
now test:
alias outside called inside << fine
msg is an alias for echo $mag alias inside $nrm << whence is correct
alias outside called inside function << but the old alias is used
anyway.
msg is an alias for echo $cyn alias outside $nrm << original alias
undisturbed, good.
alias outside called outside function << fine
==================================
... so I have an apparent localization of the alias as far as whence is
concerned but it is not acted upon. Can that be rectified? I tried a
few variations, one succeeds in having it exactly backwards, the
external alias is used inside and the redefined alias is used
externally, but a second run fixes that, it seems the alias must always
be defined before the function is sourced. Can we have instant
gratification with an alias change inside a function? I'd have thought
that the subshell would make it easy. In any case one would think that
the alias that whence reports would be the alias in effect.
What I'm actually trying to do is reduce verbosity of a function by
redefining various message printer functions as null. It works fine
with functions, but if the message printers are aliases (which seem to
be the only way to get: ${(%):-%x %I} ... line information printed, it
seems that can't be done in a function) ... then it goes sour. For example:
[[ "$vverbose" < 3 ]] &&
{
warningmsg () { ; }
}
... I kill the message by nullifying the function that prints it (it's
nothing but a colorized line). In the subshell it's all local, no
damage outside the function. But when debugging I like the line
numbers, so 'warningmsg' becomes an alias:
alias warningmsg=' echo -en "${(%):-%x %I}: " && magline ' # Just
colorizes. I wish we could do that in a function.
... but now, when I want to kill messages, as above, efforts to neuter
the alias fail. The whole thing is very suspect. I had thought to
redefine the alias like this:
local alias warningmsg='#'
... which is probably outrageous, but the idea is that it would turn the
text of the message into a comment. I'm probably best to forget the
whole thing, but I do love the line numbers and killing messages by
nullifying message functions works like a charm ... but not with
aliases. Can I have my cake and eat it too? Some elegant solution?
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: activate alias inside subshell
2018-04-06 16:29 activate alias inside subshell Ray Andrews
@ 2018-04-07 19:57 ` Ray Andrews
2018-04-08 7:39 ` Bart Schaefer
0 siblings, 1 reply; 8+ messages in thread
From: Ray Andrews @ 2018-04-07 19:57 UTC (permalink / raw)
To: zsh-users
> Some elegant solution?
>
> " As a consequence, aliases defined in a function are not
> available until after that function is executed. To be safe,
> always put alias definitions on a separate line, and do not use
> alias in compound commands.
>
> And another quote, this time from |zsh| manual:
>
> There is a commonly encountered problem with aliases illustrated
> by the following code:
>
> |alias echobar='echo bar';echobar|
>
> This prints a message that the command echobar could not be found."
>
Ok, that is clear. Too bad whence seems to report the thing as active,
that had me beating my head against the wall. Something like a runtime
expansion would be a nice option to have but it seems that unheard of.
But another mystery:
mag=$'\e[35;1m'
cyn=$'\e[36;1m'
nrm=$'\e[0m'
yelline () { echo -e "$yel$@$nrm" }
function msg () { echo -e "${grn}$@${nrm}" }
alias msg='yelline ${(%):-%x %I}:'
function test1 ()
{
(
whence -va msg; declare -f msg
msg one
msg () { echo nulled }
whence -va msg; declare -f msg
msg where has the alias gone?
echo "\n==========================\n"
)
}
Output:
$ . test1; test1
msg is an alias for yelline ${(%):-%x %I}: << fine
msg is a shell function from test1 << fine,
function is right and alias is there
msg () {
echo -e "${grn}$@${nrm}"
}
test1 14: one << fine, the alias is in effect.
msg is an alias for yelline ${(%):-%x %I}: << ok ..
msg is a shell function from test1 << ... but the
function is not updated and ...
msg () {
echo -e "${grn}$@${nrm}"
}
nulled << ... the
changed function now overrides the alias!
... in practice this is exactly what I need in the current situation --
to kill either function or alias, but it does seem strange that changing
a function causes it to override an alias. Is this documented somewhere?
>
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: activate alias inside subshell
2018-04-07 19:57 ` Ray Andrews
@ 2018-04-08 7:39 ` Bart Schaefer
2018-04-08 14:56 ` Ray Andrews
0 siblings, 1 reply; 8+ messages in thread
From: Bart Schaefer @ 2018-04-08 7:39 UTC (permalink / raw)
To: Zsh Users
I'm not going to try to respond blow-by-blow to your messages, because
there still seem to be some concepts about aliasing that we've
discussed in past threads that you don't appear to be applying.
Firstly, though, there's something that doesn't add up about your
"test1" example; as you quoted it, "yelline" references a variable
$yel that's never assigned, and if I attempt to replicate verbatim in
a freshly-started shell what you say you've done, I get exactly the
errors I expected:
% . test1; test1
test1:10: defining function based on alias `msg'
test1:14: parse error near `()'
zsh: command not found: test1
I suspect you're using a shell in which you've been running other
tests and something from an earlier experiment is spilling over to
confuse you. Either that, or you haven't actually shown us the full
contents of the "test1" file.
The fundamental thing you're forgetting is that aliases act by text
replacement. "whence" will tell you whether an alias WILL replace
text the NEXT time the lexer is invoked, but that has no meaning for
text that has previously been parsed. Function definitions are always
fully lexed+parsed before they are executed, so once a function is
defined any aliases it may have used have been replaced by the
expanded text of the alias and can never expand again.
We explained this several threads ago when you were shown the "eval"
example. "eval" runs the parser again so aliases have a chance to
expand.
Thus:
% alias msg='echo this is an alias'
% test1() { msg in test1 }
% functions test1
test1 () {
echo this is an alias in test1
}
%
See how the use of the alias is no longer present in the stored
definition of test1? Note that it's important that the alias and the
function were defined separately (in this example at separate PS1
prompts), so that the parser was run a second time AFTER the alias was
defined.
Compare running the parser only once, by using a multi-line construct
(I have started a fresh "zsh -f" for each of these examples even
though I've changed the function names to differentiate them):
% {
cursh> alias msg='echo this is an alias'
cursh> test2() { msg in test2 }
cursh> }
% functions test2
test2 () {
msg in test2
}
% test2
test2: command not found: msg
%
Here test2 was parsed at the same time as the alias command, so the
alias was not yet "active" when the body of test2 was read, and thus
the alias definition is both not expanded in test2 and also irrelevant
at the time the function is executed.
However, that has no bearing on what "whence" will say about the
current state of the alias at the time the function is executed:
% {
cursh> alias msg='echo this is an alias'
cursh> test3() { whence -v msg; msg }
cursh> }
% test3
msg is an alias for echo this is an alias
test3: command not found: msg
%
Something like this must be involved in producing the "nulled" output
from the example you posted.
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: activate alias inside subshell
2018-04-08 7:39 ` Bart Schaefer
@ 2018-04-08 14:56 ` Ray Andrews
2018-04-08 20:18 ` Bart Schaefer
2018-04-08 22:38 ` Ray Andrews
0 siblings, 2 replies; 8+ messages in thread
From: Ray Andrews @ 2018-04-08 14:56 UTC (permalink / raw)
To: zsh-users
On 08/04/18 12:39 AM, Bart Schaefer wrote:
> I'm not going to try to respond blow-by-blow to your messages, because
> there still seem to be some concepts about aliasing that we've
> discussed in past threads that you don't appear to be applying.
It does take a while for some things to stick, but they do stick
eventually. There are so many things assumed to be understood in the
culture. Misunderstood, answers don't really gel, the mind hunts for a
'get it' but the 'get it' is false. Like only recently do I finally
really get it as to bleeding newlines in arrays -- not there!
> Firstly, though, there's something that doesn't add up about your
> "test1" example; as you quoted it, "yelline" references a variable
> $yel that's never assigned,
Pardon, I try to copy in all the relevant bits and pieces from my
environment. That's just the code for 'yellow' of course. What's the
best way to run something as a test for fitness to export it, as to
here, for example? I mean a way of ensuring that it's entirely
self-contained as to things like that and nothing has been left out or
assumed?
> I suspect you're using a shell in which you've been running other
> tests and something from an earlier experiment is spilling over to
> confuse you. Either that, or you haven't actually shown us the full
> contents of the "test1" file.
Sure. As above, I'm always worried that there's some local setting or
glitch that makes my code invalid as far as other people pasting it from
an email and getting the same results. I need a sort of 'virgin' test
before sending these things on. Should have got that squared away years
ago.
> The fundamental thing you're forgetting is that aliases act by text
> replacement. "whence" will tell you whether an alias WILL replace
> text the NEXT time the lexer is invoked, but that has no meaning for
> text that has previously been parsed. Function definitions are always
> fully lexed+parsed before they are executed, so once a function is
> defined any aliases it may have used have been replaced by the
> expanded text of the alias and can never expand again.
Ok, so whence is simply obeying the 'not active till next time' rule.
Not very friendly but it is consistent with the law of aliases.
> % alias msg='echo this is an alias'
> % test1() { msg in test1 }
> % functions test1
> test1 () {
> echo this is an alias in test1
> }
> %
>
> See how the use of the alias is no longer present in the stored
> definition of test1?
That at least is exactly as I expect, it's a macro.
> Note that it's important that the alias and the
> function were defined separately (in this example at separate PS1
> prompts), so that the parser was run a second time AFTER the alias was
> defined.
>
> Compare running the parser only once, by using a multi-line construct
> (I have started a fresh "zsh -f" for each of these examples even
> though I've changed the function names to differentiate them):
Is 'zsh -f' the answer to the above -- a truly clean test of something?
> Here test2 was parsed at the same time as the alias command, so the
> alias was not yet "active" when the body of test2 was read, and thus
> the alias definition is both not expanded in test2 and also irrelevant
> at the time the function is executed.
So:
$ alias msg ... ; test2 () { msg }
and:
$ alias msg ...
$ test2 () { msg }
... are very different! In the former the alias is 'pending' in the
latter, it is active, yes? That's easy not to know.
> Something like this must be involved in producing the "nulled" output
> from the example you posted.
Ok, let me hack away at it a bit more. Nevermind whence, the only
serious issue is the way the redefined function seems to kill the alias
within the subshell within the calling function. Again, it turns out
that this is exactly what I want, but not something I understand. It is
as if the fact that the redefined function has the same name as the
alias overwrites the namespace within the subshell so the alias
vanishes. If so, that could be seen as a feature not a bug.
BTW, results are hugely different if the redefined message function is
redefined with or without 'function' prepended: " function msg () ... "
vs. " msg () ... ". Most comments found on the internet suggest there
should be no difference but that is not so, one changes things
externally, the other does not. It added to the confusion.
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: activate alias inside subshell
2018-04-08 14:56 ` Ray Andrews
@ 2018-04-08 20:18 ` Bart Schaefer
2018-04-08 20:54 ` Ray Andrews
2018-04-08 22:38 ` Ray Andrews
1 sibling, 1 reply; 8+ messages in thread
From: Bart Schaefer @ 2018-04-08 20:18 UTC (permalink / raw)
To: zsh-users
On Apr 8, 7:56am, Ray Andrews wrote:
}
} Is 'zsh -f' the answer to the above -- a truly clean test of something?
The first thing asked following most bug reports is "can you reproduce
this from zsh -f?" So yes. Start from -f and then load the minimum
number of changes to try what you want to try (e.g., add extendedglob
if necessary, zmodload zsh/parameter or other required modules, etc.).
} So:
}
} $ alias msg ... ; test2 () { msg }
}
} and:
}
} $ alias msg ...
} $ test2 () { msg }
}
} ... are very different! In the former the alias is 'pending' in the
} latter, it is active, yes? That's easy not to know.
Yes, that's correct. "alias" is really intended only to make interactive
shells easier (reduce typing), not to abbreviate scripts (even if the
script is going to be used interactively later).
} BTW, results are hugely different if the redefined message function is
} redefined with or without 'function' prepended: " function msg () ... "
} vs. " msg () ... ". Most comments found on the internet suggest there
} should be no difference
There's no difference when "msg" is not an alias. But in
msg() ...
the word "msg" is in command position and therefore subject to alias
expansion, whereas in
function msg () ...
it is *not* in command position and will not be alias-expanded.
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: activate alias inside subshell
2018-04-08 20:18 ` Bart Schaefer
@ 2018-04-08 20:54 ` Ray Andrews
0 siblings, 0 replies; 8+ messages in thread
From: Ray Andrews @ 2018-04-08 20:54 UTC (permalink / raw)
To: zsh-users
On 08/04/18 01:18 PM, Bart Schaefer wrote:
> On Apr 8, 7:56am, Ray Andrews wrote:
> }
> } Is 'zsh -f' the answer to the above -- a truly clean test of something?
>
> The first thing asked following most bug reports is "can you reproduce
> this from zsh -f?" So yes. Start from -f and then load the minimum
> number of changes to try what you want to try (e.g., add extendedglob
> if necessary, zmodload zsh/parameter or other required modules, etc.).
Thanks, I hate wasting everyone's time over really elementary issues
like that.
> } ... are very different! In the former the alias is 'pending' in the
> } latter, it is active, yes? That's easy not to know.
>
> Yes, that's correct. "alias" is really intended only to make interactive
> shells easier (reduce typing), not to abbreviate scripts (even if the
> script is going to be used interactively later).
I've always distrusted any sort of macro and I use aliases only in the
most limited way possible. The anomaly is with that 'print function and
line' code which seems to be impossible to put inside a function via
another function except via an alias IF you want to be able to turn it
on and off, thus the can of worms is opened and after that it becomes a
matter more of education. I do understand that " ${(%):-%x %I} " is a
parse time thing which is why that string can't be in a function called
by another function and report anything other than its position in the
immediate function, so the alias seems inevitable. If there was such a
thing as a runtime expansion of an alias, sorta an automatic 'eval',
that would be cool but I can believe that such a thing is just not on.
>
> } BTW, results are hugely different if the redefined message function is
> } redefined with or without 'function' prepended: " function msg () ... "
> } vs. " msg () ... ". Most comments found on the internet suggest there
> } should be no difference
>
> There's no difference when "msg" is not an alias. But in
> msg() ...
> the word "msg" is in command position and therefore subject to alias
> expansion, whereas in
> function msg () ...
> it is *not* in command position and will not be alias-expanded.
>
Ah!! Nuts ... I'm unconsciously thinking that a function definition is
somehow immune to alias substitution. Why would it be? And yes, the
'command position' thing is easy to forget about. I know it in theory
but in practice ...
Ok, I'll bet that's everything I need to understand my issue.
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: activate alias inside subshell
2018-04-08 14:56 ` Ray Andrews
2018-04-08 20:18 ` Bart Schaefer
@ 2018-04-08 22:38 ` Ray Andrews
2018-04-09 4:11 ` Ray Andrews
1 sibling, 1 reply; 8+ messages in thread
From: Ray Andrews @ 2018-04-08 22:38 UTC (permalink / raw)
To: zsh-users
> BTW, results are hugely different if the redefined message function is
> redefined with or without 'function' prepended: " function msg () ...
> " vs. " msg () ... ". Most comments found on the internet suggest
> there should be no difference but that is not so, one changes things
> externally, the other does not. It added to the confusion.
>
Well zsh-5.5 behaves quite differently with or without '-f':
# . test1; test1
test1:6: defining function based on alias `msg'
test1:16: parse error near `()'
zsh: permission denied: test1
... so it seems that I'm not going to get away with my previous
anymore. Is there a new strategy that might work? Nullify the
function and/or the alias? Really, just some way of stopping messages
from printing at all?
>
>
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: activate alias inside subshell
2018-04-08 22:38 ` Ray Andrews
@ 2018-04-09 4:11 ` Ray Andrews
0 siblings, 0 replies; 8+ messages in thread
From: Ray Andrews @ 2018-04-09 4:11 UTC (permalink / raw)
To: zsh-users
On 08/04/18 03:38 PM, Ray Andrews wrote:
>
>
> ... so it seems that I'm not going to get away with my previous
> anymore. Is there a new strategy that might work? Nullify the
> function and/or the alias? Really, just some way of stopping messages
> from printing at all?
>>
Heck it's easy, and no need for anything sick and twisted. Case closed.
Thanks for your patience Bart.
>>
>
>
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2018-04-09 4:11 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-04-06 16:29 activate alias inside subshell Ray Andrews
2018-04-07 19:57 ` Ray Andrews
2018-04-08 7:39 ` Bart Schaefer
2018-04-08 14:56 ` Ray Andrews
2018-04-08 20:18 ` Bart Schaefer
2018-04-08 20:54 ` Ray Andrews
2018-04-08 22:38 ` Ray Andrews
2018-04-09 4:11 ` Ray Andrews
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).