Intérprete específico de bloque de código en Org Babel
13
¿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?
¿Quiere decir, por ejemplo, diferentes versiones de software instalado, por ejemplo python26, python27 y python3? ¿O solo sesiones únicas de Python, pero todas usando el mismo ejecutable? @dgtized explica lo último.
mankoff
2
Me refiero a diferentes versiones de software instalado, es decir, usando diferentes ejecutables.
cefstat
Respuestas:
10
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-libraryinspeccioné 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-$langsoporte adecuado para ver.
Esto podría combinarse con :session python3y :session python2para evitar llamar a elisp antes de cada bloque. Sin embargo, parece que debería haber una manera más simple de hacer esto.
Hay un org-babel-post-tangle-hook. Alguien debe implementar en org-babel-pre-tangle-hook.
mankoff
1
No estoy muy familiarizado con los aspectos internos, pero no estoy seguro de que el enredo sea la fase adecuada para hacer este cambio. Honestamente, parece que el bloque necesita una :interpreterpropiedad.
dgtized
2
Tampoco estoy muy familiarizado con eso. Si :interpretertiene sentido. Pero se org-babel-post-tangle-hookejecuta después de la ejecución del código a través C-c C-cde un bloque de código. Supongo que prese 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. :interpreterseria mejor.
mankoff
1
Gracias @dgtized y @mankoff por sus respuestas. Me señalaron la dirección correcta. Fue mi error no haber especificado que estaba interesado en el código JavaScript. Con base en sus respuestas he decidido añadir una :interpreteropción para org-babel-execute:js. Pero luego, revisando la fuente org-babel-execute:js, descubrí que ya hay una :cmdopción que hace exactamente lo que quiero. Desafortunadamente, :cmdno está disponible para todos los idiomas y tampoco encontré ninguna documentación, por ob-jslo que inicialmente me perdí :cmdla existencia.
cefstat
@cefstat noté :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 :cmdpara resolver el problema para aquellos que tengan este problema en el futuro?
dgtized
1
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.
Buena respuesta en teoría, pero no responde la pregunta.
mankoff
1
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 :cmdopció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 :cmdopción como en el siguiente ejemplo.
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 deob-ruby
, que incluye este código:He visto referencias en otros lugares para usar Python
org-babel-python-command
, por lo que existe en algunos otros idiomas, consulte elob-$lang
soporte adecuado para ver.Esto permite que funcione lo siguiente:
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.fuente
org-babel-post-tangle-hook
. Alguien debe implementar enorg-babel-pre-tangle-hook
.:interpreter
propiedad.:interpreter
tiene sentido. Pero seorg-babel-post-tangle-hook
ejecuta después de la ejecución del código a travésC-c C-c
de un bloque de código. Supongo quepre
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 paraorg-babel-execute:js
. Pero luego, revisando la fuenteorg-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, porob-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.
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.fuente
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 variableorg-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.fuente