如何在引用变量之前测试它是否已定义? [英] How do I test whether a variable is defined before referencing it?

查看:40
本文介绍了如何在引用变量之前测试它是否已定义?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望能够在访问变量之前测试它是否已定义.

我喜欢有一个指定调试级别"的全局变量.如果调试级别为 0,则不会给出额外的输出.大于 1 时,给出调试输出,数字越大越详细.

如果我还没有开始定义它,我还想设置它以便程序运行,并假设级别为 0.类似于:( 定义在哪里? 是我不知道该怎么做的魔法?

(if (and (defined? debug-level) (> debug-level 1))(显示一些调试信息"))

我浏览了The Scheme Programming语言,第 4 版.我认为唯一可能的是 identifier?.它没有用.

我正在使用 SISC 1.16.6(声称符合 R5RS)和 Chez Petite Scheme v8(声称符合 R6RS)

EDIT 我尝试用 guard 包裹 eval ,例如:

(guard (x (else #f)) (eval 'debug-level))

由于 'debug-level 被引用,它可以被评估并传递给 eval.然后,当 eval 尝试对其进行评估时,会发生错误,我希望 guard 能够捕获该错误.没有.

EDIT 2 我意识到我想将调试跟踪包装到一个单独的过程中,并且定义该过程的文件也可以使用默认值定义 debug-level0. 使用单独过程的原因是为了减少工作过程中的行数,并且还允许在需要时重定向调试输出.

解决方案

这完全取决于实现提供,而且看起来大多数实现都不能令人满意地提供它.

在 SISC 方案中,您似乎可以使用 GETPROP为了这个效果,但是环境不会自动更新哦,看,你可以使用一个叫做交互环境的东西:

<前>#;> (getprop 'cons (interaction-environment))#<本机程序缺点>#;> (getprop 'x (交互环境))#F#;>(定义 x 100)#;> (getprop 'x (交互环境))100

但它只适用于顶层.

<前>#;> (定义 (foo y)(让((e(交互环境)))(display "Is X bound? ") (display (getprop 'x e))(新队)(display "Is Y bound? ") (display (getprop 'y e))(新队) ))#;> (foo 1)#;> X 是绑定的吗?100Y是绑定的吗?#F

对于 Chez,您有 TOP-LEVEL-BOUND? 和交互环境.

I would like to be able to test whether a variable is defined, prior to accessing it.

I like to have a global that specifies a "debug level". If debug level is 0, no extra output is given. When greater than 1, debug output is given, with more verbosity at greater numbers.

I also would like to set it up so that the procedures would run, and assume a level 0, if I had not gotten around to defining it. Something like: (where defined? is the magic I don't know how to do?

(if (and (defined? debug-level) (> debug-level 1))
    (diplay "Some debugging info"))

I have looked through the summary of forms in The Scheme Programming Language, 4th Edition. The only one that I saw as a possibility was identifier?. It did not work.

I'm using SISC 1.16.6 (claims R5RS compliance) and Chez Petite Scheme v8 (claims R6RS compliance)

EDIT I tried wrapping eval with a guard like:

(guard (x (else #f)) (eval 'debug-level))

Since 'debug-level is quoted it can be evaluated and passed to eval. Then when eval tries to evaluate it, an error would happen, which I hoped guard would catch. It didn't.

EDIT 2 I realized that I wanted to wrap the debug tracing into a seperate procedure and that the file that defines that procedure can also define debug-level with a default of 0. The reasons for using a seperate procedure are to lower the number of lines in the procedures that do work and also to allow the redirection of debug output if needed.

解决方案

This is totally up to the implementation to provide, and it looks like most implementations don't satisfactorily provide it.

In SISC scheme, it looks like you can use GETPROP to this effect, but environments don't update automatically oh, look, there's this thing called INTERACTION-ENVIRONMENT that you can use:

#;> (getprop 'cons (interaction-environment))
#<native procedure cons>
#;> (getprop 'x (interaction-environment))
#f
#;> (define x 100)
#;> (getprop 'x (interaction-environment))
100

But it only works on the top level.

#;> (define (foo y)
  (let ((e (interaction-environment)))
    (display "Is X bound? ") (display (getprop 'x e))
    (newline)
    (display "Is Y bound? ") (display (getprop 'y e))
    (newline) ))
#;> (foo 1)
#;> Is X bound? 100
Is Y bound? #f

For Chez you have TOP-LEVEL-BOUND? and INTERACTION-ENVIRONMENT again.

这篇关于如何在引用变量之前测试它是否已定义?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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