bug-bash
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: conditional aliases are broken


From: Linda Walsh
Subject: Re: conditional aliases are broken
Date: Thu, 18 Aug 2011 10:11:53 -0700
User-agent: Mozilla/5.0 (Windows; U; Windows NT 6.0; en-US; rv:1.8.1.24) Gecko/20100228 Thunderbird/2.0.0.24 Mnenhy/0.7.6.666




` Greg Wooledge wrote:
On Thu, Aug 18, 2011 at 08:03:41AM -0700, Linda Walsh wrote:
4.2 introduce a new -g to declare a global variable inside a function.
----
   Which doesn't say what it would do in situations like the above.

Then let's test:

imadev:~$ echo $BASH_VERSION
4.2.10(7)-release
imadev:~$ unset a b; unset -f f1 f2
imadev:~$ f1() { local a='tmp'; f2; }
imadev:~$ f2() { declare -g a b; a=3 b=5; }
imadev:~$ a=a b=b; f1; echo "a=<$a> b=<$b>"
a=<a> b=<5>

It would appear "declare -g" does NOT allow you to "jump over" a local
variable that is shadowing a global.  That's disappointing.

When I asked about defining a local var in a command in the context
of the caller, -- greg didn't even think of aliases, just inferred it
couldn't be done except by doing it in the caller -- i.e. manually
typing it in each time..  Not good!

If you're going to use the "magic aliases" or "upvar" hacks in your
scripts, please don't ever ask me to debug them.
---
   Not using any "magic aliases -- just aliases -- but since you didn't
know about aliases, then by definition ALL aliases are magic, so you got me
there!...Aliases are like "macros" (but w/o param substitution).

They are used in all sorts of languages usefully and aren't considered an
impediment to programing or understand -- when used rationally and in
defined ways! Sure, you can write garbage, but the point here is whether or
not I an increase readability and understanding by using an alias
vs. not.


Be fair -- your question did not ask how to do "call by reference"
in bash.
--- EXACTLY...I didn't bring up 4.2...

  You asked a very specific thing, and I gave a very specific
answer and example.  If you had wanted arbitrary call-by-reference
then I would have pointed you back to FAQ 6.
---
   Not knowing it by heart, I'll just say -- I wasn't asking for a general
C-B-R, I just wanted bash to handle ${#<word>[@]}, where word can now
only be a simple name of an array, but ''COULD" be a subexpression that
returns the name of an array...just that the parser isn't that bright.

   Please don't ask me to defend a position that I didn't take!  I'd have
to do preparation first, and I'm not sure I'd want to argue that position! ;-)


It's not that I "didn't think of" things.  It's that I *have* thought
about them in the past several years, and I know what is reasonable
and what is not.  Certain things cannot be achieved reasonably in bash,
and so we *don't do them* in bash, and we advise other people not to
do them either.
----
   I didn't ask for anything unreasonable.   But you didn't know about
bash's builtin macro ability being an ajunct to it's functions, so you would
rule out using many useful paradigms in bash that bash would support just
fine. If you had known the usefulness of "-e", in 3.0-4.0, you might have made
use of it.  now its broken garbage  -- have to follow every expression
with ||:  that's so attractive!  not to mention the ~5% performance it
for taking the or on the : expression (from primitive timings)...


Well, if you remember, this was a  4-bullet list of things to do, -- it's
been adding all the error checking and interlocks (as well as LOTS
of debug code) that have made it as complex as it is....


As for the case of needs to use macros(aliases)-- besides setting var
s in the right context, there's also setting *flags* (to set) in the correct
context.  Here was my usage:

(in the lib file)...

   alias DebugPop='test -n "$save_ops" && set -$save_ops'
   alias DebugPop_preserve_status='local stat=$?;test -n "$save_ops" &&
   { set -$save_ops; }; return $stat;'

   function DebugPush_helper {
       local dbgflgs="${-:-}";set +x;
       local flag="${1:?}"
       if chkflg Trace_off "$flag";then dbgflgs="${dbgflgs//x/}" ;fi
        if chkflg Trace_on "$flag" ;then dbgflgs="${dbgflgs}x"  ;fi
       if chkflg Local_Debug "$flag" ; then _Debug=1; else _Debug=0; fi
       test -n "$dbgflgs" && set -$dbgflgs
       return 0
   }
   alias DebugPush='local save_ops="${-:-}" _Debug=; DebugPush_helper'

I haven't used the preserve status one, as haven't needed it, but threw
it in as I thought I might. But in both cases any debug ops altered for the routine this was called in, are 'reset' upon exit, so I can turn on/off tracing in a function (or set other flags "+/-eu"...etc..., as well as set a func-specific debug
flag.


The resulting code is much cleaner looking than any of the alternatives:


function get_devname_of_mp {
   DebugPush MP_OPS
   if (($# < 1 )); then ; DebugPop; errx -9 "Internal error: ...";   fi
   local mp="${1:?}"
   local dev="$($_grep -P '\s'"$mp"'\s' /proc/mounts|$_cut -d\  -f1)"
   echo "$dev"
   DebugPop
}










reply via email to

[Prev in Thread] Current Thread [Next in Thread]