Rebol中的"reword"功能是什么,如何使用? [英] What is the 'reword' function in Rebol and how do I use it?

查看:149
本文介绍了Rebol中的"reword"功能是什么,如何使用?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我今天看到有人提到reword函数,但是有关它的文档非常简短.它看起来像shell脚本环境变量替换,或者正则表达式替换,但有所不同.如何使用此功能,我会遇到什么陷阱?

I saw someone mention the reword function today, but documentation for it is very brief. It looks like shell script environment variable substitution, or maybe regex substitution, but different. How do I use this function and what kind of gotchas am I going to run into?

推荐答案

这里有龙!

reword函数是一个实验,它以一种与我们的工作方式配合使用的方式向Rebol添加了外壳样式的字符串插值.与Rebol的许多系列函数不同,它确实针对仅字符串类型进行了优化,并且设计反映了这一点.当前版本是设计原型,最终将重做为本机,但是它确实按设计工作,因此有必要讨论其工作方式和使用方式.

Here there be dragons!

The reword function is a bit of an experiment to add shell-style string interpolation to Rebol in a way that works with the way we do things. Unlike a lot of Rebol's series functions, it really is optimized for working on just string types, and the design reflects that. The current version is a design prototype, meant to eventually be redone as a native, but it does work as designed so it makes sense to talk about how it works and how to use it.

基本上是这样:

>> reword "$a is $b." [a "This" b "that"]
== "This is that."

它使用一个模板字符串,搜索转义序列,并用相应的替换值替换它们.值也作为对象,映射或键和值块传递给函数.键几乎可以是任何东西,甚至可以是数字:

It takes a template string, it searches for the escape sequences, and replaces those with the corresponding substitution values. The values are passed to the function as well, as an object, a map, or a block of keys and values. The keys can be pretty much anything, even numbers:

>> reword "$1 is $2." [1 "This" 2 "that"]
== "This is that."

如果键还不是字符串,则将其转换为字符串.如果将键转换为相同的字符串,则认为它们是相同的,这是在您执行以下操作时发生的情况:

The keys are converted to strings if they aren't strings already. Keys are considered to be the same if they would be converted to the same string, which is what happens when you do something like this:

>> reword "A $a is $a." [a "fox" "a" "brown"]
== "A brown is brown."

它不像正则表达式替换那样定位,它是基于关键字的.如您所见,如果您在values块中多次指定了一个键,则该键的最后一个值就是被使用的键.只是跳过任何未设置或不设置的值,因为在将内容放入字符串时这些值没有意义.

It's not positional like regex replacement, it's keyword based. If you have a key that is specified more than once in the values block, the last value for that key is the one that gets used, as we just saw. Any unset or none values are just skipped, since those have no meaning when putting stuff into a string.

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

You can use other escape flags too, even multi-character ones:

>> reword/escape "A %%a is %%b." [a "fox" b "brown"] "%%"
== "A fox is brown."

甚至根本没有转义标志,它将替换所有地方的密钥:

Or even have no escape flag at all, and it will replace the key everywhere:

>> reword/escape "I am answering you." [I "Brian" am "is" you "Adrian"] none
== "Brian is answerBrianng Adrian."

糟糕,这没用.这是因为键不区分大小写,并且不需要用空格或其他类似的定界符将它们包围.但是,如果您将键指定为字符串,则可以在键本身中放置空格,因此效果更好:

Whoops, that didn't work. This is because the keys aren't case-sensitive, and they don't need to be surrounded by spaces or other such delimiters. But, you can put spaces in the keys themselves if you specify them as strings, so this works better:

>> reword/escape "I am answering you." ["I am" "Brian is" you "Adrian"] none
== "Brian is answering Adrian."

仍然,在没有转义字符的情况下执行reword模板往往比较棘手,而且速度稍慢,因此执行的频率不高.

Still, doing reword templates without escape characters tends to be tricky and a little bit slower, so it's not done as often.

尽管有一个更好的技巧...

There's an even better trick though...

reword真正令人感兴趣的地方是当您使用函数作为替换值时,因为每次重新编写单词时该函数都会被调用.假设您要替换为计数器:

Where reword gets really interesting is when you use a function as a replacement value, since that function gets called with every rewording. Say, you wanted to replace with a counter:

>> reword "$x then $x and $x, also $x" object [y: 1 x: does [++ y]]
== "1 then 2 and 3, also 4"

甚至位置,因为它可以将字符串位置作为参数:

Or maybe even the position, since it can take the string position as a parameter:

>> reword "$x then $x and $x, also $x" object [x: func [s] [index? s]]
== "1 then 9 and 16, also 25"

等等,看起来不正确,这些数字似乎不正确.这是因为该函数返回的是 template 字符串的索引,而不是结果字符串.编写这些函数时要牢记这一点.该功能甚至不必只分配给一个键,它可以检测或使用它:

Wait, that doesn't look right, those numbers seem off. That is because the function is returning the indexes of the template string, not the result string. Good to keep that in mind when writing these functions. The function doesn't even have to just be assigned to one key, it can detect or use it:

>> reword "$x or $y" object [x: y: func [s] [ajoin ["(it's " copy/part s 2 ")"]]]
== "(it's $x) or (it's $y)"

请参阅模板变量,转义符和所有.而且该功能可能会有副作用,例如以下行计数器:

See, template variables, escapes and all. And the function can have side effects, like this line counter:

>> reword/escape "Hello^/There^/nl" use [x] [x: 0 map reduce ["^/" does [++ x "^/"] "nl" does [x]]] ""
== "Hello^/There^/2"

它甚至带有/into选项,因此您可以使用它来分阶段构建字符串.

It even comes with the /into option, so you can use it to build strings in stages.

但是对于那些来自具有内置插值语言的人来说,最大的陷阱是...

But the big gotcha for someone coming from a language with interpolation build in, is...

因为 Rebol不能那样工作. Rebol没有词法绑定,它还有其他功能,因此在字符串中,没有办法不知道如何从哪里获取变量的值.在那些具有插值的Shell语言之一中,这等效于必须将对整个环境的引用传递给插值函数.但是,嘿,我们可以在Rebol中做到这一点:

Because Rebol just doesn't work that way. Rebol doesn't have lexical binding, it does something else, so in a string there is just no way to know where to get the values of variables from without saying so. In one of those shell languages that has interpolation, it would be the equivalent to having to pass a reference to the environment as a whole to the interpolation function. But hey, we can do just that in 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:

That bind? method will work in use, binding loops and functions. If you are in an object, you can also 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"

但是要小心,否则您最终可能会执行以下操作:

But be careful, or you can end up doing something like this:

>> o/y "$x then $x and $x, also $x, finally $y"
** Internal error: stack overflow

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

这篇关于Rebol中的"reword"功能是什么,如何使用?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆