如何在Racket中使用管道和自定义端口

时间:2013-12-14 15:19:34

标签: scheme port racket pipe

我正在尝试在Racket中使用自定义端口或管道。我想写一个消息到管道,管道检查消息,并根据消息,它返回另一个消息或某个值。

我尝试过这样的事情:

(define (write-s msg)
    (let-values ([(in-port transmitting) (make-pipe)]
                 [(receiving out-port) (make-pipe)])
     (write msg out-port)
      (let ((message (read receiving)))
         (if (equal? message '(DOGE)) 
             (write '(SO AMAZE) transmitting) 
             'do-nothing)
         (if (equal? message '(MUCH PIPES)) 
             (write '(WOW RACKET) transmitting)
             'do-nothing))
      (read in-port)))

1 个答案:

答案 0 :(得分:2)

我建议定义一个简单的辅助函数make-codec-input-port,它允许您从原始输入端口和“编解码器”功能创建输入端口。这里的关键点 - 我在make-pipe的Racket文档中对我来说并不明显 - 是你要运行一个调用编解码器函数的thread

在这里,我展示了一个简单的编解码器,用#\a替换每个#\b个字符。您可以更改其match语句以执行更有趣的操作。

#lang racket

;; Given an input-port and a codec function, return a new input-port
;; that is the encoded version. `codec` is (input-port? output-port?
;; -> any). For example can be deflate, inflate, gzip-through-ports,
;; gunzip-through-ports, copy-port (the identity function for this),
;; or your own such function.
(define codec-buffer-size (make-parameter 1024))
(define (make-codec-input-port in codec [name #f])
  (define-values (pin pout) (make-pipe (codec-buffer-size) name name))
  (thread (lambda ()
            (codec in pout)
            (close-output-port pout)))
  pin)

;; Example of a codec function.
(define (replace-a-with-b in out) ;; (input-port? output-port? -> any)
  (let loop ()
    (define ch (read-char in))
    (unless (eof-object? ch)
      (write-char (match ch
                    [#\a #\b]
                    [x x])
                  out)
      (loop))))

;; You could also write the codec function a bit more simply using
;; `in-port`:
(define (replace-a-with-b in out) ;; (input-port? output-port? -> any)
  (for ([ch (in-port read-char in)])
    (write-char (match ch
                  [#\a #\b]
                  [x x])
                out)))

;; Example direct use of the codec function.
(let ()
  (define orig-in (open-input-string "axaxax"))
  (replace-a-with-b orig-in (current-output-port)))
;; => bxbxbx

;; Example use of the encoded input port. With this, a user of the
;; port need not know anything about the codec function.
(let ()
  (define orig-in (open-input-string "axaxax"))
  (define encoded-in (make-codec-input-port orig-in replace-a-with-b))
  (port->string encoded-in))
;; => "bxbxbx"