假设我有一些rebol/红色代码。如果我加载源文本,我会得到一个块,但是如何从块中取回源文本?我尝试了表单块,但它没有返回源文本。
text: {
Red [Title: "Red Pretty Printer"]
out: none ; output text
spaced: off ; add extra bracket spacing
indent: "" ; holds indentation tabs
emit-line: func [] [append out newline]
emit-space: func [pos] [
append out either newline = last out [indent] [
pick [#" " ""] found? any [
spaced
not any [find "[(" last out find ")]" first pos]
]
]
]
emit: func [from to] [emit-space from append out copy/part from to]
clean-script: func [
"Returns new script text with standard spacing."
script "Original Script text"
/spacey "Optional spaces near brackets and parens"
/local str new
] [
spaced: found? spacey
clear indent
out: append clear copy script newline
parse script blk-rule: [
some [
str:
newline (emit-line) |
#";" [thru newline | to end] new: (emit str new) |
[#"[" | #"("] (emit str 1 append indent tab) blk-rule |
[#"]" | #")"] (remove indent emit str 1) break |
skip (set [value new] load/next str emit str new) :new
]
]
remove out ; remove first char
]
print clean-script read %clean-script.r
}
block: load text
LOAD 是一个具有复杂行为的高级操作,例如,它可以接受 FILE!、STRING!或 BLOCK!。 因为它做了很多不同的事情,所以很难说它作为一个操作的确切补充。(例如,有 SAVE,它可能看起来像是从文件加载时的"相反"!
但是您的示例专门处理字符串!
如果我加载源文本,我会得到一个块,但是如何从块中取回源文本?
作为一般观点,也是非常相关的问题:您无法"取回"源文本。
在上面的示例中,源文本包含注释,在 LOAD 之后,它们将消失。 此外,保留的空格信息数量非常有限,以每个值携带的 NEW-LINE 标志的形式保留。 但是,您使用的特定缩进样式(或者是否使用制表符或空格)不会保留。
在更微妙的注释中,丢失了少量的符号区别。 字符串!加载的文字将失去您是"with quotes"
还是{with curly braces}
编写它们的知识......Rebol和Red都没有保留这一点。 (即使他们这样做了,这也不能回答突变后或新字符串后该怎么做的问题。 日期有变化!输入格式,它不记得您使用了哪个特定的格式。 等。
但是,当谈到代码作为文本的往返时,与绑定相比,格式设置是次要的。 考虑您可以构建如下结构:
>> o1: make object! [a: 1]
>> o2: make object! [a: 2]
>> o3: make object! [a: 3]
>> b: compose [(in o1 'a) (in o2 'a) (in o3 'a)]
== [a a a]
>> reduce b
[1 2 3]
>> mold b
"[a a a]"
您不能简单地将b序列化为字符串"[a a a]"
并有足够的信息来获取等效的源。 与 Rebol 相比,Red 掩盖了这种影响——因为即使是像 STRING 上的to block!
这样的操作!并且system/lexer/transcode
似乎对用户上下文进行绑定。 但这是一个你将面临的问题,除了最微不足道的例子。
Rebol2 和 Red 有一些二进制格式试图解决这个问题。 例如在"RedBin"中一个单词!保存其上下文(并在该上下文中索引)。但是,您必须考虑要将多少加载的环境拖到文件中以保留上下文。 所以它肯定是在打开一罐蠕虫。
这并不是说塑造事物的能力没有帮助。 但是没有免费的午餐...因此,Rebol 和 Red 程序最终不得不像其他人一样考虑序列化。 如果你正在考虑对任何源代码进行处理——如果没有别的,出于注释保留的原因——那么 PARSE 应该是你首先要做的事情。