On Sat, Nov 27, 2021 at 8:36 AM Thiede, Christoph <Christoph.Thiede@student.hpi.uni-potsdam.de> wrote:

What about


{ '{|'  . '|-' . '|}' . '{{' . '}}' .  '[[' . ']]' . '__' . '==' . '::' . '**' . '##' . '''' } anySatisfy: [:pattern | self match: pattern]


?


Maybe also this one if the identity of the matching pattern is of interest:


{ '{|'  . '|-' . '|}' . '{{' . '}}' .  '[[' . ']]' . '__' . '==' . '::' . '**' . '##' . '''' }

    detect: [:pattern | self match: pattern]

    ifFound: [:pattern | self inform: 'Matched pattern: ' , pattern]

    ifNone: [self inform: 'no match']


Best,

Christoph


PS: Don't use #| unless you explicitly want every method to be invoked always. Use #or:... instead, this is faster.


And just as importantly, never use a brace construct when a literal array will do.  { '{|'  . '|-' . '|}' . '{{' . '}}' .  '[[' . ']]' . '__' . '==' . '::' . '**' . '##' . '''' } is created at run-time.  The equivalent #('{|' '|-' '|}' '{{' '}}' '[[' ']]' '__' '==' '::' '**' '##' '''')  is created at compile-time.  Inspect the method in the browser or the debugger and have a look at the bytecode.

If performancer is important you'll construct a parser of some form.  For example, the simplest optimization here is to check if the first character is a candidate and then if the second character is a candidate.  In a parser you'd have different code executed for each first character candidate.  But the below avoids doing a match until we know both characters are in the set.  I've written it as a doit bit I'm imagining Firsts and Seconds are class or instance variables (the issue here is provided the matcher is called often we want Firsts and Seconds to be computed precisely once).

| patterns first second Firsts Seconds |

patterns :=  #('{|' '|-' '|}' '{{' '}}' '[[' ']]' '__' '==' '::' '**' '##' '''').
Firsts ifNil:
   [Firsts := (patterns collect: #first) as: String.
    Seconds  := (patterns collect: #second) as: String].
self size >= 2
and: [(Firsts includes: (first := self first))
and: [(Seconds includes: (second := sef second)
and: [patterns includes: (ByteString with: first with: second)]]]


Von: Squeak-dev <squeak-dev-bounces@lists.squeakfoundation.org> im Auftrag von gettimothy via Squeak-dev <squeak-dev@lists.squeakfoundation.org>
Gesendet: Samstag, 27. November 2021 17:30:38
An: squeak-dev
Betreff: [squeak-dev] Anybody got an elegent construct for this functional monstrosity?
 
I have a ReadStream and I want to detect some substrings in it.

This works, but it is ugly.


((self match:'{|') |
(self match:'|-') |
(self match:'|}') |
(self match:'{{') |
(self match:'}}') |
(self match:'[[') |
(self match:']]') |
(self match:'__') |
(self match:'==') |
(self match:'::') |
(self match:'**') |
(self match:'##') |
(self match:'''') )

Is anybody aware of an elegant approach to this?


Something along the lines of 


self matchAny: { '{|'  . '|-' . '|}' . '{{' . '}}' .  '[[' . ']]' . '__' . '==' . '::' . '**' . '##' . '''' }


thx in advance




--
_,,,^..^,,,_
best, Eliot