Adam Turoff on Tue, 7 Mar 2000 01:24:03 -0500 (EST) |
Forwarded message: > From: abigail@delanet.com > Date: Tue, 7 Mar 2000 01:11:28 -0500 > To: Mark-Jason Dominus <mjd@plover.com> > Cc: phl@lists.pm.org > Subject: Re: Funky code thing (index-rindex) > Reply-To: abigail@delanet.com > > On Mon, Mar 06, 2000 at 10:54:45PM -0500, Mark-Jason Dominus wrote: > > > > Here's the thing I wanted to show, but I couldn't remember what it > > was: > > > > sub handle_parens { > > my ($t, $code, $o, $c) = @_; > > $o = '(' unless defined $o; > > $c = ')' unless defined $c; > > > > while ('true') { > > last if (my $cp = index $t, $c) < 0; > > last if (my $op = rindex $t, $o, $cp) < 0; > > $code->(substr($t, $op, $cp-$op+1)); > ^ Or perhaps: length $c? > > } > > > > return $t; > > } > > > > The thing I actually wanted to show was the > > > > last if (my ... ) > > > > in the middle, but when I got home and saw the context, I thought > > folks might be interested to see the whole thing. > > > > There are at least four features of note: > > > > 1. This shows the new method for handling strings with nested > > delimiters that I mentioned this evening. If you give it the > > string > > > > (1 (2) (3 (4)) 5) > > > > it will invoke $code on (2), then (4), then (3 ...), then (1 ... 5), > > in that order. Short descrition: The parentheses groups get > > handled in left-to-right order of their *close* parentheses. > > Yes, it's a recursive algorithm made sequential, except that you forget > about the stack and seek back in the string to find the opening delimiter. > > > 2. last if (my ... ) < 0 ; > > > > Clever innovation or horrid obfuscation? > > Somewhere in between. ;-) > > > 3. while ('true') { ... } > > > > Idiomatic or idiotic? > > My first reaction was "cute", immediately followed by "but it means the > same as: while ('false') { ... }". Perhaps not a good idea. > > I like to write my "infinite loop"s as bare blocks with a redo. > > > 4. Notice the way that $t gets modified. $code is supposed to look > > something like this: > > > > sub { $_[0] = '...' } > > > > The $_[0] is aliased to the actual argument, which is a substr() > > call. Thus assigning to $_[0] down in the $code actually modifies > > $t back in handle_parens. What do people think of this? I found > > it rather convenient to use, and had the idea that maybe other > > people would be able to use it easily without having to know how it > > was implemented. What verdict do you folks have? Do you find it > > sweet, sour, bitter, or salty? > > Dubious. It's an action at a distance, and it makes it easy to break your > program by just looking at the sub and rewriting (parts of it) in such a > way the trick doesn't work anymore. On the other hand, it is kind of cool. > > > Note also that this approach is quadratic in the length of the string, due > to the repeatedly seeking back and forth. But then, since you probably want > to remove the parens before futher processing, you're doing quadractic work > anyway. > > > If you don't modify the string, preprocessing the string and creating > a double linked list of positions of opening and closing delimiters > would turn it into a linear algorithm. But it would look way less cool. > Not to mention that with modern computers, you won't notice the quadratic > behaviour unless you have real long strings. > > > I just realized there's a danger if you want to generalize this to > delimiters longer than one character. Suppose you do this, and your > opening and closing delimiters are '/*' and '*/', then with a substring of > '/*/*', you will find the '*/' as closing delimiter, find the overlapping > '/*' as opening delimiter, and call the closure with '/*/' as substring. > > > > Abigail > **Majordomo list services provided by PANIX <URL:http://www.panix.com>** **To Unsubscribe, send "unsubscribe phl" to majordomo@lists.pm.org**
|
|