Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Templates 什么是';改写';Rebol中的函数以及如何使用它?_Templates_Template Engine_Rebol_Variable Expansion_Rebol3 - Fatal编程技术网

Templates 什么是';改写';Rebol中的函数以及如何使用它?

Templates 什么是';改写';Rebol中的函数以及如何使用它?,templates,template-engine,rebol,variable-expansion,rebol3,Templates,Template Engine,Rebol,Variable Expansion,Rebol3,今天我看到有人提到了reword函数,但它的文档非常简短。它看起来像shell脚本环境变量替换,或者可能是正则表达式替换,但不同。我该如何使用这个函数?我将遇到什么样的陷阱?这里有龙! reword函数是一个实验,它将shell样式的字符串插值添加到Rebol中,与我们的工作方式一致。与许多Rebol的系列函数不同,它确实是为处理字符串类型而优化的,设计也反映了这一点。当前版本是一个设计原型,最终将作为本地版本重做,但它确实按照设计工作,因此讨论它如何工作以及如何使用它是有意义的 重写的功能是什

今天我看到有人提到了
reword
函数,但它的文档非常简短。它看起来像shell脚本环境变量替换,或者可能是正则表达式替换,但不同。我该如何使用这个函数?我将遇到什么样的陷阱?

这里有龙!
reword
函数是一个实验,它将shell样式的字符串插值添加到Rebol中,与我们的工作方式一致。与许多Rebol的系列函数不同,它确实是为处理字符串类型而优化的,设计也反映了这一点。当前版本是一个设计原型,最终将作为本地版本重做,但它确实按照设计工作,因此讨论它如何工作以及如何使用它是有意义的

重写的功能是什么?
基本上:

>> reword "$a is $b." [a "This" b "that"]
== "This is that."
它获取一个模板字符串,搜索转义序列,并用相应的替换值替换这些序列。值也作为对象、贴图或键和值块传递给函数。钥匙几乎可以是任何东西,甚至是数字:

>> reword "$1 is $2." [1 "This" 2 "that"]
== "This is that."
如果键不是字符串,则它们将转换为字符串。如果将键转换为相同的字符串,则认为它们是相同的,这就是执行以下操作时发生的情况:

>> reword "A $a is $a." [a "fox" "a" "brown"]
== "A brown is brown."
>> o/y "$x then $x and $x, also $x, finally $y"
** Internal error: stack overflow
它不像正则表达式替换,而是基于关键字的。如果您有一个在values块中多次指定的键,那么该键的最后一个值就是被使用的值,正如我们刚才看到的。任何未设置或无值都将被跳过,因为将内容放入字符串时,这些值没有任何意义

您也可以使用其他转义标志,甚至多字符转义标志:

>> reword/escape "A %%a is %%b." [a "fox" b "brown"] "%%"
== "A fox is brown."
甚至根本没有逃逸标志,到处都会替换钥匙:

>> reword/escape "I am answering you." [I "Brian" am "is" you "Adrian"] none
== "Brian is answerBrianng Adrian."
哎呀,那不行。这是因为键不区分大小写,并且它们不需要被空格或其他类似的分隔符包围。但是,如果将键指定为字符串,则可以在键本身中放置空格,这样效果更好:

>> reword/escape "I am answering you." ["I am" "Brian is" you "Adrian"] none
== "Brian is answering Adrian."
尽管如此,在没有转义字符的情况下对模板进行重写往往会很棘手,而且速度会慢一点,因此通常不会这样做

不过还有一个更好的把戏

功能替换 当您使用函数作为替换值时,
reword
变得非常有趣,因为每次重写都会调用该函数。比如说,您想用计数器替换:

>> reword "$x then $x and $x, also $x" object [y: 1 x: does [++ y]]
== "1 then 2 and 3, also 4"
或者甚至是位置,因为它可以将字符串位置作为参数:

>> reword "$x then $x and $x, also $x" object [x: func [s] [index? s]]
== "1 then 9 and 16, also 25"
等等,看起来不对,那些数字好像不正确。这是因为函数返回的是模板字符串的索引,而不是结果字符串。在编写这些函数时,最好记住这一点。该功能甚至不必只分配给一个键,它可以检测或使用它:

>> reword "$x or $y" object [x: y: func [s] [ajoin ["(it's " copy/part s 2 ")"]]]
== "(it's $x) or (it's $y)"
请参阅,模板变量、转义和所有。该功能可能会产生副作用,如以下行计数器:

>> reword/escape "Hello^/There^/nl" use [x] [x: 0 map reduce ["^/" does [++ x "^/"] "nl" does [x]]] ""
== "Hello^/There^/2"
它甚至附带了
/into
选项,因此您可以使用它分阶段构建字符串

但是对于来自内置插值语言的人来说,最大的难题是

为什么要使用值块,为什么不像普通语言一样使用变量? 因为Rebol不是那样工作的。Rebol没有词法绑定,它做一些其他的事情,所以在字符串中,如果不这样说,就无法知道从哪里获取变量的值。在其中一种具有插值的shell语言中,这相当于必须将对整个环境的引用传递给插值函数。但是,我们可以在Rebol中这样做:

>> use [x] [x: func [s] [index? s] reword "$x then $x and $x, also $x" bind? 'x]
== "1 then 9 and 16, also 25"
bind?
方法将在
use
、绑定循环和函数中起作用。如果您在对象中,也可以使用
self

>> o: object [x: func [s] [index? s] y: func [s] [reword s self]]
== make object! [
    x: make function! [[s][index? s]]
    y: make function! [[s][reword s self]]
]
>> o/y "$x then $x and $x, also $x"
== "1 then 9 and 16, also 25"
但是要小心,否则你会做这样的事情:

>> reword "A $a is $a." [a "fox" "a" "brown"]
== "A brown is brown."
>> o/y "$x then $x and $x, also $x, finally $y"
** Internal error: stack overflow

龙!这是将变量和替换键分开的一个很好的理由…

给self的提示:添加/case并支持一个尾随分隔符,以
重写
。另一个主类,在BrianH的答案之上和之后。这些都很棒,我们学到的不仅仅是。。。我们也了解如何以及为什么!你在哪里找到reword?我在rebolview中键入reword,它显示**脚本错误:reword没有值