Hi Andrew,

You can do Patch_to-func a lot more easily if you use the latest version
of HUH (not yet available on rebol.org).

>> patch_to-func
Can't convert to-bin
Can't convert to-bin2
Can't convert to-bits
Can't convert to-idate
Can't convert to-matrix
Can't convert to-native    ; this isn't what you think!
>> source to-paren
to-paren: func ["Converts to paren value." value "Value to convert"]
    [to paren! :value]
>> source to-money
to-money: func ["Converts to money value." value "Value to convert"]
    [to money! :value]


See you,
Eric

==========

Patch_to-func: function [][Old_to-Func][
        foreach to-type huh/ret "to-*" function? [
                Old_to-Func: get to-type
                either 'value = last second :Old_to-func [
                        do reduce [
                                to set-word! to-type
                                'func
                                copy third :Old_to-func
                                head change back tail copy second :Old_to-func first 
[:value]
                        ]
                ][print ["Can't convert" to-type]]
        ]
]

; new HUH (actually it's old - never got around to posting it)
; /verbose and /ret refinements not available in the one on rebol.org
; /verbose can be very very verbose!

huh: func [
    {Print a list of globally defined words classified by datatype}
    'pattern [word! string! unset!]  "matching pattern (. and * wild)"
    'type    [word! unset!]          "datatype test function (eg series?)"
    /any     {displays words containing any type of value, even unset}
    /verbose {display help for all words}
    /wc      {use ? and + for wild cards}
        /ret     {return the block of words}
    /local tester word-array this-type ret-block
][
    either value? 'type [
        if unset? get/any type [
            print [type "has no value"]
            exit
        ]
                tester: get type
                if datatype! = type? :tester [
                        tester: get to-word head change back tail mold tester "?"
                ]
                if not type-tester? :tester [
                        print [type "is not a datatype test function"]
                        exit
                ]
        if do [tester] [any: true]     ; if tester is UNSET? or ANY-TYPE?
    ][ tester: none ]

    either wc [wc: "?+"][wc: ".*"]
    either value? 'pattern
        [pattern: to-string pattern]
        [pattern: to-string last wc]   ; assign wildcard to match any string

    word-array: copy []                ; to hold matching words
    foreach word first system/words [
        this-type: mold type? get/any word: in system/words word
        if all [
            system/words/any [
                this-type <> "unset!"  ; ignore unset values
                any                    ; unless we got the /any refinement
            ]
            system/words/any [
                not :tester            ; unless we aren't using tester,
                tester get/any word    ; check with datatype test function
            ]
            "" = find/match/with word: mold word pattern wc
        ][
            either find word-array this-type
                [append select word-array this-type word]
                [append word-array reduce [this-type reduce [word]]]
        ]
    ]
    either tail? word-array [
        print "no matching words found"
    ][
                if ret [
                        ret-block: copy []
                        foreach [this-type word-block] word-array [
                                foreach word sort word-block [
                                        insert tail ret-block in system/words to-word 
word
                                ]
                        ]
                        return ret-block
                ]
        foreach [this-type word-block] sort/skip word-array 2 [
            print join newline ["@@ " this-type]
                        either verbose [
                        foreach word sort word-block [
                            prin join ">> " [word ": "]
                            either any-function? get/any to-word word [
                                do join "help " word
                                print ""
                            ][
                                either this-type = "unset!" [
                                    print "has no value"
                                ][
                                                        either this-type = "error!" [
                                                                print mold disarm get 
to-word word
                                                        ][
                                            word: get to-word word
                                            either this-type = "object!" [
                                                                        print ""
                                                qt first word
                                            ][
                                                print mold word
                                            ]
                                                        ]
                                ]
                            ]
                        ]
                        ][
                                qt sort word-block     ; qt defined in %format.r
                        ]
        ]
    ]
]

; useful for debugging with HUH - see if any words that should be local
; are "leaking" through

data?: func [
    {returns TRUE for all data types except unset, any-function and datatype}
    value [any-type!]
][
    either any [
        not value? 'value
        any-function? :value
        datatype? :value
    ][false][true]
]

not?: func [
    {returns TRUE for NONE and FALSE - returns FALSE for all other values}
    value [any-type!]
][
    either any [
        not value? 'value
        error? :value
        :value
    ][false][true]
]

type-tester?: func [
        {Returns TRUE if VALUE is a datatype test function}
        value [any-type!]
][
        either any [
                not value? 'value
                not any-function? :value
                not find/only third :value reduce [any-type!]
                find third :value lit-word!
                not string? first third :value
                not find first third :value "Returns TRUE"
        ][false][true]
]

; abbreviated version of QT in format.r
; handy for lots of things, such as seeing what words are defined in
; an object.

qt: func [
    {Quick table: prints out a simple block in aligned columns}
    b [any-block! object!]
    /width     max     [integer!]
    /local s rm
][
; RIGHT-MARGIN may be globally set to control the length of each line
; print out.
; If B contains nested blocks, each nested block will be individually
; print out.
; QT will try to guess if decimals should be printed out as decimals or
; as integers, but it won't always guess right.
    if object? b [
        b: first b
    ]
    no-decimal: true
    rm: either value? 'right-margin [right-margin][77]
    if not width [
        max: 0
        foreach a b [
            if all [not object? a not any-block? a] [
                max: maximum max  length? form a
            ]
        ]
        max: max + 2
    ]
    s: 0
    foreach a b [
        either any [any-block? a object? a ][
            print "^/(nested)"
            qt a
            s: 0
        ][
            s: s + max
            if s > rm [
                print ""
                s: max
            ]
                        a: form a
            prin head insert/dup tail a " " (max - length? a)
        ]
    ]
    print ""
    exit
]

Reply via email to