2017-01-24 2 views
3

Я отлаживаю некоторый код с бесконечным циклом, но это сложно, потому что я не могу получить никаких сообщений журнала. Здесь нет упрощенного случай:Консоль регистрации в вяжете с бесконечной петлей

import Debug exposing (log) 

f x = 
    let _ = log "Hello, world!"() 
    in f x 

Если я запускаю это в моих Вязах РЕПЛИ как f(), она бесконечно петлю и никогда не печатает "Hello, world!", как я ожидаю, что это.

Я смотрел на реализацию Debug.log (после его Native.Debug.log), но это только кажется, что называть process.stdout.write или console.log синхронно, поэтому я удивлен, что я не вижу никакого выхода.

+0

Я не знаю, будет ли Elm проходить оптимизацию, но если это так, присваивание значения игнорируемой привязке, скорее всего, будет оптимизировано. Пробовали ли вы это, не присваивая значение журнала '_'? –

+0

Ну, это не оптимизирует его в не бесконечно-рекурсивном случае: 'f x = let _ = log« Привет, мир! »() в 5', а затем вызов 'f()' делает печать 'Hello, world!' –

+0

@w.brian Правильный компилятор будет только оптимизировать неиспользуемое выражение, если он может доказать, что он не имеет побочных эффектов. Оптимизация 'let_ = side_effecting_expression в foo'' 'foo' была бы очень неправильной оптимизацией. PS: 'let _ = ...' фактически не вводит привязку. – sepp2k

ответ

6

Это всего лишь ошибка в Elm REPL.

Проблема

Я нырнул в реализации Вязов РЕПЛ. Соответствующая функция находится здесь: Eval.Code.run

Эта функция run, по-видимому, является функцией, выполняющей кусок кода. Похоже, что каждая строка кода выполняется в подпроцессе через Elm.Utils. unwrappedRun. Существуют две проблемы с тем, как он ее запускает:

  • Этап подпроцесса не транслируется; он возвращается только после завершения всего подпроцесса. Поэтому, пока вы ждете, когда ваш код завершит оценку, вы ничего не увидите.
  • Если вы нажмете ctrl-c для завершения оценки преждевременно (что отлично работает и возвращает вас обратно в подсказку Elm), Elm Repl игнорирует возвращаемую ему стандартную версию. Обратите внимание на pattern match for CommandFailed:

Left (Utils.CommandFailed _out err) -> throwError err

Utils.CommandFailed результат услужливо включает в себя стандартный вывод (который связывался с _out), но этот код игнорирует его и просто бросает ошибку.

Таким образом, в основном это не что-то странное, что происходит с компилятором Elm или временем выполнения, только что REPL не так хорош, как это могло бы быть в отношении зарегистрированных результатов.

обходной путь

В качестве временного решения, для того, чтобы отлаживать такие вещи, как бесконечные циклы, вы можете

  1. поставить некоторые тестовый код в новом файле, Scratch.elm, как x = f()
  2. компилировать код с elm-make Scratch.elm --output scratch.js
  3. запустить код с node scratch.js

Затем вывод будет передан на ваш терминал.

+0

Это довольно умное обходное решение; поскольку node.js основан на v8, который выполняет javascript в хромовом веб-браузере. Можно подделать некоторые элементы браузера с помощью [node-jsdom] (https://github.com/darrylwest/node-jsdom). –

+1

Elm-REPL также использует node.js для оценки, поэтому он идентичен тому, как Elm REPL будет работать в любом случае. –

Смежные вопросы