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?


2
¿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 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 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.


2
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.


2
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.

#+begin_src js :cmd "/usr/bin/osascript -l JavaScript"
app = Application.currentApplication()
app.includeStandardAdditions = true
app.say("Hello")
#+end_src
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.