如何在Racket中重新定义范围内的标准函数



我想在词法范围内重新定义一个标准的Racket函数,即display,如本例所示:

(with-custom-display (display "hello"))

即使with-custom-display范围内的代码来自不同的库,甚至是racket/*包,这也应该起作用。

这可能吗?如果是,该怎么做?

编辑:

如果一般情况下不可能,至少对于display和其他写函数的情况。。。我可以通过对current-output-port进行参数化,然后将转换后的输出重定向到原始端口,以某种方式转换每个输出吗?

虽然全局替换Racket中的任意函数是不可能的,但您绝对可以更改Racket程序使用的标准输出端口(并扩展为display等函数(。事实上,这正是球拍中readline集合所做的,除了输入端口而不是输出端口。

基本上,您所需要做的就是全局参数化current-output-port,使其成为您的特殊端口。由于您希望最终写入原始输出端口(但使用颜色(,因此在将其更改为新端口之前,您也可以获取原始输出端口。你得到的代码看起来像这样:

#lang racket/base ;; init.rkt
(define orig-port (current-output-port))
(define new-output-port
.... uses orig-port ....)
(current-output-port new-ouput-port)

(用新的彩色输出端口的实现取代.... uses orig-port ....(

现在,任何需要"init.rkt"的文件都将在其默认输出端口中获得颜色

(不过要注意,如果你有多个文件做同样的事情,你必须小心,确保它们不会以不安全的顺序发生。(

您还可以通过以下操作将with-custom-display表单作为一个简单的语言扩展:

#lang racket ;; custom-disp.rkt
(provide with-custom-display)
(require syntax/parse/define)
(define orig-port (current-output-port))
(define new-output-port
.... uses orig-port ....)
(define-simple-macro (with-custom-display body ...)
(parameterize ([current-output-port new-output-port])
body ...))

这是DrRacket如何将输出打印到DrRacket-特定的repl,而不是控制台stdout的一般想法。

1通常情况下,如果你真的想打破,通常会有一些方法。但这几乎总是一个坏主意。;(

最新更新