Возможно ли иметь в одном и том же оргструктуре два кодовых блока на одном и том же языке, которые выполняются в разных интерпретаторах, указав разные параметры в верхней части блока кода?
Возможно ли иметь в одном и том же оргструктуре два кодовых блока на одном и том же языке, которые выполняются в разных интерпретаторах, указав разные параметры в верхней части блока кода?
Ответы:
Первоначальный вопрос был изменен, чтобы касаться запуска нескольких версий исполняемого файла, а не просто независимых интерпретаторов.
Используя 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