¿Es posible tener, en el mismo archivo de organización, dos bloques de código en el mismo idioma que se ejecutan en diferentes intérpretes especificando diferentes opciones en la parte superior del bloque de código?
¿Es posible tener, en el mismo archivo de organización, dos bloques de código en el mismo idioma que se ejecutan en diferentes intérpretes especificando diferentes opciones en la parte superior del bloque de código?
Respuestas:
La pregunta original ha sido modificada para referirse a ejecutar múltiples versiones de un ejecutable, y no simplemente a intérpretes independientes.
Utilizando find-library
inspeccioné la fuente de ob-ruby
, que incluye este código:
(defvar org-babel-ruby-command "ruby"
"Name of command to use for executing ruby code.")
He visto referencias en otros lugares para usar Python org-babel-python-command
, por lo que existe en algunos otros idiomas, consulte el ob-$lang
soporte adecuado para ver.
Esto permite que funcione lo siguiente:
#+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]
Esto podría combinarse con :session python3
y :session python2
para evitar llamar a elisp antes de cada bloque. Sin embargo, parece que debería haber una manera más simple de hacer esto.
org-babel-post-tangle-hook
. Alguien debe implementar en org-babel-pre-tangle-hook
.
:interpreter
propiedad.
:interpreter
tiene sentido. Pero se org-babel-post-tangle-hook
ejecuta después de la ejecución del código a través C-c C-c
de un bloque de código. Supongo que pre
se ejecutará antes de la ejecución del código. Pero ahora me doy cuenta de que si cambia una variable global, tendría efectos secundarios negativos. :interpreter
seria mejor.
:interpreter
opción para org-babel-execute:js
. Pero luego, revisando la fuente org-babel-execute:js
, descubrí que ya hay una :cmd
opción que hace exactamente lo que quiero. Desafortunadamente, :cmd
no está disponible para todos los idiomas y tampoco encontré ninguna documentación, por ob-js
lo que inicialmente me perdí :cmd
la existencia.
:cmd
, pero parecía que solo se usaba para agregar argumentos al comando del intérprete. ¿Podría responder a su propia pregunta con un ejemplo completo que muestre el uso de :cmd
para resolver el problema para aquellos que tengan este problema en el futuro?
Creo que, por defecto, cada bloque se ejecuta en un intérprete independiente, incluso si es el mismo idioma. El comportamiento puede ser diferente para algunos idiomas. Por ejemplo, no estoy seguro de que los bloques emacs-lisp admitan la propiedad de sesión.
#+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
Los primeros dos bloques usan intérpretes independientes, pero el tercer y cuarto bloque comparten una sesión :foo
, por lo que evalúan en el mismo intérprete.
Resulta que, en casi todos los idiomas admitidos por Org Babel, no hay opción de usar un intérprete diferente para un bloque de código específico. Una excepción notable (y la que me interesa) es Javascript. En este caso, uno puede usar la :cmd
opción.
El intérprete JS estándar es node
, como se define en la variable org-babel-js-cmd
. Para ejecutar un bloque de código específico a través de un intérprete diferente, pase la :cmd
opción como en el siguiente ejemplo.
#+begin_src js :cmd "/usr/bin/osascript -l JavaScript"
app = Application.currentApplication()
app.includeStandardAdditions = true
app.say("Hello")
#+end_src