Спеціальний перекладач кодового блоку в Org Babel


13

Чи можливо мати в одному файлі org два кодові блоки на одній мові, які виконуються в різних інтерпретаторах, вказавши різні параметри вгорі блоку коду?


2
Ви маєте на увазі, наприклад, різні версії встановленого програмного забезпечення, наприклад python26, python27 та python3? Або просто унікальні сеанси пітона, але всі вони використовують один і той же виконуваний файл? @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підтримку.

Це дозволяє працювати наступним чином:

#+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 перед кожним блоком. Здається, що для цього повинен бути простіший спосіб.


2
Існує org-babel-post-tangle-hook. Хтось повинен реалізувати на org-babel-pre-tangle-hook.
mankoff

1
Я не дуже знайомий з внутрішніми, але я не впевнений, що заплутування стане відповідною фазою для внесення цих змін? Чесно кажучи, здається, що блоку потрібна :interpreterвластивість.
занотувано

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для вирішення проблеми для тих, хто має це питання в майбутньому?
дегтізовано

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, щоб вони оцінювались в одному і тому ж перекладачі.


2
Теоретично відповідь хороший, але не відповідає на питання.
mankoff

1

Виявляється, що майже на всіх мовах, які підтримуються 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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.