Ракетка REPL через TCP - PullRequest
       31

Ракетка REPL через TCP

8 голосов
/ 10 мая 2011

Я создал довольно сложное приложение с Racket (ранее PLT Scheme) и хотел бы добавить REPL для целей отладки.Я попытался сделать его доступным через поток TCP:

(define repl-server
  (thread (lambda ()
          (let ((listener (tcp-listen 8082 5 #t)))
            (do () (#f)
              (let-values (((in out) (tcp-accept listener)))
                (thread (lambda ()
                          (let ((port-string (get-port-string in)))
                             (Try "debug-repl" #f
                               (begin
                                 (file-stream-buffer-mode out 'line)
                                 (display-and-log "Password: " out)
                                 (flush-output out)
                                 (when (string=? (read-line in) "whatever")
                                   (log "Connect to REPL: " port-string))
                                   (current-input-port in)
                                   (current-output-port out)
                                   (current-error-port out)
                                   (read-eval-print-loop))
                                 (close-input-port in)
                                 (close-output-port out))))))))))))

(Try name result-if-exception form) - это макрос, обеспечивающий базовую обработку исключений (log ...) и (display-and-log ...)делайте так, как они звучат.

Теперь, когда я получаю доступ к REPL, я даже не могу оценить константы, так как я продолжаю получать ошибку compile: unbound identifier (and no #%app syntax transformer is bound) at: #%top-interaction.Как я могу заставить этот REPL работать?И как я могу получить доступ к значениям define d перед запуском сервера REPL?

1 Ответ

3 голосов
/ 10 мая 2011

Вы используете read-eval-print-loop, что по сути то же самое, что и eval, и поэтому имеет те же проблемы. См. соответствующий раздел руководства для подробного объяснения. Лучше прочитать это полностью, но ответы, которые вы ищете, - это то, что описано в разделе «Пространства имен», или раздел «Пространства имен и модули» - первое, если вы хотите использовать пространство имен верхнего уровня, и во-вторых, если вы хотите, чтобы пространство имен соответствовало фактическому файлу, в котором появляется код. (Первое обычно лучше - например, если вы используете второе, тогда repl-server само доступно для пользователя REPL, что делает его сомнительная особенность ...)

Вот как это будет выглядеть:

...
(thread (lambda ()
          (parameterize ([current-namespace (make-base-namespace)])
            ...same code...)))
...

, а для второго определите привязку и используйте namespace-anchor->namespace, как показано в последнем примере на этой странице.

[Кстати, см. Также вещь run-server, она немного старая, но все еще может быть полезной.]

...