块的反面是什么:以rebol/red加载文本 [英] What's the inverse of block: load text in rebol / red

查看:136
本文介绍了块的反面是什么:以rebol/red加载文本的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

假设我有一些rebol/红色代码.如果加载源文本,则会得到一个块,但是如何从块中获取源文本呢?我尝试了表单块,但它没有返回源文本.

Let's say I have some rebol / red code. If I load the source text, I get a block, but how can get back the source text from block ? I tried form block but it doesn't give back the source text.

    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 is a higher-level operation with complex behaviors, e.g. it can take a FILE!, a STRING!, or a BLOCK!. Because it does a lot of different things, it's hard to speak of its exact complement as an operation. (For instance, there is SAVE which might appear to be the "inverse" of when you LOAD from a FILE!)

但是您的示例专门处理了STRING!:

But your example is specifically dealing with a STRING!:

如果我加载源文本,则会得到一个块,但是如何从块中取回源文本?

If I load the source text, I get a block, but how can get back the source text from block ?

一般而言,这是非常相关的事情:您无法找回"源文本.

As a general point, and very relevant matter: you can't "get back" source text.

在上面的示例中,您的源文本包含注释,并且在LOAD之后它们将消失.同样,以每个值携带的NEW-LINE标志的形式,保留了非常有限的空白信息.但是,不会保留您使用的特定缩进样式(或是否使用制表符或空格).

In your example above, your source text contained comments, and after LOAD they will be gone. Also, a very limited amount of whitespace information is preserved, in the form of the NEW-LINE flag that each value carries. Yet what specific indentation style you used--or whether you used tabs or spaces--is not preserved.

更微妙的是,丢失了少量的符号区别.细绳!加载的文字会丢失您是否写了"with quotes"{with curly braces}的知识... Rebol和Red都不会保留该位. (即使他们这样做了,也不会回答在突变后或使用新字符串后该怎么做的问题.)DATE有变化!输入格式,它不记得您使用了哪种特定格式.等等.

On a more subtle note, small amounts of notational distinction are lost. STRING! literals which are loaded will lose knowledge of whether you wrote them "with quotes" or {with curly braces}...neither Rebol nor Red preserve that bit. (And even if they did, that wouldn't answer the question of what to do after mutations, or with new strings.) There are variations of DATE! input formats, and it doesn't remember which specific one you used. Etc.

但是,当谈到将代码作为文本来回传递时,与绑定相比,格式是次要的.考虑到您可以构建如下结构:

But when it comes to talking about code round-tripping as text, the formatting is minor compared to what happens with binding. Consider that you can build structures like:

>> 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更加模糊了它的影响-因为甚至在STRING上执行to block!之类的操作!和system/lexer/transcode似乎绑定到用户上下文中.但是,除了最琐碎的例子之外,您将面临其他任何问题.

You cannot simply serialize b to a string as "[a a a]" and have enough information to get equivalent source. Red obscures the impacts of this a bit more than in Rebol--since even operations like to block! on STRING! and system/lexer/transcode appear to do binding into the user context. But it's a problem you will face on anything but the most trivial examples.

有一些针对Rebol2和Red的二进制格式试图解决此问题.例如在"RedBin"中一个WORD!保存其上下文 (并在该上下文中建立索引).但是随后,您必须考虑要将多少已加载环境拖到文件中以保留上下文.因此,肯定会打开一罐蠕虫.

There are some binary formats for Rebol2 and Red that attempt to address this. For instance in "RedBin" a WORD! saves its context (and index into that context). But then you have to think about how much of your loaded environment you want dragged into the file to preserve context. So it's certainly opening a can of worms.

这并不是说将事物模制出来的功能并没有帮助.但是没有免费的午餐……因此Rebol和Red程序不得不像其他人一样去考虑序列化.如果您考虑对任何源代码进行处理(出于保留注释的原因,如果没有其他原因),那么PARSE可能应该是您要做的第一件事.

This isn't to say that the ability to MOLD things out isn't helpful. But there's no free lunch...so Rebol and Red programs wind up having to think about serialization as much as anyone else. If you're thinking of doing processing on any source code--for the reasons of comment preservation if nothing else--then PARSE should probably be the first thing you reach for.

这篇关于块的反面是什么:以rebol/red加载文本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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