A terrifying Presource macro: #tclCase:choose:


In reference to a comment about Tcl switch, enjoy a #tclCase:choose: macro for Presource. I reproduce its class comment here:

TclSwitchMacro comment:
I expand the #tclCase:choose: pseudo-message macro, which efficiently implements something approximating the Tcl `switch' command.

A #tclCase:choose: message looks like this:

 someInput tclCase: #(#regex #nocase) choose:
     {'^<?xml' -> [#xmlFile].
      '<html>' -> [#htmlFile]}.

This macro matches the receiver against the keys in the choose: list in turn, invoking the first block that matches, and answering its result.

Exactly what "match" means is determined by the tclCase: arguments, which must be a literal array of symbols or a single symbol. For a traditional case/switch that works with any kind of value, just use #exact here. Also available are #glob, which uses Smalltalk's traditional #match: message on strings, and of course #regex (aka #regexp), which matches regular expression keys. Any of these accept the #nocase modifier, which enables case-insensitivity, and the default is #exact.

It does not make sense to match anything but strings if you use any tclCase: arguments other than #exact, and you are likely to get a runtime error if you do this.

Regex mode also supports the #sendMatch option, meaning it will send the RegexResults object to the associated block on successful match. All your blocks must accept this argument if you use this option.

Finally, there is a major performance penalty if you use #(#regex #nocase) with non-literal match keys, because I must recompute these regular expressions on every test. This issue does not affect regexes specified literally, because I fix those at compile time. Be aware of this issue in performance-critical situations.

You may note that this macro has far too many DWIM-style matching features, making it a summarily insane macro. This is because it is a demonstration that Presource lets you bring all kinds of syntax into Smalltalk, whatever the wisdom of such things.

User login