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?
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ć.
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.
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.
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.
Odpowiedzi:
Pierwotne pytanie zostało zmodyfikowane, aby dotyczyło uruchamiania wielu wersji pliku wykonywalnego, a nie tylko niezależnych tłumaczy.
Za pomocą
find-library
sprawdziłem źródłoob-ruby
, które zawiera ten kod:Widziałem odniesienia gdzie indziej dotyczące używania Pythona
org-babel-python-command
, więc istnieje on w innych językach, sprawdź odpowiednieob-$lang
wsparcie, aby zobaczyć.Umożliwia to działanie następujących elementów:
Można to połączyć z
:session python3
i,:session python2
aby uniknąć wywołania elisp przed każdym blokiem. Wydaje się jednak, że powinien istnieć prostszy sposób na zrobienie tego.źródło
org-babel-post-tangle-hook
. Ktoś powinien wdrożyć oorg-babel-pre-tangle-hook
.:interpreter
nieruchomości.:interpreter
ma sens. Aleorg-babel-post-tangle-hook
działa po wykonaniuC-c C-c
kodu w bloku kodu. Zakładampre
, że działałby przed wykonaniem kodu. Ale teraz zdaję sobie sprawę, że zmiana globalnej zmiennej miałaby złe skutki uboczne.:interpreter
byłoby lepiej.:interpreter
opcję doorg-babel-execute:js
. Ale po przejrzeniu źródłaorg-babel-execute:js
odkryłem, że istnieje już:cmd
opcja, która robi dokładnie to, co chcę. Niestety,:cmd
nie jest dostępny we wszystkich językach, a także nie znalazłem żadnej dokumentacji,ob-js
więc początkowo brakowało mi:cmd
istnienia.: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:cmd
rozwiązania problemu dla tych, którzy mają ten problem w przyszłości?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.
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.źródło
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
:cmd
opcji.Standardowy interpreter JS jest
node
zdefiniowany w zmiennejorg-babel-js-cmd
. Aby uruchomić określony blok kodu przez innego interpretera, przepuść:cmd
opcję jak w poniższym przykładzie.źródło