Как (повторно) загрузить файлы в Racket (X) REPL?

Предположим, у меня есть файл вроде

#lang racket/base
(define (hello) (print "Hello"))
... more definitions ...

и я хотел бы загрузить определения в файл для интерактивной работы с ними в (X) REPL. Как я могу это сделать?

Если я запустил (X) REPL и (load "/tmp/hello.rkt"), то функция hello мне не станет доступной:

-> (hello)
; hello: undefined;

Если я (require (file "/tmp/hello.rkt")), результат тот же. Теперь я могу (enter! (file "/tmp/hello.rkt")), а затем (hello) работает, но это кажется довольно ... неинтуитивным и недружелюбным для новичков.

Действительно ли это должно быть сделано таким образом, и я должен просто прочитать модули и пространства имен, чтобы легко просматривать и экспериментировать с моим кодом, или есть более простой способ, который я упускаю?

N.B. Я нашел Как загрузить файл в ракетку через командную строку?, но это только объясняет, как запустить файл. Не о том, как загрузить его в REPL, чтобы вы могли тестировать / отлаживать некоторые конкретные определения, затем редактировать, перезагружать и т. Д.


person Confusion    schedule 16.02.2013    source источник


Ответы (2)


Поскольку файлы, начинающиеся с #lang, являются модулями, они ничего не сделают, если вы load их. (На самом деле он что-то делает, но, вероятно, не что-то, что могло бы вам помочь.) На самом деле лучше всего полностью избегать использования load, просто притворившись, что его там нет.

Теперь использование require - это правильно, но он создает экземпляр модуля и предоставляет вам доступ к именам, которые он предоставляет. В вашем случае вы ничего не предоставили, что означает, что вы не можете использовать свой hello. Для этого вы можете добавить в файл (provide hello). Но, скорее всего, это не то, что вам нужно, поскольку кажется, что вы хотите отлаживать код. (То есть вы не захотите provide все из вашего модуля просто работать над чем-то.)

Так что правильнее всего использовать enter!, или, если вы используете xrepl, есть более удобная команда ,en. Это создаст экземпляр модуля и заставит repl использовать пространство имен модуля, чтобы вы могли получить доступ ко всему. (И вам не нужно load или require.) Вы также можете использовать его несколько раз, чтобы перезагрузить код, если вы его измените. Но обратите внимание, что с ним возникли некоторые проблемы, поэтому вам может потребоваться установить ночную сборку для работы с ним.

Наконец, вы, вероятно, знаете это, но работа с DrRacket в целом значительно упростит задачу.

person Eli Barzilay    schedule 16.02.2013
comment
Хорошо, enter! это так. Причина, по которой я использую (X) REPL, заключается в том, что я использую charterm пакет для интерфейса командной строки моей программы, и этот пакет нельзя использовать в DrRacket (что имеет смысл, поскольку DrRacket не предоставляет tty). - person Confusion; 17.02.2013
comment
Он используется так btw: (enter! "file.rkt") или используйте простую версию без скобок и кавычек: ,en file.rkt - person vlz; 02.07.2020

Размещение #lang racket/base в верхней части файла означает, что файл помечается как форма модуля (это # сокращенное обозначение языка); таким образом, загрузка файла - это просто добавление определения модуля для (file "/tmp/hello.rkt"), как вы обнаружили, когда вам потребовался этот путь.

Если вы просто хотите поэкспериментировать с набором определений и попробовать загрузить их в интерактивном режиме, вы можете попробовать удалить #lang racket/base из верхней части файла. Я проиллюстрирую это здесь на паре файлов "Racket toplevel" (rktl):

% cat hello-unhashed.rktl
(define (hello) (print "Hello") (newline))
% cat hello2-unhashed.rktl
(define (hello) (print "Hello2") (newline))
% racket
Welcome to Racket v5.3.2.
> (load "hello-unhashed.rktl")
> (hello)
"Hello"
> (load "hello2-unhashed.rktl")
> (hello)
"Hello2"
> (load "hello-unhashed.rktl")
> (hello)
"Hello"
> (exit)
% 

Обратите внимание, что при работе на верхнем уровне, как показано выше, существует множество подводных камней. Чтобы понять, о чем я говорю, попробуйте поискать в Google «верхний уровень рэкетов безнадежен» или «верхний уровень схемы plt безнадежен».

person pnkfelix    schedule 16.02.2013
comment
Эта суть от одного из разработчиков Racket также дает хороший указатель верхнего уровня безнадежного мема: gist.github. ru / samth / 3083053 - person pnkfelix; 16.02.2013
comment
load никогда не следует рекомендовать. Никогда. Как и eval, это то, что люди, которые могут найти его полезным, - это люди, которые знают достаточно, чтобы не спрашивать об этом - поэтому, просто спрашивая об этом, вы должны знать, что это не то, что предлагать ... (И, кстати, поскольку такие файлы верхнего уровня настолько разные, что мы используем .rktl в качестве суффикса для них.) - person Eli Barzilay; 16.02.2013
comment
ах, я не знал о .rktl соглашении. Я отредактирую свой ответ, чтобы использовать его, по крайней мере, для созданных мной файлов. Первоначальный вопрос начался с использования load, и я просто дошел до конца; Я позволю спрашивающему решить, какой из двух подходов, которые мы дали, ответил на их вопрос. - person pnkfelix; 17.02.2013
comment
Я считаю, что load так же плохо, как eval. С одной стороны, его меньше злоупотребляют, что делает его лучше, но OTOH - это то, на что люди прыгают без запретов, которые они получают за _3 _... В любом случае использование load в Racket гарантированно будет ошибкой для людей, которые спросят об этом. (То есть, для него есть несколько правильных применений, но это то, что могут сделать только эксперты.) - person Eli Barzilay; 19.02.2013