交错块,或从两个块中创建对象(字段名称和值)

时间:2013-08-21 02:26:22

标签: object rebol rebol3

而不是通过写作来创建对象:

obj: object [
    name: "Fork"
    id: 1020
]

我想写点像......

obj: something-or-another [name id] ["Fork" 1020]

...并得到相同的结果。理想的解决方案还允许:

obj: something-or-another [name: id:] ["Fork" 1020]

something-or-another很容易,但这是否适合“盒子里”?

3 个答案:

答案 0 :(得分:3)

我不相信有这样做的方式。虽然不难:

func [words values][
    set words: context append map-each word words [to set-word! word] none values
    words
]

我想我可以稍微分解一下:

func [
    "Creates an Object From a Block of Words, Assigns Values"
    words [block!] "Words used to create object"
    values "Value(s) to assign"
][
    words: map-each word words [to set-word! word] ; The requisite set-words
    append words none ; Initial value for all words
    words: context words ; Create our object
    set words values ; Assigns our value(s) to the object
    words ; returns the object
]

您可以使用不同的方法来交错块,例如:

func [words [block!] values [block!]][
    collect [
        repeat index max length? words length? values [
            keep words/:index
            keep values/:index
        ]
    ]
]

答案 1 :(得分:2)

这至少需要Rebol 3:

func [
    "Create an object based on some words and values."
    words [any-word! block!] "Word or block of words"
    values [any-type!] "Value or block of values"
    /local object
][
    object: make object! either block? words [length? words] [1]
    set bind/copy/new :words object :values
    object
]

如果您还想允许设置未设置的值,请​​尝试以下操作:

func [
    "Create an object based on some words and values."
    words [any-word! block!] "Word or block of words"
    values [any-type!] "Value or block of values"
    /any "Allows setting words to any value, including unset"
    /local object
][
    object: make object! either block? words [length? words] [1]
    apply :set [bind/copy/new :words object :values any]
    object
]

这两个都使用self创建对象,所以如果你想创建一个没有self的对象,你必须做一些更高级的技巧。有关详细信息,请参阅the selfless proposal

答案 2 :(得分:1)

几天前我写了一个类似的功能(Rebol2):

build-object: func [
    "Builds an object from a block"
    names [block!] "Field names"
    /values val [block!] "Initial values"
    /local o name value
] [
    o: copy []
    names: compose names
    o: either values [
        parse names [
            some [
                set name [word! | set-word!]
                (append o to-set-word name)
                | skip
            ]
        ]
        set/pad reflect o: context append o none 'words val
        o
    ] [
        if any [
            parse names [
                some [
                    set name [word! | set-word!]
                    (append o reduce [to-set-word name none])
                ]
            ]
            parse names [
                (clear o) some [
                    set name [word! | set-word!] set value any-type!
                    (append o reduce [to-set-word name :value])
                ]
            ]
        ] [context o]
    ]
    o
]

要构建您的对象,您可以编写以下任何一项:(创建一个函数f: does ["x"]

  • build-object [name "Fork" id 1020]
  • build-object [name: "Fork" id: 1020]
  • build-object/values [name id] ["Fork" 1020]
  • build-object/values [name: id:] ["Fork" 1020]
  • build-object [name f]
  • build-object [name (f)] ;block is composed
  • build-object [name 5 id f]
  • build-object [name 5 id 'f]

如果您保留值,您也可以将字段设置为none的对象,例如与

build-object [name id]