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

Re: tilde operator



- "Loren J. Rittle" <rittle@supra.rsch.comm.mot.com>:

| I have no idea if any gurus still read this mailing list, but...

They do.  i won't lay any claim to guruhood myself, but as a long-time
es user I think I can give a qualified answer to this one.

| Is the following correct behavior under es?

The short answer is yes.

| S rittle@supra; echo <={~ x1 x*}
| 0
| S rittle@supra; h=x*; echo <={~ x1 $h}
| 1
| S rittle@supra; h=x1; echo <={~ x1 $h}
| 0
| 
| It looks like patterns may be stored in variables, but wildcard
| patterns are not allowed (or working) when stored in variables.

That's right.  The assignment h=x* is a bit dangerous by the way:  If
any files in the current directory have names beginning with `x', h
will contain the list of these file names.  Otherwise, the assignment
is equivalent to h='x*' and so {~ x1 $h} is the same as {~ x1 'x*'}
which does not match.  You're really asking for a match with a literal
* here.

How to do what you want depends a lot on your circumstances.  A very
simple solution is

; fn xmatcher {~ $* x*}
; echo <={xmatcher x1}
0
; echo <={xmatcher y1}
1

But this does not help much if the pattern is coming from user input,
or if you wish to use it in several different contexts without typing
it several times.  In this case there is no way around using eval.

Beware:  Here be dragons.  Bourne shell programmers often need to use
eval due to the limited capabilities of sh.  This leads to obscure
programs with equally obscure bugs.  With es, you need to use eval
much less often, but when you do, as you do in this case, the result
can be equally hard to understand.

I include some experimental code I made a long time ago.  I haven't
used it much, so I am not too sure how solid it is.  But here it is,
for you to study.  Perhaps you can use these ideas to solve your own
problem.

## wild-match
#  Example usage:
#  wild-match '*.c' foo  ==  foo @{~~ $1 *.c} *.c
fn wild-match w fun {$fun <={eval 'I @{~~ $1 ' ^ $w ^ '}' $w}}

## wild-foreach
#  Example:  wild-foreach '*.C' @ f b{mv $f $b^.cc}
#            renames *.C to *.cc
#  Example:  wild-foreach '*-*' @ f b c {mv $f $c^-^$b}
#            renames foo-bar to bar-foo etc.
fn wild-foreach w fun {
  wild-match ( $w
               @ matcher files {for (f=$files) $fun $f <={$matcher $f}})}

Hmm, looking at it now, I find this kind of hard to read myself.
Well, haven't got the time to try to explain it right now.
I hope you can make some sense out of it:  Just take it slow and
figure out how the examples are evaluated.  Good luck.

- Harald