我想在词法范围内重新定义一个标准的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通常情况下,如果你真的想打破,通常会有一些方法。但这几乎总是一个坏主意。;(