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

[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-