Org-babel ile, bir işlev çağrısının sonuçlarını nasıl adlandırır ve yeniden kullanırsınız


9

Gelen org-mode, ben bir işlev, bir değişken tanımlamak için çalışıyor ve sonra başka değişkene ilk değişkeni fonksiyon çağrısının sonucunu atama ediyorum. Ancak, sonraki işlev çağrılarında bu yeni değişkeni kullanamaz gibi görünüyor.

İşlev çağrılarını satır içine almak işe yarar, ancak ilk önce bir değişkenin değerini etkilemek, ilk işlev çağrısında bir şeyler ters gittiğinde daha hızlı hata ayıklamaya ve potansiyel olarak pahalı hesaplamaların çoğaltılmasından kaçınmaya olanak tanır.

MWE: ( (require 'ob-emacs-lisp)gerekirse kullanın )

#+name: square
#+begin_src emacs-lisp :var x=3
  (message (format "%s" (* x x)))
#+end_src

#+RESULTS: square
: 9

#+name: value
: 45

#+name: squaredvalue
#+call: square(x=value)

#+RESULTS: squaredvalue
: 2025

Now I try to reuse this value: 

#+begin_src emacs-lisp :var res=squaredvalue
  (message res)
#+end_src

#+RESULTS:
: nil

Inlined calls do work:    

#+begin_src emacs-lisp :var res=square(value)
  (message res)
#+end_src

#+RESULTS:
: 2025

İkinci kod bloğunu genişletmek şunları gösterir:

(let ((res (quote "nil")))
  (message res))

Neyi kaçırıyorum?

(Bu, 8.2.10 org kullanılarak 24.3.1, 24.4 ve 24.5 emacs üzerinde test edilmiştir)


bence Kütüphane Babil ile ilgili bir şey.
yi.tang.uni

Yanıtlar:


7

Bloğun #+name:üstüne açıkça yeni ekleyin #+results:.

Not: kodunuzu Güncelleme (message res)için (message (format "%s" res))bir önlemek için Wrong type argument: stringp, 2025ek karışıklığa neden olmasını.

#+name: square
#+begin_src emacs-lisp :var x=3 
  (message (format "%s" (* x x)))
#+end_src

#+RESULTS: square
: 9

#+name: value
: 45

#+name: squaredvalue
#+call: square(x=value)

#+name: squaredvalue-results
#+RESULTS: squaredvalue
: 2025

#+begin_src emacs-lisp :var res=squaredvalue
   (message (format "%s" res))
#+end_src

#+RESULTS:
: nil


#+begin_src emacs-lisp :var res=squaredvalue-results
 (message (format "%s" res)) 
#+end_src

#+RESULTS:
: 2025


GNU Emacs 24.4.1 (x86_64-bilinmeyen-cygwin, GTK + Sürüm 3.10.9)
Kuruluş Modu Sürümü: 8.2.10 kullanılarak test edilmiştir


Tamam, bu kesinlikle bugüne kadarki en basit çözüm. Bu durumda, aslında satırdan #+name:önce gerek yoktur #+call:, bu nedenle sürece herhangi bir defter tutma eklemez: sadece tanım yerine sonuçları adlandırın. Belki olabildiğince doğal hissettirmez, ama en azından alternatif bir çözüm için yalvarmak değil.
T. Verron

Bu güzel (+1). Denedim ve org-modu 8.2.7c ile çalışıyor. İlginç bir şekilde Org Mode bilgi dokümanları araması -resultsonuç vermiyor . Lütfen çağrıyı adlandırmanın gerekli olduğunu ve sonucun adının son eklenmiş çağrının adı olması gerektiğini unutmayın -result. En azından ben de bunu belirtmiştim. (Birisi aramayı adlandırmayı kaçırırsa, bir sonraki yeniden değerlendirme mevcut adlandırılmış sonucu yok sayarak yeni bir sonuç ekler.
Tobias

@Tobias - Sadece açıklığa kavuşturmak -resultiçin, bu örnek için kullandığım bir adlandırma kuralı. Bir kaynak bloğunun sonuçlarını açıkça arıyorsanız (), adı başka bir bloğa veya noweb başvurusunun içine bir değişken olarak iletirken ada ekleyin.
Melioratus

1
Görünüşe göre tek gereksinim #+calladlandırılmış olmasıdır. Sonucun adı isteğe bağlı olarak seçilebilir. Çağrı adlandırılmazsa, çağrı tarafından ek bir adsız sonuç satırı oluşturulur.
Tobias

Kılavuzda bu davranışı açıklayan herhangi bir bölüm var mı?
Tobias

3

:postSonucu çıktı olarak veren bir- yordam kullanabilirsiniz :name. Babil bloğunuzu bu yazı rutini ile arayın ve sonucu bir çekmeceye koyun. Aşağıdaki örnekte bu gönderi yordamı adlandırılmıştır asValue.

#+name: asValue
#+begin_src emacs-lisp :var name="last" :var val=0 :results drawer
(format "#+NAME: %s\n: %s" name val)
#+end_src

#+name: square
#+begin_src emacs-lisp :var x=3
(message "Running square")
(* x x)
#+end_src

#+RESULTS: square
: 9

#+NAME: value
: 45

#+call: square(value) :post asValue(name="squaredValue",val=*this*) :results drawer

#+RESULTS:
:RESULTS:
#+NAME: squaredValue
: 2025
:END:

Now I try to reuse this value: 

#+begin_src emacs-lisp  :var res=squaredValue
  (format "Re-used value: %s" res)
#+end_src

#+RESULTS:
: Re-used value: 2025

Kod bloklarının yeniden hesaplanmasını önlemenin bir başka yolu da :cachebaşlık argümanıdır. Bu yeskod bloğuna ayarlanırsa ve argümanlarında değişiklik olup olmadığı kontrol edilirse ve değişiklik yoksa önceki sonuç kaynak kodu bloğunun yeniden değerlendirilmesi yapılmadan kullanılır.

* Running of source blocks with caching

#+name: square
#+begin_src emacs-lisp :cache yes :var x=4
(message "Running square")
(* x x)
#+end_src

#+RESULTS[31bcff57ec9977f9b237fdc62ab18b1378b8c646]: square
: 16

#+NAME: value
: 40

#+name: squaredValue
#+begin_src emacs-lisp :cache yes :var x=square(x=value)
x
#+end_src

#+RESULTS[f90a5856e446c3120f7e91c4b77959598078526e]: squaredValue
: 1600

Now I try to reuse this value: 

#+begin_src emacs-lisp  :var res=squaredValue
  (format "Re-used value: %s" res)
#+end_src

#+RESULTS:
: Re-used value: 1600

Re-trying with call:

#+NAME: value2
: 20

#+NAME: squaredResult
#+call: square(x=value2) :cache yes

#+RESULTS[2f7c47d4c609a1a49ce00b4696afb7b5a5517b97]: squaredResult
: 400

The last version gives the following error with org-mode 8.2.4 in emacs 24.3.1.
(I do not know why.)

Debugger entered--Lisp error: (wrong-type-argument integer-or-marker-p nil)
  org-babel-set-current-result-hash("94ef10d9192a0be25e46238df4cf05389ff69040")
  org-babel-lob-execute(("square(x=value2)" ":cache yes" 0 "squaredResult"))

Kesmeler için teşekkürler! Görünüşe göre her iki çözüm de işe yarıyor, ama biz bir şekilde "sadece dene, beklediğiniz gibi çalışacak" org felsefesi ile biraz uzaklaşıyoruz. Başka bir çözüm olmadığı ortaya çıkarsa, cevabı kabul edeceğim.
T. Verron

@ T.Verron Sanırım ikinci çözüm ( :cache yes) standart çözümdür. Ayrıca org-kılavuzunda da açıklanmaktadır (bkz. Bölüm 14.8.2.16 :cache'). It is a pity that it does not smoothly work with # + call . I think this is a bug. The first solution works with # + call`) ve ayrıca kod bloklarını tamamen ayırması avantajına sahiptir. (Avantaj veya dezavantaj olabilecek göreve bağlı olarak. Sadece aklınızda bulundurmanız gerekir.)
Tobias

Dün gece yoruldum, fark etmedim ... Son bloğun değerlendirilmesinde hata olmasa bile, soruda yazdıklarımdan daha iyi çalışır mıydı? Sonuçta, sorun her referans için çağrıyı yeniden değerlendirmesi değil (bu da bir sorun olurdu ve sonra evet, önbellek çözüm olurdu), ama hiç referans veremem.
T. Verron

@ T.Verron Kyle Meyer haklı. Orgmode.org/w/… değişiklikleri henüz bagaja girmedi. En yeni sürüm burada: orgmode.org/w/?p=org-mode.git;a=blob_plain;f=lisp/… . Ama, belki de, uyumsuz değişiklikler var ...
Tobias

@ T.Verron Yukarıda "gövde" değil, "kararlı salım" demek istedim. Bunun için üzgünüm. Cevabımı 1'i eksik özellik için geçici çözüm olarak görebilirsiniz.
Tobias

3

Kuruluş modunuzu yükseltmeniz gerektiğinden şüpheleniyorum. Bu benim sonımda (Org'un şu anki gelişimsel sürümü) çalışıyor ve genel olarak etiketten sonra çalışmalıdır release_8.3beta. Aşağıda, açıklamakta olduğunuz sorunu giderdiğini düşünüyorum.

commit 1877652ce0234cf333fa103b5ada08fbf5946ab1
Date:   Wed Nov 13 11:42:40 2013 -0700

    allow reference to named call lines

    * lisp/ob-ref.el (org-babel-ref-resolve): Look for call lines when
      resolving references.

Git deposundan Org yüklemesinin yanı sıra, daha yeni bir sürüm çalıştırmak için başka bir seçenek de ELPA paketini yüklemektir .


Eh, geliştirme sürümü kullanmak olmayabilir, ama ben değilim 2013 yılından beri ben güncellemediğiniz anlamına gelmez olduğunu geç. ;)Kesin olmak gerekirse, benim org-version8.2.10. Soruyu ilk etapta olması gereken bu bilgilerle düzenledim.
T. Verron

Hata, yanlış bilgi için üzgünüm. Bu taahhüt olmalı, ancak 8.2.10'da yer almıyor.
Kyle Meyer

Bu işlem hakkında nerede bir tartışma bulabileceğimi biliyor musunuz?
T. Verron

Bu konuda bir tartışma varsa, büyük olasılıkla Org modu listesinde olurdu, ancak arayarak bir tane bulamadım ve taahhüt mesajında ​​referans verilen bir tane yok, bu yüzden biri olmayabilir.
Kyle Meyer
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.