Search code examples
conditional-statementsrebolrebol2

Rebol's either condition not working correctly


I'm trying to set a condition for evaluating the values of several text-lists. This works, using a SWITCH:

options: ["" "" "" ""]

view layout [
    text-list "one" "two" "three" "four" [poke options 1 value]
    button "test" [switch/default options/1 [
        "one" [alert "first"]
        "two" [alert "second"]
        "three" [alert "third"]
        "four" [alert "fourth"]
        ] [alert "pick a number!"]
    ]
]

But this one doesn't work for some reason:

options: ["" "" "" ""]

view layout [
    text-list "one" "two" "three" "four" [poke options 1 value]
    button "test" [
        either options/1 <> 0 [
          alert "you have picked a number!"
        ][alert "pick a number!"]
    ]
]

The EITHER evaluation always executes the first block if I put options/1 <> 0 as the condition, and always executes the second block if I put options/1 = 0 as the condition, which is obviously not how it should work at all.

What's the matter here?


Solution

  • You are using an empty string to indicate a "nothing" state. As @iceflow19 points out, strings and integers will never compare equal. If you want to know if a string is empty, use EMPTY? or compare literally against "" or {}.

    (Note: I usually prefer braced strings myself, and {It's cool that they {nest better} and can do "quotes" and apostrophe's [sic] without escaping.})

    Rebol has another possibility for representing nothingness, and that's a value whose type is NONE!. A nice property that a NONE! value has is that it will behave like a LOGIC! false value does as far as IF, UNLESS, and EITHER are concerned.

    value: none
    
    if value [print {this won't run}]
    
    unless value [print {this will run}]
    

    Some routines use a NONE! value as their return to indicate a normal "failure" condition. IF and UNLESS are such routines:

    >> print if 1 < 2 [{math is working}]
    math is working
    
    >> print if 1 > 2 [{math is broken}]
    none ;-- Rebol2 prints out the string representation of NONE!
    

    (Note: Rebol3 does not require you to put conditions to IF, UNLESS, or EITHER into a block if they are single values.)

    So you could have written:

    options: reduce [none none none none]
    
    view layout [
        text-list {one} {two} {three} {four} [poke options 1 value]
        button {test} [
            alert either options/1 [
                {you have picked a number!}
            ][{pick a number!}]
        ]
    ]
    

    The REDUCE is needed because blocks are not evaluated by default...and you would have the word none four times (vs. a value of type NONE!, to which NONE is bound).

    Note also that you can pass the result of a SWITCH or EITHER to alert, and it will be the last evaluation value of the branch that runs. Or none if no branch runs--as shown above.

    (Note: Constructs you might be wanting soon--if you haven't discovered already--are CASE and ALL.)