SBCL的repl中使用UTF–8

Common Lisp的实现SBCL日常使用中的一些问题处理和解决方法。此次解决在特定场景下 SBCL的repl操作redis不能正常保存为UTF–8

SBCL是什么

SBCL是Common Lisp的一个实现,也是笔者比较推荐的一个实现,因为看到著名企业 Grammarly 也在使用这个实现,并且该实现得到了Google的程序员的支持。

出现了什么问题

SBCL对UTF8的支持一直很好,但是在编写一个东西的时候出现了个奇怪的东西,通过SBCL的 的repl存储到redis中的数据,并不是UTF–8的,并且是完全错误的。

解决问题

输入输出编码检查

在SBCL的repl中使用下面的代码

1
2
3
(stream-external-format *standard-output*)
(stream-external-format *standard-input*)
sb-impl::*default-external-format*

得到的结果是(:ASCII :REPLACEMENT #?),说明默认的输入输出的格式是ASCII的

解决方法

用了下面这段代码,将SBCL的repl输入输出设定为了UTF–8。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
(defun set-default-external-format (external-format)
  (assert (sb-impl::find-external-format external-format))
  (setf sb-impl::*default-external-format* external-format)
  (with-output-to-string (*error-output*)
    (setf sb-sys:*stdin*
          (sb-sys:make-fd-stream 0 :name "standard input" :input t :buffering :line))
    (setf sb-sys:*stdout*
          (sb-sys:make-fd-stream 1 :name "standard output" :output t :buffering :line))
    (setf sb-sys:*stderr*
          (sb-sys:make-fd-stream 2 :name "standard error" :output t :buffering :line))
    (setf sb-sys:*tty* 
        (make-two-way-stream sb-sys:*stdin* sb-sys:*stdout*)) 
    (princ (get-output-stream-string *error-output*) sb-sys:*stderr*)))