跳转到内容

Rebol 编程/mold

来自维基教科书,开放的书籍,为一个开放的世界
MOLD value /only /all /flat 

将值转换为可读的 Rebol 字符串。

MOLD 是一个原生值。

将值转换为什么?

[编辑 | 编辑源代码]

文本“将值转换为可读的 Rebol 字符串。”是函数的帮助字符串。当 Rebol 是语言时,“可读的 Rebol”是什么意思?这并不难解决,可读的 Rebol 意味着“可被 Rebol 解释器读取”。为了进一步解释,这意味着字符串应该被识别为有效的 Load 方言,即在被 LOAD 函数处理时被接受为有效。

“旧”语法

[编辑 | 编辑源代码]

最初,Rebol 语法无法直接描述某些值。例如,

make object! [field: 1]

是一个 Rebol 表达式,可以加载并产生

load "make object! [field: 1]" ; == [make object! [field: 1]]

,它是一个包含三个值的块:两个字和一个(子)块。当由 DO 函数评估时,表达式产生一个对象。评估基于 Do 方言的语义属性,评估 MAKE 函数(Rebol 中最常用的构造函数之一),为它提供两个参数:要构造的值的类型(本例中为 OBJECT!)和规范块。

根据我们解释它的方式,上面的源代码可以描述某些块(当解释为 Load 方言时),也可以描述一个对象(当解释为 Do 方言时)。有人可能会认为,这种歧义很容易通过始终使用 Do 方言来解释源代码来解决,但是,只有稍微更复杂的例子会再次咬我们

string1: mold [make object! [field: 1]] ; == "[make object! [field: 1]]"
string2: mold reduce [make object! [field: 1]] ; == "[make object! [^/        field: 1^/    ]]"

上面的 STRING1 是对包含三个值的块进行模塑的结果,而 STRING2 是对包含一个元素的块进行模塑的结果:一个对象。无论 STRING1 或 STRING2 是仅由 LOAD 解释还是由 DO 评估,结果始终是一个包含三个元素的块:两个字和一个子块,即没有一种方法产生一个包含对象的块。

“新”语法

[编辑 | 编辑源代码]

为了克服用 Rebol 语法描述对象的困难,引入了一种新的语法结构。它看起来像这样

#[object! [field: 1]]

正如人们很容易发现的那样,它以“语法方式”描述了对象,即 LOAD 函数在处理它时产生一个对象

type? load "#[object! [field: 1]]" ; == object!

“新”语法用法和名称

[编辑 | 编辑源代码]

在引入新语法后,MOLD 函数的行为没有改变(为了保持向后兼容性,我想),而新语法仅在 MOLD/ALL 带来优势时使用,即在上面这样的情况下。

一些用户建议将“序列化语法”名称用于“新”语法类型。不幸的是,“序列化语法”的概念(借用西布里勋爵的话,我爱英国幽默!)只是“语法”概念的“冗余和累赘”的等价物(“语法”和“系列”实际上是相同的概念,一个来自希腊语,另一个来自拉丁语,就像“冗余”和“累赘”这两个词一样)。因此,将它们组合在一起并认为它具有某种特殊意义的做法是相当不合适的。

幸运的是,当观察 make object! [field: 1]#[object! [field: 1]] 之间的相似之处时,我们可以得出结论,后者只是描述了前者中存在的构造函数参数列表。唯一缺少的部分是构造函数。这就是为什么术语“构造函数”也不合适。Hostile Fork 注意到这种相似性,将“新”语法称为“构造语法”,这看起来很合适,而且它可以用作一个词“构造”,或者作为缩写形式的两个词“构造规范”或“构造格式”等等。

  • value -- 要模塑的值(类型:任何类型)
  • /only -- 对于块值,仅给出内容,没有外部 [ ]。
  • /all -- 以序列化格式模塑
  • /flat -- 不缩进

源代码

[编辑 | 编辑源代码]
mold: native[
    "Converts a value to a REBOL-readable string." 
    value "The value to mold" 
    /only {For a block value, give only contents, no outer [ ].} 
    /all "Mold in serialized format" 
    /flat "No indentation"
]
华夏公益教科书