[REBOL] Re: I hate computers!
From: joel:neely:fedex at: 4-Jan-2003 11:20
Hi, Ed,
You're 95% there!!! (see below)
Ed Dana wrote:
> ... I whipped up a small routine to validate parameters. It is
> relatively simple, You pass it the parameter, you pass it a series
> full of datatypes, it compares the two and tells you if your
> parameter's datatype is valid (IOW, in the series).
>
> But it's actin' strangely.
>
It's doing just what you designed it to do. (Maybe you want to
design it to do something different... ;-)
> Here it is:
> ...
> The problem is in the line "If (Type? Parameter) = DataType" it just
> doesn't work. When I call the routine, it does this:
> >> Valid-Type? "x" [ String! Money! Integer! ]
> == false
>
> Which is incorrect. It should be "true" since "x" is clearly a string.
>
The problem is that your usage above isn't passing a block of types,
but a block of words! (Others have been bitten by this; wrapping a
collection of words in a block keeps them from being evaluated at
unless you expressly ask for DO or REDUCE at some point.)
>> foo: [string! money! integer!]
== [string! money! integer!]
>> foreach item foo [print type? :item]
word
word
word
>> foo: reduce foo
== [string! money! integer!]
>> foreach item foo [print type? :item]
datatype
datatype
datatype
We can fix this either of two ways:
1) either make sure that the calling expression really passes a
block of data types...
>> valid-type? "x" reduce [string! money! integer!]
== true
2) or rewrite your function to perform the reduction for you (
which is safe because reducing a block of data types gives
back a block of data types)...
======================================================================
valid-type?: func [
parameter [any-type!]
datatypes [series!]
][
foreach datatype reduce datatypes [
if datatype = type? parameter [
return true
]
]
return false
]
======================================================================
And now, if you'll pardon the editorializing, a couple of suggestions:
1) Use the standard REBOL conventions for code layout (including
capitalization) to make your code more readable to the widest
audience on the list.
2) Use the fact that parameters values are local to avoid having
to evaluate TYPE? PARAMETER over and over for all values in the
block of types.
3) Use the fact that the value of a function evaluation is the last
expression evaluated in the function (lose the RETURN in the
last line reading RETURN FALSE).
4) Use the fact that the value of a FOREACH is the last expression
evaluated inside the body. Use the fact that the value of an IF
expression is either the value of the controlled expression if
the guard is true or is NONE if the guard is false (and NONE acts
as false for most purposes).
In other words, of none of the tests succeed (causing the RETURN
TRUE to evaluate) then the last IF evaluates to NONE, and so does
the FOREACH, and therefore so does the entire function!
A version utlizing all of these hints appears as:
======================================================================
valid-type?: func [
parameter [any-type!]
datatypes [series!]
][
parameter: type? parameter
foreach datatype reduce datatypes [
if datatype = parameter [
return true
]
]
]
======================================================================
Hope this helps!
-jn-