Rebol中#[datatype]构造函数的用途是什么?

时间:2014-11-21 21:00:29

标签: rebol rebol3

我刚刚在Rebol中遇到了这种语法来构造一些值:

>> #[email! "me@host.com"]
== me@host.com

这似乎等同于

>> to email! "me@host.com"
== me@host.com

和这个

>> #[string! "hello"]
== "hello"

虽然出现了这些错误:

>> #[integer! 1]
** Syntax Error: Invalid construct -- #[
** Near: (line 1) #[integer! 1]
>> #[decimal! 1]
** Syntax Error: Invalid construct -- #[
** Near: (line 1) #[decimal! 1]
>> #[string! 1] 
== [string! 1]

我想知道这是为了什么?它带来了什么好处?

1 个答案:

答案 0 :(得分:4)

这种句法结构称为"construction syntax"(另见CureCode issue #1955)。它的存在理由是允许以其他方式直接表示的价值的文字形式。

有两类主要情况需要构造语法。

  1. 除了构造语法之外的值没有单独的词法形式,但只能通过评估构建。
  2. 具有常规文字形式的值,但在特定值为“特殊”的情况下,该值不再可以直接写入。
  3. (1)直接值表示的构造语法

    这个类的一个突出例子是对象! Rebol对象通常使用make object! [a: 42]等代码创建。这不是结果对象值的直接文字表示,而是在评估时(在DO方言中)创建预期对象值的代码。构造语法允许直接表示值:#[object! [a: 42]]

    其他典型示例包括#[none!]和有些不规则(构造语法方面)#[true]#[false](请注意缺少!)。围绕例如两者之间的差异包裹一个人的头部。 #[none!]none将导致对Rebol语义的更深入理解(因此留给读者作为练习)。

    (2)构造语法为“逃生机制”

    此案例的典型示例是反向网址,例如您从reverse http://stackoverflow.com获得的值。如果结果值将被序列化为纯URL!,则序列化表单将不再具有语法上的有效性:

    >> /moc.wolfrevokcats//:ptth
    ** Script error: // does not allow unset! for its value2 argument
    

    构造语法为这种情况提供了一种转义机制:

    >> #[url! "/moc.wolfrevokcats//:ptth"] = reverse http://stackoverflow.com/
    == true
    

    这个特殊的例子也指出了一个有问题的情况:

    >> reverse http://stackoverflow.com/
    == /moc.wolfrevokcats//:ptth
    

    可以说,此输出(由mold native生成)是错误的:显示的结果不是相应值的有效词法表示。

    有一些错误跟踪此类问题的特定实例(例如URL的CureCode issue #2010!)。针对更通用解决方案的一个提议是在MOLD的某些变体中建立往返检查:每当加载非构造语法MOLD的结果导致值与原始值不同时,此MOLD变体会回归到序列化到构造语法。