Interpreter specyficzny dla bloku kodu w Org Babel


13

Czy można mieć w tym samym pliku org dwa bloki kodu w tym samym języku, które działają w różnych interpretatorach, podając różne opcje na górze bloku kodu?


2
Czy masz na przykład na myśli różne wersje zainstalowanego oprogramowania, na przykład python26, python27 i python3? A może po prostu unikalne sesje Pythona, ale wszystkie przy użyciu tego samego pliku wykonywalnego? @dgtized wyjaśnia to drugie.
mankoff

2
Mam na myśli różne wersje zainstalowanego oprogramowania, tj. Wykorzystujące różne pliki wykonywalne.
cefstat

Odpowiedzi:


10

Pierwotne pytanie zostało zmodyfikowane, aby dotyczyło uruchamiania wielu wersji pliku wykonywalnego, a nie tylko niezależnych tłumaczy.

Za pomocą find-librarysprawdziłem źródło ob-ruby, które zawiera ten kod:

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

Widziałem odniesienia gdzie indziej dotyczące używania Pythona org-babel-python-command, więc istnieje on w innych językach, sprawdź odpowiednie ob-$langwsparcie, aby zobaczyć.

Umożliwia to działanie następujących elementów:

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

Można to połączyć z :session python3i, :session python2aby uniknąć wywołania elisp przed każdym blokiem. Wydaje się jednak, że powinien istnieć prostszy sposób na zrobienie tego.


2
Jest org-babel-post-tangle-hook. Ktoś powinien wdrożyć o org-babel-pre-tangle-hook.
mankoff

1
Nie znam się dobrze na elementach wewnętrznych, ale nie jestem pewien, czy splątanie byłoby odpowiednim etapem do wprowadzenia tej zmiany? Szczerze mówiąc, wygląda na to, że blok potrzebuje :interpreternieruchomości.
zdiagnozowano

2
Nie znam się też zbyt dobrze. Tak :interpreterma sens. Ale org-babel-post-tangle-hookdziała po wykonaniu C-c C-ckodu w bloku kodu. Zakładam pre, że działałby przed wykonaniem kodu. Ale teraz zdaję sobie sprawę, że zmiana globalnej zmiennej miałaby złe skutki uboczne. :interpreterbyłoby lepiej.
mankoff

1
Dziękuję @dgtized i @mankoff za odpowiedzi. Wskazali mi właściwy kierunek. To mój błąd, że nie sprecyzowałem, że jestem zainteresowany kodem javascript. Na podstawie twoich odpowiedzi postanowiłem dodać :interpreteropcję do org-babel-execute:js. Ale po przejrzeniu źródła org-babel-execute:jsodkryłem, że istnieje już :cmdopcja, która robi dokładnie to, co chcę. Niestety, :cmdnie jest dostępny we wszystkich językach, a także nie znalazłem żadnej dokumentacji, ob-jswięc początkowo brakowało mi :cmdistnienia.
cefstat

@cefstat Zauważyłem :cmd, ale wyglądało to tak, jakby służyło tylko do dołączania argumentów do polecenia interpretera. Czy mógłbyś odpowiedzieć na swoje pytanie z pełnym przykładem pokazującym zastosowanie :cmdrozwiązania problemu dla tych, którzy mają ten problem w przyszłości?
zdiagnozowano

1

Wierzę, że domyślnie każdy blok działa w niezależnym tłumaczu, nawet jeśli jest to ten sam język. W niektórych językach zachowanie może być inne. Na przykład nie jestem pewien, czy bloki emacs-lisp obsługują właściwość sesji.

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

Pierwsze dwa bloki używają niezależnych tłumaczy, ale trzeci i czwarty blok współużytkują sesję :foo, aby oceniać w tym samym tłumaczu.


2
Dobra odpowiedź w teorii, ale nie odpowiada na pytanie.
mankoff

1

Okazuje się, że w prawie wszystkich językach obsługiwanych przez Org Babel nie ma opcji użycia innego interpretera dla określonego bloku kodu. Jednym godnym uwagi wyjątkiem (i tym, który mnie interesuje) jest JavaScript. W takim przypadku można skorzystać z :cmdopcji.

Standardowy interpreter JS jest nodezdefiniowany w zmiennej org-babel-js-cmd. Aby uruchomić określony blok kodu przez innego interpretera, przepuść :cmdopcję jak w poniższym przykładzie.

#+begin_src js :cmd "/usr/bin/osascript -l JavaScript"
app = Application.currentApplication()
app.includeStandardAdditions = true
app.say("Hello")
#+end_src
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.