From: Rick DeNatale Date: 2006-09-14T05:03:01+09:00 Subject: Re: How about Enumerable#find_pattern? On 9/12/06, A. S. Bradbury wrote: > On Tuesday 12 September 2006 19:50, Rick DeNatale wrote: > > Nice, but it can fall down if the pattern contains a regexp which > > matches more than one element: > > > > a = "aaaabbabbab".split(//) > > a.find_pattern /aab/, 'b' #=> nil > > > > There's probably a way to fix that, but I'm not sure I can see how. > > I'd actually argue that's expected behaviour and you're just using it > wrong(!). /aab/ simply doesn't match any element, so it *should* fail. Well, I'd expect that if you allow regexps that you should allow regexps! But see below. > The > main problem with my current implementation is it doesn't really skip ahead > when it should do, it just continues to the next iteration. This is where > it's easier when you're using an index and a while loop (and the object > responds_to []), but we can't assume that for an Enumerable-compatible > implementation. > > The Enumerable mixin provides #to_a, but relying on this seems like a poor > solution... Not sure why. > > I did a pretty slavish translation to ruby of the KMP algorithm as > > given in the Wikipedia article. It involved turning the enumerable > > into either an array or a string so that it could be indexed instead > > of using each. That didn't allow regexps at all though. > > > I've been working on hacking that to work with regexps, but that would > > really only work if the enumerable was a string anyway, so it would > > probably be better to do a specialized implementation in String. > > The string approach really doesn't seem like the right way to go about this, > if I understand you correctly. Not for the problem I'm trying to solve at > least. The idea of #find_pattern is that it will work for any arbitrary > object. But then regexps won't work except for a string. Also, strings are a funny kind of enumerable here, since by default, they just yield themselves in each, unless they include newlines. I'd think that the general use of find_pattern in a string would be to search for the pattern in the string, not as a pattern of the lines in the string. > Perhaps you should be able to specify a comparison function in a block upon > calling find_pattern. Of course this would require careful interface design to expand the generality while preserving the efficiency. -- Rick DeNatale My blog on Ruby http://talklikeaduck.denhaven2.com/