How can one use named constants in switch?
[1/10] from: dlhawley::home::com at: 24-Oct-2001 21:33
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 ]
...
]
? Thanks,
Dave
--
David L. Hawley D.L. Hawley and Associates 1.503.274.2242
Software Engineer [David--L--Hawley--computer--org]
[2/10] from: cyphre:seznam:cz at: 25-Oct-2001 12:51
Hi David,
try this:
ca: 5
cd: 8
i: first random [5 8]
switch i reduce [
ca [print "five"]
cb [print "eight"]
]
regards,
Cyphre
[3/10] from: lmecir:mbox:vol:cz at: 25-Oct-2001 13:04
Hi Dave,
> I just spent a while trying to figure out why the following fails:
> case_a: 1
<<quoted lines omitted: 5>>
> ]
> 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 ]
> ...
> ]
>
> ? Thanks,
> Dave
There is, of course:
switch msgType reduce [
case_a []
...
]
[4/10] 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
<<quoted lines omitted: 11>>
> ...
> ]
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" ;
[5/10] from: greggirwin:mindspring at: 25-Oct-2001 11:32
Hi David,
In addition to the other replies you got, and hopefully not confusing the
issue, here are a couple other ways to look at things.
First, you could set MsgType to be the literal word matching the case you
want:
case_a: 1
case_b: 2
msgType: 'case_b
switch msgType [
case_a [print "msgA" ]
case_b [print "msgB" ]
]
Now, of course, that obviates the need for defining the case words! I don't
know the best way to emulate enums, for those of us accustomed to using
them, and I don't know that we need to, but here's a slightly more intuitive
approach which puts the words in a block:
cases: [case_a case_b]
msgType: second cases
switch msgType [
case_a [print "msgA" ]
case_b [print "msgB" ]
]
Now, you have quite a bit of flexibility using this approach as well. Being
a block itself, you can access the item you want a number of different ways.
>> first cases
== case_a
>> cases/2
== case_b
>> pick cases 2
== case_b
You can also access the entire block:
>> head cases
== [case_a case_b]
>> foreach case cases [print case]
case_a
case_b
...or find out where an item falls in the enum:
>> index? find cases 'case_a
== 1
>> index? find cases 'case_b
== 2
(note that we use a literal word for each case here)
You can also protect your block with one call to protect, which is kind of
nice.
I haven't looked into building an enum object or dialect, though you could
probably make REBOL do pretty much anything you want along those lines.
Also, I'm fairly new to REBOL myself so I don't know the pros and cons of
this approach as far as efficiency, binding issues, etc. I'd love for some
experts to chime in and give their opinions.
--Gregg
[6/10] from: phil:hayes:cnutarch at: 25-Oct-2001 18:55
David,
How about ? A little neater ..
set [ CASE_A CASE_B ] [ 1 2 ]
msgType: 'CASE_B
switch msgType [
CASE_A [ print "A" ]
CASE_B [ print "B" ]
]
Phil
[7/10] from: dlhawley:home at: 25-Oct-2001 10:54
Thanks for the great replies everybody. Now I have another question: Is there
a way to pass data into predefined cases?
cases: reduce [
ca [print ["five:" msg]]
cb [print ["eight:" msg]]
]
switch first msg cases
This isn't that big of a deal since I don't really have to predefine the cases...
but I figure that I'll learn more re REBOL
Dave
Previously, you (Cyphre) wrote:
> Hi David,
> try this:
<<quoted lines omitted: 55>>
> [rebol-request--rebol--com] with "unsubscribe" in the
> subject, without the quotes.
--
David L. Hawley D.L. Hawley and Associates 1.503.274.2242
Software Engineer [David--L--Hawley--computer--org]
[8/10] from: joel:neely:fedex at: 25-Oct-2001 14:48
Hi, Gregg,
OUTSTANDING!
Gregg Irwin wrote:
> First, you could set MsgType to be the literal word matching
> the case you want:
<<quoted lines omitted: 8>>
> words! I don't know the best way to emulate enums, for those
> of us accustomed to using them, and I don't know that we need to...
You are *SO* right. The whole origin of "enums" was a way to
give a meaningful name to a concept in program text (although
the primitive language underneath required/preferred that the
actual data be numbers).
The main advantage to using words as names for code numbers
is that the data become portable across programs, languages,
machines, etc. However, the I/O translation routines could
be the place where those issues are encapsulated.
-jn-
--
This sentence contradicts itself -- no actually it doesn't.
-- Doug Hofstadter
joel<dot>neely<at>fedex<dot>com
[9/10] from: joel:neely:fedex at: 25-Oct-2001 15:01
Hi, David,
David Hawley wrote:
> Thanks for the great replies everybody. Now I have another
> question: Is there a way to pass data into predefined cases?
<<quoted lines omitted: 6>>
> predefine the cases... but I figure that I'll learn more
> re REBOL
I may have misunderstood, but you don't have to do anything to
put data "into" the nested blocks. REDUCEing a block leaves
nested blocks alone, so words in the nested blocks are not
evaluated (until called for).
I don't think I said that very well, but look at this example:
>> set [ca cb cc cd] ["A" "B" "C" "D"]
== ["A" "B" "C" "D"]
>> cases: reduce [
[ ca [print ["five:" msg]]
[ cb [print ["eight:" msg]]
[ ]
== ["A" [print ["five:" msg]] "B" [print ["eight:" msg]]]
Notice that the embedded occurrences of MSG (and of PRINT, for
that matter) aren't yet evaluated. In fact MSG wasn't even
defined at that point. Now I can say:
>> msg: ["B" 42 "This is a test"]
== ["B" 42 "This is a test"]
to give MSG a value, and then say:
>> switch first msg cases
eight: B 42 This is a test
to cause evaluation of an expression for the current value
of MSG.
HTH!
-jn-
--
This sentence contradicts itself -- no actually it doesn't.
-- Doug Hofstadter
joel<dot>neely<at>fedex<dot>com
[10/10] from: greggirwin:mindspring at: 25-Oct-2001 14:20
Hi Dave,
<< Thanks for the great replies everybody. Now I have another question: Is
there
a way to pass data into predefined cases? >>
I'd probably make it a function if you need to do that. With REBOL, though,
there is so much flexibility that the best solution may often be dependent
on the context (no pun intended). I.e. what's best in the context of a
static application may totally miss the mark for a dynamic, data driven,
app.
--Gregg
Notes
- Quoted lines have been omitted from some messages.
View the message alone to see the lines that have been omitted