Object 交错块,或使对象由两个块(字段名和值)组成

Object 交错块,或使对象由两个块(字段名和值)组成,object,rebol,rebol3,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] 写一个什么东西或另一个很容易,但这是否适合已经“在盒子里”的东西?我不相信有现成的方法可以做到这一点。不过并不

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

obj: object [
    name: "Fork"
    id: 1020
]
我想写一些像

obj: something-or-another [name id] ["Fork" 1020]
…并得到同样的结果。理想的解决方案还将允许:

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

写一个
什么东西或另一个
很容易,但这是否适合已经“在盒子里”的东西?

我不相信有现成的方法可以做到这一点。不过并不难:

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

几天前,我编写了一个类似的函数(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”]

  • 生成对象[名称“Fork”id 1020]
  • build对象[名称:“Fork”id:1020]
  • 生成对象/值[name id][“Fork”1020]
  • 生成对象/值[名称:id:][“Fork”1020]
  • 生成对象[名称f]
  • 构建对象[名称(f)];块已组成
  • 生成对象[name 5 id f]
  • 生成对象[name 5 id'f]
如果忽略值,也可以创建字段设置为
none
的对象,例如

build-object [name id]

以下内容至少需要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
的对象,您必须执行一些更高级的技巧。有关详细信息,请参阅。

您的第一个代码示例(函数可能需要一个名称)简短明了,我认为它是最好的。有趣的是,它会在短时间内出现不止一次!也许这是一个经常出现的迹象,这里有些东西应该标准化。是否有理由这样表达您的
值规则
,而不是
任何类型的差异
?这是为了我的特殊需要。但你是对的,使用任何类型!可能有用。我用任何类型和一些小补丁编写了另一个版本,我应该编辑我以前的答案还是添加一个新答案?酷。一般来说,我认为最好编辑答案…(请注意,编辑历史记录是可用的,因此,如果任何人对注释感到困惑,他们可以回滚并查看旧版本。)好的,谢谢,我已经更新了函数并添加了更多示例。请注意,给定的块先合成,然后缩减。检查以下示例:
探测构建对象[a1b3c(f)daef]