Схема: правильное применение функции eval? - PullRequest
0 голосов
/ 26 апреля 2011

на работе Я столкнулся с основной проблемой при попытке реализовать скрипт конфигурации с помощью Scheme. Чтобы избежать необходимости изобретать искусственный и ограниченный язык, скрипт должен содержать реальный код. Этот код будет оценен позже. Чтобы конфигурация работала как нужно, она должна иметь доступ к определенным переменным Эти переменные известны только в контексте оценки. Поэтому сценарий конфигурации должен оцениваться в текущей среде. Вот примитивный пример того, о чем я говорю:

(let ((a #t))
  (wr "a is ..."
    (eval '(if a "true" "false"))))

При запуске этого кода я всегда получаю сообщение об ошибке, сообщающее, что переменная 'a' неизвестна. Вопрос в том, знаете ли вы, как оценивать замороженный код в текущей среде?

P.S .: Я использую компилятор bigloo.

///////////////////////////////////////////// РЕДАКТИРОВАТЬ: //////////////////////////////////////////////// //////

При использовании подхода, предложенного Крисом, я столкнулся с еще одной интересной проблемой - использованием ключевого слова case. В следующих двух примерах используется одна и та же конструкция case, которая должна вызывать вывод «yes!» линия. К сожалению, они ведут себя по-разному.

Обычный -> вывод "да!" как и ожидалось:

  (define testit "test")
  (case testit
    (("test")
     (begin (newline) (write "yes!") (newline)))
    (else
      (begin (newline) (write "no!") (newline)))))

С eval -> output на удивление "нет":

  (define env (null-environment 5))
  (eval '(define testit "test") env)
  (eval '(case testit
           (("test")
            (begin (newline) (write "yes!") (newline)))
           (else
            (begin (newline) (write "no!") (newline))))) 

Имеет ли это какой-то смысл?

Ответы [ 2 ]

5 голосов
/ 26 апреля 2011

eval не может получить доступ к лексическим переменным, например, определенным с помощью let.

Вместо этого вам необходимо создать среду и заполнить ее переменными, которые вы хотите сделать доступными.Например:

(define env (null-environment 5))
(eval '(define a #t) env)
(wr "a is ..."
    (eval '(if a "true" "false") env))
2 голосов
/ 03 мая 2011

Чтобы ответить на ваши изменения, вы не передаете env в качестве аргумента для последнего eval.testit не существует в среде, которую создает eval, если этот аргумент не указан.

Это может быть опечаткой, но если нет, то это ваша проблема.

...