Возможно ли иметь в одном и том же оргструктуре два кодовых блока на одном и том же языке, которые выполняются в разных интерпретаторах, указав разные параметры в верхней части блока кода?
Возможно ли иметь в одном и том же оргструктуре два кодовых блока на одном и том же языке, которые выполняются в разных интерпретаторах, указав разные параметры в верхней части блока кода?
Ответы:
Первоначальный вопрос был изменен, чтобы касаться запуска нескольких версий исполняемого файла, а не просто независимых интерпретаторов.
Используя 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поддержку, чтобы увидеть.
Это позволяет следующему работать:
#+begin_src emacs-lisp :results none
(setq org-babel-python-command "python3")
#+end_src
#+begin_src python :results output
import sys
print(sys.version)
#+end_src
#+RESULTS:
: 3.4.0 (default, Apr 11 2014, 13:05:11)
: [GCC 4.8.2]
#+begin_src emacs-lisp :results none
(setq org-babel-python-command "python2")
#+end_src
#+begin_src python :results output
import sys
print(sys.version)
#+end_src
#+RESULTS:
: 2.7.6 (default, Mar 22 2014, 22:59:56)
: [GCC 4.8.2]
Это можно сочетать с :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 поддерживают свойство сеанса.
#+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опцию, как в следующем примере.
#+begin_src js :cmd "/usr/bin/osascript -l JavaScript"
app = Application.currentApplication()
app.includeStandardAdditions = true
app.say("Hello")
#+end_src