0

给定一个子列表,有没有办法获得对它的父/封闭列表/块的引用?例如:

fs: [
 usr [
  local [
   bin []
  ]
  share []
 ]
 bin []
]

l: fs/usr/local ;grab a sublist
p: none ;now grab l's parent (which is fs/usr) without hardcoding the path

谢谢你的帮助!

4

1 回答 1

4

块没有“父”引用!系列,因为它可以从多个其他块中引用!系列,所以在这种情况下,“父母”的概念是没有意义的。

但是,您可以在需要时在块中手动添加反向引用(然后在 PROBE-ing 或 MOLD-ing “子”块时要小心,这将导致取消引用指向的块,从而导致更冗长的结果比你想要的)。

提示:我有时会使用“隐藏”标头为块值添加反向引用(只需移动块偏移量即可传递您想要隐藏的值)。它是 PROBE-resistant 和方便的,但不能序列化(例如在磁盘上),而无需编写自己的特定序列化例程来适当地处理这些反向引用(意味着通常用非序列值替换它们:整数、单词、问题,标签......任何允许您在加载后重建该链接)。

例如:

>> x: [1 2 3]
== [1 2 3]
>> y: [a b c]
== [a b c]
>> insert/only x y            ; insert a reference to y in x
== [1 2 3]
>> x
== [[a b c] 1 2 3]            ; y reference is at first position
>> x: next x                  ; let's hide it now
== [1 2 3]
>> x
== [1 2 3]
>> x/-1                       ; here is how to retrieve our "hidden" header
== [a b c]

请注意 /-1 快捷方式目前在 R3 中不像在 R2 中那样工作。

因此,对于上面您自己的代码示例,您需要创建一个函数来深入您的初始块结构并插入那些隐藏的反向引用,以便您可以在需要时轻松访问它们。这是处理您的结构的示例代码:

insert-back-ref: func [blk [block!] parent [block! none!]][
    if parent [                     ;-- no processing if root call
        insert/only blk next head parent ;-- insert the back-reference in child
        parent/1: blk: next blk     ;-- reset the parent reference to child to
    ]                               ;-- point after the back-ref (and hide it)
    forall blk [
        if block? blk/1 [              ;-- if a child block is found
            insert-back-ref blk/1 blk  ;-- process its content recursively              
        ]
    ]
]

insert-back-ref fs none            ;-- pass none as root parent

?? fs
l: fs/usr/local
?? l
p: l/-1
?? p
p: p/-1
?? p

这将输出:

fs: [
    usr [
        local [
            bin []
        ]
        share []
    ]
    bin []
]
l: [
    bin []
]
p: [
    local [
        bin []
    ]
    share []
]
p: [[
        local [
            bin []
        ]
        share []
    ]
    bin []
]

实际上,我们使用嵌套块引用创建了一个图形结构,可以使用内置的系列动作和路径非常简单地进行导航。

于 2013-03-12T17:10:31.653 回答