Trình thông dịch cụ thể khối mã trong Org Babel


13

Có thể có, trong cùng một tệp org, hai khối mã trong cùng một ngôn ngữ được chạy trong các trình thông dịch khác nhau bằng cách chỉ định các tùy chọn khác nhau ở đầu khối mã không?


2
Bạn có nghĩa là, ví dụ, các phiên bản khác nhau của phần mềm đã cài đặt, ví dụ python26, python27 và python3? Hoặc chỉ là các phiên python duy nhất, nhưng tất cả đều sử dụng cùng một tệp thực thi? @dgtized giải thích cái sau.
mankoff

2
Tôi có nghĩa là các phiên bản khác nhau của phần mềm được cài đặt, tức là sử dụng các tệp thực thi khác nhau.
cefstat

Câu trả lời:


10

Câu hỏi ban đầu đã được sửa đổi liên quan đến việc chạy nhiều phiên bản của một tệp thực thi và không chỉ đơn giản là các thông dịch viên độc lập.

Sử dụng find-librarytôi đã kiểm tra nguồn của ob-ruby, bao gồm mã này:

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

Tôi đã thấy các tài liệu tham khảo ở nơi khác cho python sử dụng org-babel-python-command, vì vậy nó tồn tại trong một số ngôn ngữ khác, kiểm tra ob-$langhỗ trợ phù hợp để xem.

Điều này cho phép các công việc sau:

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

Điều này có thể được kết hợp với :session python3:session python2để tránh gọi elisp trước mỗi khối. Dường như có một cách đơn giản hơn để làm điều này mặc dù.


2
Có một org-babel-post-tangle-hook. Ai đó nên thực hiện tại org-babel-pre-tangle-hook.
mankoff

1
Tôi không quen thuộc lắm với những người bên trong, nhưng tôi không chắc rằng rối sẽ là giai đoạn thích hợp để thực hiện thay đổi này? Thành thật mà nói, có vẻ như khối cần một :interpretertài sản.
dgtized

2
Tôi cũng không quá quen thuộc với nó. Có :interpreterý nghĩa. Nhưng org-babel-post-tangle-hookchạy sau khi thực thi mã thông qua C-c C-ctrong một khối mã. Tôi giả sử presẽ chạy trước khi thực thi mã. Nhưng tôi nhận ra bây giờ nếu thay đổi một biến toàn cầu, nó sẽ có tác dụng phụ xấu. :interpretersẽ tốt hơn.
mankoff

1
Cảm ơn bạn @dgtized và @mankoff vì câu trả lời của bạn. Họ chỉ cho tôi đi đúng hướng. Đó là sai lầm của tôi mà tôi đã không xác định rằng tôi quan tâm đến mã javascript. Dựa trên câu trả lời của bạn, tôi quyết định thêm một :interpretertùy chọn org-babel-execute:js. Nhưng sau đó đi qua nguồn cho org-babel-execute:jstôi thấy rằng đã có một :cmdtùy chọn thực hiện chính xác những gì tôi muốn. Thật không may, :cmdkhông có sẵn cho tất cả các ngôn ngữ và tôi cũng không tìm thấy bất kỳ tài liệu nào ob-jsvì vậy ban đầu tôi đã bỏ lỡ :cmdsự tồn tại của nó.
cefstat

@cefstat Tôi đã lưu ý :cmd, nhưng có vẻ như nó chỉ được sử dụng để nối các đối số vào lệnh phiên dịch. Bạn có thể vui lòng trả lời câu hỏi của riêng bạn với một ví dụ đầy đủ cho thấy việc sử dụng :cmdđể giải quyết vấn đề cho những người có vấn đề này trong tương lai không?
dgtized

1

Tôi tin theo mặc định mỗi khối chạy trong một trình thông dịch độc lập ngay cả khi đó là cùng một ngôn ngữ. Hành vi có thể khác nhau đối với một số ngôn ngữ. Chẳng hạn, tôi không chắc chắn rằng các khối emacs-lisp hỗ trợ thuộc tính phiê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

Hai khối đầu tiên sử dụng trình thông dịch độc lập, nhưng khối thứ ba và thứ tư chia sẻ một phiên :foo, để chúng đánh giá trong cùng một trình thông dịch.


2
Câu trả lời tốt trong lý thuyết, nhưng không trả lời câu hỏi.
mankoff

1

Nó chỉ ra rằng hầu như tất cả các ngôn ngữ được hỗ trợ bởi Org Babel không có tùy chọn để sử dụng một trình thông dịch khác cho một khối mã cụ thể. Một ngoại lệ đáng chú ý (và một ngoại lệ khiến tôi quan tâm) là Javascript. Trong trường hợp này, người ta có thể sử dụng :cmdtùy chọn.

Trình thông dịch JS tiêu chuẩn là node, như được định nghĩa trong biến org-babel-js-cmd. Để chạy một khối mã cụ thể thông qua một trình thông dịch khác, hãy chuyển :cmdtùy chọn như trong ví dụ sau.

#+begin_src js :cmd "/usr/bin/osascript -l JavaScript"
app = Application.currentApplication()
app.includeStandardAdditions = true
app.say("Hello")
#+end_src
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.