Специфичный интерпретатор кодовых блоков в Org Babel
13
Возможно ли иметь в одном и том же оргструктуре два кодовых блока на одном и том же языке, которые выполняются в разных интерпретаторах, указав разные параметры в верхней части блока кода?
Вы имеете в виду, например, разные версии установленного программного обеспечения, например, python26, python27 и python3? Или просто уникальные сессии Python, но все используют один и тот же исполняемый файл? @dgtized объясняет последнее.
Mankoff
2
Я имею в виду разные версии установленного программного обеспечения, т.е. использующие разные исполняемые файлы.
cefstat
Ответы:
10
Первоначальный вопрос был изменен, чтобы касаться запуска нескольких версий исполняемого файла, а не просто независимых интерпретаторов.
Используя find-libraryя проверил источник ob-ruby, который включает этот код:
(defvar org-babel-ruby-command "ruby"
"Name of command to use for executing ruby code.")
В других местах я видел ссылки на использование Python org-babel-python-command, поэтому он существует в некоторых других языках, проверьте соответствующую ob-$langподдержку, чтобы увидеть.
Это можно сочетать с :session python3и :session python2избегать вызова elisp перед каждым блоком. Похоже, что должен быть более простой способ сделать это.
Существует org-babel-post-tangle-hook. Кто-то должен реализовать в org-babel-pre-tangle-hook.
mankoff
1
Я не очень знаком с внутренностями, но я не уверен, что запутывание было бы подходящей фазой, чтобы сделать это изменение? Честно говоря, похоже, что блок нуждается в :interpreterсобственности.
dgtized
2
Я тоже не слишком знаком с этим. Да :interpreterимеет смысл. Но org-babel-post-tangle-hookзапускается после выполнения кода через C-c C-cблок кода. Я предполагаю, preчто будет работать до выполнения кода. Но теперь я понимаю, что если изменить глобальную переменную, это будет иметь плохие побочные эффекты. :interpreterбыло бы лучше.
Mankoff
1
Спасибо @dgtized и @mankoff за ваши ответы. Они указали мне в правильном направлении. Это была моя ошибка, что я не указал, что меня интересует код JavaScript. На основании ваших ответов я решил добавить :interpreterопцию org-babel-execute:js. Но затем, просматривая источник, org-babel-execute:jsя обнаружил, что уже есть :cmdопция, которая делает именно то, что я хочу. К сожалению, :cmdдоступно не для всех языков, и я также не нашел никакой документации, ob-jsпоэтому я изначально пропустил :cmdсуществование.
cefstat
@cefstat Я заметил :cmd, но похоже, что он использовался только для добавления аргументов к команде интерпретатора. Не могли бы вы ответить на свой вопрос с полным примером, показывающим использование :cmdдля решения проблемы для тех, кто имеет эту проблему в будущем?
dgtized
1
Я считаю, что по умолчанию каждый блок работает в независимом интерпретаторе, даже если это один и тот же язык. Поведение может отличаться для некоторых языков. Например, я не уверен, что блоки emacs-lisp поддерживают свойство сеанса.
#+BEGIN_SRC ruby
a = "foo"
#+END_SRC
#+RESULTS:
: foo
#+BEGIN_SRC ruby
a ||= "bar"
#+END_SRC
#+RESULTS:
: bar
#+BEGIN_SRC ruby :session foo
a ||= "session foo"
#+END_SRC
#+RESULTS:
: session foo
#+BEGIN_SRC ruby :session foo
a += " with bar"
#+END_SRC
#+RESULTS:
: session foo with bar
Первые два блока используют независимые интерпретаторы, но третий и четвертый блоки совместно используют сеанс :foo, поэтому они оцениваются в одном и том же интерпретаторе.
Оказывается, что почти во всех языках, поддерживаемых Org Babel, нет возможности использовать другой интерпретатор для конкретного кодового блока. Одним заметным исключением (и тем, которое меня интересует) является Javascript. В этом случае можно использовать :cmdопцию.
Стандартный интерпретатор JS node, как определено в переменной org-babel-js-cmd. Чтобы запустить определенный блок кода через другой интерпретатор, передайте :cmdопцию, как в следующем примере.
Ответы:
Первоначальный вопрос был изменен, чтобы касаться запуска нескольких версий исполняемого файла, а не просто независимых интерпретаторов.
Используя
find-library
я проверил источникob-ruby
, который включает этот код:В других местах я видел ссылки на использование Python
org-babel-python-command
, поэтому он существует в некоторых других языках, проверьте соответствующуюob-$lang
поддержку, чтобы увидеть.Это позволяет следующему работать:
Это можно сочетать с
:session python3
и:session python2
избегать вызова elisp перед каждым блоком. Похоже, что должен быть более простой способ сделать это.источник
org-babel-post-tangle-hook
. Кто-то должен реализовать вorg-babel-pre-tangle-hook
.:interpreter
собственности.:interpreter
имеет смысл. Ноorg-babel-post-tangle-hook
запускается после выполнения кода черезC-c C-c
блок кода. Я предполагаю,pre
что будет работать до выполнения кода. Но теперь я понимаю, что если изменить глобальную переменную, это будет иметь плохие побочные эффекты.:interpreter
было бы лучше.:interpreter
опциюorg-babel-execute:js
. Но затем, просматривая источник,org-babel-execute:js
я обнаружил, что уже есть:cmd
опция, которая делает именно то, что я хочу. К сожалению,:cmd
доступно не для всех языков, и я также не нашел никакой документации,ob-js
поэтому я изначально пропустил:cmd
существование.:cmd
, но похоже, что он использовался только для добавления аргументов к команде интерпретатора. Не могли бы вы ответить на свой вопрос с полным примером, показывающим использование:cmd
для решения проблемы для тех, кто имеет эту проблему в будущем?Я считаю, что по умолчанию каждый блок работает в независимом интерпретаторе, даже если это один и тот же язык. Поведение может отличаться для некоторых языков. Например, я не уверен, что блоки emacs-lisp поддерживают свойство сеанса.
Первые два блока используют независимые интерпретаторы, но третий и четвертый блоки совместно используют сеанс
:foo
, поэтому они оцениваются в одном и том же интерпретаторе.источник
Оказывается, что почти во всех языках, поддерживаемых Org Babel, нет возможности использовать другой интерпретатор для конкретного кодового блока. Одним заметным исключением (и тем, которое меня интересует) является Javascript. В этом случае можно использовать
:cmd
опцию.Стандартный интерпретатор JS
node
, как определено в переменнойorg-babel-js-cmd
. Чтобы запустить определенный блок кода через другой интерпретатор, передайте:cmd
опцию, как в следующем примере.источник