当我使用错误?并尝试,err需要一个值 [英] When I use error? and try, err need a value

查看:140
本文介绍了当我使用错误?并尝试,err需要一个值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这里我执行cmd作为Rebol指令的功能:

Here my function that execute cmd as a Rebol instructions :

exec-cmd: func [
        cmd [ block! ] "Rebol instructions"
        /local err
] [
        if error? err: try [
                do cmd
        ] [ print mold disarm err ]
]

当我启动该功能时,我遇到以下错误消息:

When I launch the function, I've encountered the following error message :

** Script Error: err needs a value
** Where: exec-cmd
** Near: if error? err: try [
    do cmd
]

如何避免此消息并且管理错误?

How can I avoid this message and manage the error ?

推荐答案

当Rebol默认评估程序看到一个SET-WORD的序列!然后是一个完整表达式,它会将该表达式的结果分配给命名的单词。

When the Rebol default evaluator sees a sequence of a SET-WORD! followed by a "complete" expression, it will assign the result of that expression to the named word.

然而,Rebol有能力返回一种特殊的无 从一个名为UNSET的函数!例如:

However, Rebol has the ability to return a special kind of "nothing" from a function called an UNSET!. For instance:

>> type? print {What "value" does a print return?}
What "value" does a print return?
== unset!

这不同于返回一个NONE!价值...因为如果您继续评估链,评估者将不允许他们进行分配。

This is different from returning a NONE! value...because if you continue the chain of evaluation, the evaluator will not allow them in assignments.

>> foo: print {This isn't legal}
This isn't legal
** Script Error: foo needs a value
** Near: foo: print "This isn't legal"

变量实际上不能持有值类型为UNSET! UNSET!只是您尝试访问未设置的变量时将获得的值类型。无论是否存在无价值的哲学等价性,机械的后果是,如果你想让一个未知的!值要有效地分配,你必须使用函数和 / any 细化 :

Variables cannot actually "hold a value" of type UNSET!. UNSET! is just the "value type" that you will get if you try and access a variable that is not set. Regardless of the philosophical equivalence of whether there is a none value or not, the mechanical consequence is that if you want to allow an unset! value to effectively be "assigned" you have to do that "assignment" using the set function and the /any refinement:

>> set/any 'foo (print {This works...})
This works...
== unset!

但是,为了能够从值中读取,您不能仅仅将其引用为变量现在未定义您需要使用相应的 get

But to be able to read from the value, you can't just reference it as the variable is now undefined. You need to use the corresponding get:

>> type? get/any 'foo
== unset!

无论如何,这是为什么你看到这个的背景。您的 cmd 可能以返回UNSET!的功能结束,例如可能 print

Anyway, that's the background on why you're seeing this. Your cmd presumably ended with a function that returned an UNSET!, like maybe print?

这是一个例子,可能是说明性的:

Here's an example that may be illustrative:

exec-cmd: func [
    cmd [block!] "Rebol instructions"
    /local err
] [
    set/any 'result (try [do cmd])
    case [
        unset? get/any 'result [
            print "Cmd returned no result"
        ]

        function? :result [
            print ["Cmd returned a function:" newline (mold :result)]
        ]

        ;-- Rebol3 only --
        ;
        ; closure? :result [
        ;    print ["Cmd returned a closure:" newline (mold :result)]
        ; ]

        ;-- Rebol3 should be changed to match Red and not require this --
        ;
        lit-word? :result [
            print ["Cmd returned a literal word:" newline (mold :result)]
        ]

        error? result [
            print mold disarm result
        ]

        true [
            print ["Cmd returned result of type" (mold type? result)]
            print ["The value was:" newline (mold result)]
        ]
    ]
]


注意,一旦你已经处理结果可能未设置的情况,你不必使用 get / any 并且只能做正常访问。

Notice that once you've already handled the case where result might be unset, you don't have to use get/any and can just do normal access.

解释器的工作方式有一个基础问题,如果一个单词绑定到一个FUNCTION!值(也是Rebol3中的CLOSURE!值),然后引用该字调用相关代码。要解决这个问题,如果你知道你处于一个单词可能持有这样一个价值的情况,你可以使用GET或SET-WORD的模拟!被称为GET-WORD!这些通常被认为是丑陋的,所以最好的是你可以隔离需要测试这样一个边缘的代码的部分代码,而不是把冒号放在不需要的东西前面!

There is a foundational issue in the way the interpreter works, that if a word is bound to a FUNCTION! value (also the CLOSURE! values in Rebol3) then referencing that word invokes the related code. To work around this, if you know you're in a situation where a word may hold a such a value you can use GET or the analogue of a SET-WORD! known as a GET-WORD!. These are generally considered "ugly" so it's best if you can isolate the part of the code that needs to test for such an edge case and not wind up putting colons in front of things you don't need to!

被认为是设计缺陷的东西叫做lit-word decay。这需要使用GET-WORD!在Rebol2中,如果您的手中有一个实际字面值。在这种情况下,您的程序不会崩溃,只是不会给你期望的。 在这里解释 ...它已经在红色所以Rebol3肯定会改变。

What has been deemed a design flaw is something called "lit-word decay". This necessitates the use of a GET-WORD! in Rebol2 if you have an actual literal word in your hand. In that case, your program won't crash, it just won't give you what you expect. It's explained here...it has already been changed in Red so it's certain to change for Rebol3.

另外,Rebol3中已经消除了武装并需要被解除武装的错误概念。这不会影响Rebol2中的错误?测试,以便您需要使用GET-WORD!,但会影响到您可以使用的所有其他操作。

Also, the concept of errors being "armed" and needing to be "disarmed" to be inspected has been eliminated in Rebol3. That doesn't affect the error? test in Rebol2 such that you'd need to use a GET-WORD!, but affected just about everything else you could do with them.

好的我认为我已经涵盖了所有这些情况,但如果没有,有人会纠正我的意见。

All right. I think I've covered all the cases here, but someone will correct me if I haven't!

(注意:如果您好奇如何使自己的函数返回一个UNSET!像打印一样,只需使用 exit 而不是 return

(Note: if you're curious how to make your own function that returns an UNSET! like print does, just use exit instead of return)

>> nothing: func [value] [exit]

>> type? nothing 1020
== unset!

这篇关于当我使用错误?并尝试,err需要一个值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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