2010-06-18 4 views
1

Когда пускаю в 99 сессии R3 Альфа и ввести это в качестве первой команды, я получаю сообщение об ошибке:Почему я не могу привязывать такие вещи, как EMAIL! в глобальном контексте при запуске интерпретатора?

>> is-email-addr: get bind to-word "email?" bind? 'system 
** Script error: email? is not in the specified context 
** Where: bind 
** Near: bind to-word "email?" bind? 'system 

Но если я брошу, перезагрузка и вместо того, чтобы выполнить тест, чтобы доказать, что email? примитивные жизни в глобальном контексте, как в system объекта, сам тест делает мой псевдоним работы:

>> equal? bind? 'system bind? 'email? 
== true 

>> is-email-addr: get bind to-word "email?" bind? 'system 
>> is-email-addr [email protected] 
== true 

Что происходит, здесь?

ответ

5

Связывание не добавляет слов в контекст, если вы не сообщите об этом - вы должны использовать bind/new.

>> get bind/new to-word "email?" bind? 'system 

Но ваш вопрос показывает пару неправильных представлений о модели привязки R3. В R3 нет единого глобального контекста, а не R2. Слово 'system в вашем примере привязано к контексту контекстно-зависимого контекста задачи, а также пользовательскому контексту. И получение правильного значения слов в пользовательском контексте часто означает их импорт из системного контекста или экспорт загруженных модулей, процесс, известный как , интернирование слов.

Для того, чтобы сделать то, что вы, видимо, хотите сделать здесь, это было бы лучше для вас, чтобы использовать intern, как это:

>> get first intern to-block "email?" 

to-block используется потому, что intern, как правило, используется для работы на целых блоков кода , Я исправлю это в следующей версии, чтобы он мог работать и над словами напрямую; то вы сможете это сделать:

>> get intern to-word "email?" 

Надеюсь, это поможет.

Почему вы не используете слово напрямую? Использование строк и преобразование в слова позже имеет так много накладных расходов, что обычно не нужно.

+0

На свежем интерпретатором, * получить привязку/новое к слову «по электронной почте ?» связывать? 'system * тоже не работает. Фактически, запуск этой команды приводит к тому, что пример вашего интернатера может завершиться неудачно. Но если интерпретатор перезапускается после привязки, то работает пример INTERN, как и LOAD. Whyzzat? – HostileFork

+0

Причина неправильного использования слова, как упоминалось в AltME, пытается написать простой remapper, который принимает * "em" * и * 'email! * И аббревиатура, чтобы создать * em? * В качестве псевдонима для * электронной почты? * И * em! * для * электронная почта! *. Это требует использования строкового отношения между словами. – HostileFork

+0

«Почему?» Потому что, когда вы запускаете эту команду, вы добавляете слово «email»? в контекст пользователя, без присвоенного ему значения и не переносить значение из контекста системы или экспорта. Когда вы запускаете INTERN позже (LOAD вызывает INTERN), он видит существующее слово в пользовательском контексте и не переопределяет его, потому что это слово пользователя. Контекст пользователя по умолчанию не заполняется содержимым системы и контекстами экспорта - он заполняется по требованию. Если вам нужны системные значения, лучше использовать INTERN с самого начала. – BrianH

1

Если вы действительно настаиваете на использовании «электронной почты»? строка вместо «электронной почты»? слово, то самый простой способ для вас, чтобы получить слово от нее, пока не соблюдая никаких странностей было бы использовать функцию LOAD, следующим образом:

is-email-addr: get bind load "email?" bind? 'system