且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

如何在引用变量之前测试它是否已定义?

更新时间:2023-11-27 23:13:34

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

在 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.