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