Mailing List Archive: 49091 messages
  • Home
  • Script library
  • AltME Archive
  • Mailing list
  • Articles Index
  • Site search
 

[REBOL] Re: How can one use named constants in switch?

From: joel:neely:fedex at: 25-Oct-2001 6:09

Hi, David, Use REDUCE to get the values (it leaves sub-blocks invariant). David Hawley wrote:
> I just spent a while trying to figure out why the following fails: > > case_a: 1 > case_b: 2 > > msgType: getMsg ... ; integer! > > switch msgType [ > case_a [ msgA ] > ... > ] > > this fails since the cases are variables not constants (from a C > perspective where case_X would be an enum or #define). Is there > any way to write this except > > switch msgType [ > 1 [ msgA ] > ... > ] >
In your SWITCH block above, CASE_A is a word, and the comparison is made to the word itself, not the value bound to that word. This example shows the types of values in the block:
>> ONE: 1
== 1
>> TWO: 2
== 2
>> THREE: 3
== 3
>> actions: [
[ ONE [print "one"] [ TWO [print "two"] [ THREE [print "three"] [ ] == [ ONE [print "one"] TWO [print "two"] THREE [print "three"] ]
>> foreach item actions [print type? item]
word block word block word block
>> repeat i 4 [
[ switch/default i actions [ [ print "huh?" [ ] [ ] huh? huh? huh? huh? Since you want the value bound to each word, and not the word itself, to be the subject of comparison, you need to REDUCE the block (either in-line, or by caching a REDUCEd copy for re-use:
>> reduced-actions: reduce actions
== [1 [print "one"] 2 [print "two"] 3 [print "three"]]
>> foreach item reduced-actions [print type? item]
integer block integer block integer block
>> repeat i 4 [
[ switch/default i reduced-actions [ [ print "huh?" [ ] [ ] one two three huh?
>> repeat i 4 [
[ switch/default i reduce [ [ ONE [print "one"] [ TWO [print "two"] [ THREE [print "three"] [ ][ [ print "huh?" [ ] [ ] one two three huh? It helps to remember that REBOL is a *very* literal language! ;-) HTH! -jn- -- ; sub REBOL {}; sub head ($) {@_[0]} REBOL [] # despam: func [e] [replace replace/all e ":" "." "#" "@"] ; sub despam {my ($e) = @_; $e =~ tr/:#/.@/; return "\n$e"} print head reverse despam "moc:xedef#yleen:leoj" ;