Interprète spécifique au bloc de code à Org Babel

13

Est-il possible d'avoir, dans le même fichier org, deux blocs de code dans la même langue qui sont exécutés dans différents interprètes en spécifiant différentes options en haut du bloc de code?

cefstat
la source
2
Voulez-vous dire, par exemple, différentes versions des logiciels installés, par exemple python26, python27 et python3? Ou simplement des sessions python uniques, mais toutes utilisant le même exécutable? @dgtized explique ce dernier.
mankoff
2
Je veux dire différentes versions des logiciels installés, c'est-à-dire utilisant différents exécutables.
cefstat

Réponses:

10

La question d'origine a été modifiée pour concerner l'exécution de plusieurs versions d'un exécutable, et pas simplement des interprètes indépendants.

En utilisant find-libraryj'ai inspecté la source de ob-ruby, qui comprend ce code:

(defvar org-babel-ruby-command "ruby"
  "Name of command to use for executing ruby code.")

J'ai vu des références ailleurs pour python à l'aide org-babel-python-command, donc il existe dans d'autres langues, vérifiez le ob-$langsupport approprié pour voir.

Cela permet aux éléments suivants de fonctionner:

#+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]

Ceci pourrait être combiné avec :session python3et :session python2pour éviter d'appeler elisp avant chaque bloc. Il semble cependant qu'il devrait y avoir un moyen plus simple de le faire.

dgtized
la source
2
Il y a un org-babel-post-tangle-hook. Quelqu'un devrait implémenter à org-babel-pre-tangle-hook.
mankoff
1
Je ne connais pas très bien les éléments internes, mais je ne suis pas sûr que l'enchevêtrement serait la phase appropriée pour effectuer ce changement? Honnêtement, il semble que le bloc ait besoin d'une :interpreterpropriété.
organisé
2
Je ne le connais pas trop non plus. Oui :interpreterest logique. Mais org-babel-post-tangle-hooks'exécute après l'exécution du code via C-c C-cdans un bloc de code. Je suppose preque s'exécuterait avant l'exécution du code. Mais je me rends compte maintenant que si changer une variable globale, cela aurait de mauvais effets secondaires. :interpreterserait mieux.
mankoff
1
Merci @dgtized et @mankoff pour vos réponses. Ils m'ont indiqué la bonne direction. C'est mon erreur que je n'avais pas précisé que j'étais intéressé par le code javascript. Sur la base de vos réponses, j'ai décidé d'ajouter une :interpreteroption à org-babel-execute:js. Mais en parcourant la source, org-babel-execute:jsj'ai trouvé qu'il existe déjà une :cmdoption qui fait exactement ce que je veux. Malheureusement, :cmdn'est pas disponible pour toutes les langues et je n'ai pas non plus trouvé de documentation pour ob-jsdonc j'ai d'abord manqué :cmdl'existence de.
cefstat
@cefstat je l'ai noté :cmd, mais il semblait qu'il n'était utilisé que pour ajouter des arguments à la commande interprète. Pourriez-vous s'il vous plaît répondre à votre propre question avec un exemple complet montrant l'utilisation de :cmdpour résoudre le problème pour ceux qui ont ce problème à l'avenir?
organisé
1

Je crois que par défaut, chaque bloc s'exécute dans un interpréteur indépendant, même si c'est la même langue. Le comportement peut être différent pour certaines langues. Par exemple, je ne suis pas sûr que les blocs emacs-lisp prennent en charge la propriété de session.

#+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

Les deux premiers blocs utilisent des interprètes indépendants, mais les troisième et quatrième blocs partagent une session :foo, de sorte qu'ils évaluent dans le même interprète.

dgtized
la source
2
Bonne réponse en théorie, mais ne répond pas à la question.
mankoff
1

Il s'avère que plus presque toutes les langues prises en charge par Org Babel ne permettent pas d'utiliser un interpréteur différent pour un bloc de code spécifique. Une exception notable (et celle qui m'intéresse) est Javascript. Dans ce cas, on peut utiliser l' :cmdoption.

L'interpréteur JS standard est node, tel que défini dans la variable org-babel-js-cmd. Pour exécuter un bloc de code spécifique via un interpréteur différent, passez l' :cmdoption comme dans l'exemple suivant.

#+begin_src js :cmd "/usr/bin/osascript -l JavaScript"
app = Application.currentApplication()
app.includeStandardAdditions = true
app.say("Hello")
#+end_src
cefstat
la source