Чи можливо мати в одному файлі 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