Rebol [
    Title: "Get-Path"
    Date: 04/01/02
    File: %getpath.r
    Email: rotenca@libero.it
    Author: "Romano Paolo Tenca"
    Version: 1.0.4
    Category: [Script util 2]
    History: [
        1.0.4 04/01/02 "added block/word"
        1.0.3 22/12/01 "corrected get-word return"
        1.0.2 09/12/01 "changed catch, no more throw on error"
        ]
    Purpose: {
        Like system get, but works with path also
        Examples:
            >> probe get-path 'system/words/do
            native
            >> probe get-path/ignore 'system/words/do/next
            native
            >> unset? get-path/any 'system/words/end!
            == true
    }
]
func-self: func [spec body][
    use [self-f] compose/deep [
        self-f: func spec [(body)]
    ]
]
Get-Path: func-self [
    {Get the value of a path
     Examples:
        >> probe get-path 'system/words/do
        native
        >> probe get-path/ignore 'system/words/do/next
        native
        >> unset? get-path/anyv 'system/words/end!
        == true
    }
    [catch]
    path [path! set-path! lit-path!]
    /any "Like /any in get/any"
    /ignore "Ignore functions refinements"
    /disarm "Disarm error found in path"
    /local b e get-in cp
][
    anyv: any
    any: get in system/words 'any
    change/only next third :self-f [catch]
    get-in: func [p w [word! get-word! integer! decimal!] /local res] [
        if get-word? :w [
            if error? try [error? w: get :w]
                [throw make error! reduce ['script 'no-value :w]]
        ]
        any [
            if all [any [integer? :w decimal? :w] any-block? :p] [
                if error? try [error? set/any 'res pick :p :w]
                    [throw make error! reduce ['script 'out-of-range :w]]
                true
            ]
            if all [word? :w any [object? :p error? :p]][
                if error? try [error? set/any 'res get/any in :p :w]
                    [throw make error! reduce ['script 'invalid-path :w]]
                true
            ]
            if any [block? :p hash? :p][
                all [set-word? :w w: to-word :w]
                if any [
                    not p: find :p :w
                    error? try [error? set/any 'res select :p :w]
                ]
                    [throw make error! reduce ['script 'invalid-path :w]]
                true
            ]
            if any-function? :p [
                if ignore [return :p]
                false
            ]
            if find [pair! file! url! date! time! tuple! email! event! money! image! struct!] type?/word :p [
                if error? try [return set/any 'p p/:w]
                    [throw make error! reduce ['script 'invalid-path :w]]
                true
            ]
            throw make error! reduce ['script 'invalid-path :w]
        ]
        if error? :res [return get/any 'res] ;because of set word changed by return
        get/any 'res
    ]
    b: first head insert/only copy [] :path
    if error? try [error? e: get first :b] [
        throw make error! reduce ['script 'no-value first :b]   
    ]
    while [b: next :b not tail? :b] [
        if error? set/any 'e get-in :e first :b [
            e: system/words/disarm :e
        ]
    ]
    if all [not value? 'e not anyv] [
        throw make error! reduce ['script 'no-value :path]
    ]
    change/only next third :self-f ""
    get/any 'e
]


;this can be removed
if not value? 'my_local_user [
    print system/script/header/Purpose
    ask "See the source for examples - Return to Quit - Esc for Shell "
    comment example: [
        a: context [error? e: make error! "aa" f: :view w: to set-word! 'k]
        probe get-path 'a/f
        probe get-path/disarm 'a/e
        probe get-path 'a/w
        halt
    ]
]