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