Intérprete específico de bloco de código no Org Babel

13

É possível ter, no mesmo arquivo organizacional, dois blocos de código no mesmo idioma que são executados em intérpretes diferentes, especificando opções diferentes na parte superior do bloco de código?

cefstat
fonte
2
Você quer dizer, por exemplo, versões diferentes do software instalado, por exemplo python26, python27 e python3? Ou apenas sessões python exclusivas, mas todas usando o mesmo executável? @dgtized explica o último.
Mankoff
2
Quero dizer versões diferentes do software instalado, ou seja, usando diferentes executáveis.
precisa saber é o seguinte

Respostas:

10

A pergunta original foi modificada para se preocupar em executar várias versões de um executável, e não apenas em intérpretes independentes.

Usando find-libraryeu inspecionei a fonte de ob-ruby, que inclui este código:

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

Já vi referências em outros lugares para o uso de python org-babel-python-command; portanto, ele existe em outras línguas. Verifique o ob-$langsuporte apropriado para ver.

Isso permite que o seguinte funcione:

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

Isso pode ser combinado com :session python3e :session python2para evitar a chamada elisp antes de cada bloco. Parece que deveria haver uma maneira mais simples de fazer isso.

dgtized
fonte
2
Existe um org-babel-post-tangle-hook. Alguém deve implementar em org-babel-pre-tangle-hook.
Mankoff
1
Não estou muito familiarizado com os internos, mas não tenho certeza de que o emaranhado seria a fase apropriada para fazer essa alteração? Honestamente, parece que o bloco precisa de uma :interpreterpropriedade.
dgtized
2
Também não estou muito familiarizado com isso. Sim :interpreterfaz sentido. Mas org-babel-post-tangle-hooké executado após a execução do código C-c C-cem um bloco de código. Presumo que preseria executado antes da execução do código. Mas agora percebo que se alterar uma variável global, teria efeitos colaterais ruins. :interpreterseria melhor.
Mankoff
1
Obrigado @dgtized e @mankoff por suas respostas. Eles me indicaram a direção certa. Foi um erro meu não especificar que estava interessado em código javascript. Com base nas suas respostas, decidi adicionar uma :interpreteropção ao org-babel-execute:js. Mas depois de pesquisar a fonte org-babel-execute:js, descobri que já existe uma :cmdopção que faz exatamente o que eu quero. Infelizmente, :cmdnão está disponível para todos os idiomas e também não encontrei nenhuma documentação, ob-jsentão inicialmente perdi :cmda existência.
Cefstat 23/10/2014
@cefstat observei :cmd, mas parecia que era usado apenas para acrescentar argumentos ao comando intérprete. Você poderia responder à sua própria pergunta com um exemplo completo mostrando o uso de :cmdpara resolver o problema daqueles que tiverem esse problema no futuro?
dgtized
1

Acredito que, por padrão, cada bloco é executado em um intérprete independente, mesmo que seja o mesmo idioma. O comportamento pode ser diferente para alguns idiomas. Por exemplo, não tenho certeza de que os blocos emacs-lisp suportem a propriedade 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

Os dois primeiros blocos usam intérpretes independentes, mas o terceiro e o quarto blocos compartilham uma sessão :foo, para que sejam avaliados no mesmo intérprete.

dgtized
fonte
2
Boa resposta na teoria, mas não responde à pergunta.
Mankoff
1

Acontece que, quase todos os idiomas suportados pela Org Babel, não há opção para usar um intérprete diferente para um bloco de código específico. Uma exceção notável (e aquela que me interessa) é o Javascript. Nesse caso, pode-se usar a :cmdopção

O intérprete JS padrão é node, como definido na variável org-babel-js-cmd. Para executar um bloco de código específico por meio de um intérprete diferente, passe a :cmdopção como no exemplo a seguir.

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