ด้วย org-babel วิธีตั้งชื่อผลลัพธ์ของการเรียกฟังก์ชันและนำกลับมาใช้ใหม่


9

ในorg-modeฉันพยายามกำหนดฟังก์ชั่น, ตัวแปรแล้วกำหนดให้ตัวแปรอื่นเป็นผลลัพธ์ของการเรียกใช้ฟังก์ชันบนตัวแปรแรก อย่างไรก็ตามดูเหมือนว่าฉันไม่สามารถใช้ตัวแปรใหม่นี้ในการเรียกฟังก์ชั่นที่ตามมา

การเชื่อมการเรียกฟังก์ชันใช้งานได้ แต่มีผลกับค่าของตัวแปรก่อนจะอนุญาตให้ทำการดีบักได้เร็วขึ้นในกรณีที่มีสิ่งผิดปกติในการเรียกใช้ฟังก์ชันแรกและเพื่อหลีกเลี่ยงการคำนวณซ้ำที่อาจมีราคาแพง

MWE: (ใช้(require 'ob-emacs-lisp)ถ้าจำเป็น)

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

การขยายบล็อคโค้ดที่สองแสดง:

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

ฉันพลาดอะไรไป

(สิ่งนี้ได้รับการทดสอบบน emacs 24.3.1, 24.4 และ 24.5 โดยใช้ org 8.2.10)


ฉันคิดว่าจะทำอะไรกับ Babel of Library
yi.tang.uni

คำตอบ:


7

เพิ่มใหม่อย่างชัดเจน#+name:เหนือ#+results:บล็อก

หมายเหตุ:อัปเดตรหัสของคุณจาก(message res)เป็น(message (format "%s" res))เพื่อป้องกันไม่ให้Wrong type argument: stringp, 2025เกิดความสับสนเพิ่มเติม

#+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-unknown-cygwin, GTK + เวอร์ชัน 3.10.9)
Org-Mode เวอร์ชั่น: 8.2.10


ตกลงนั่นเป็นทางออกที่ง่ายที่สุดในปัจจุบัน ในกรณีนี้ไม่จำเป็นต้อง#+name:มี#+call:บรรทัดก่อนหน้าดังนั้นจึงไม่เพิ่มการทำบัญชีใด ๆ ในกระบวนการ: เพียงตั้งชื่อผลลัพธ์แทนคำจำกัดความ อาจจะไม่รู้สึกเป็นธรรมชาติเท่าที่จะทำได้ แต่อย่างน้อยนั่นก็ไม่ใช่วิธีแก้ปัญหาสำหรับทางเลือกอื่น
T. Verron

นี่เป็นสิ่งที่ดี (+1) ฉันลองแล้วมันใช้งานได้กับโหมด org 8.2.7c น่าสนใจว่าการค้นหาเอกสารข้อมูลของ Org Mode สำหรับการ-resultส่งคืนไม่มีผลลัพธ์ กรุณาเพิ่มทราบว่าการตั้งชื่อโทรถูกต้องและว่าชื่อของผลที่ได้จะต้องเป็นชื่อของการโทร suffixed -resultโดย อย่างน้อยนั่นคือสิ่งที่ฉันสังเกต (หากใครพลาดที่จะตั้งชื่อการโทรการประเมินใหม่ครั้งต่อไปจะเพิ่มผลลัพธ์ใหม่โดยไม่สนใจผลลัพธ์ที่มีชื่อเดิม
Tobias

@Tobias - เพียงเพื่อชี้แจง-resultเป็นเพียงการตั้งชื่อฉันใช้สำหรับตัวอย่างนี้ หากคุณกำลังมองหาผลลัพธ์ของบล็อกอย่างชัดเจนให้เพิ่ม()ชื่อเมื่อส่งชื่อเป็นตัวแปรไปยังบล็อกอื่นหรือภายในการอ้างอิง noweb
Melioratus

1
ดูเหมือนว่าความต้องการเพียงอย่างเดียว#+callคือชื่อ ชื่อของผลลัพธ์สามารถเลือกได้เอง หากการโทรไม่มีชื่อจะมีการสร้างบรรทัดผลลัพธ์ที่ไม่มีชื่อเพิ่มเติมโดยการโทร
โทเบียส

มีส่วนใดบ้างในคู่มือที่อธิบายพฤติกรรมนั้น
โทเบียส

3

คุณสามารถใช้:post-routine ซึ่งแสดงผลลัพธ์:nameดังนี้ โทรหาบล็อกของคุณด้วยชุดโพสต์นี้และวางผลลงในลิ้นชัก 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

อีกวิธีในการหลีกเลี่ยงการคำนวณบล็อคโค้ดอีกครั้งคือ:cacheอาร์กิวเมนต์ของส่วนหัว หากมีการตั้งค่าyesบล็อกรหัสและอาร์กิวเมนต์จะถูกตรวจสอบการเปลี่ยนแปลงและหากไม่มีการเปลี่ยนแปลงผลลัพธ์ก่อนหน้านี้จะถูกนำมาใช้โดยไม่ต้องประเมินบล็อกโค้ดต้นฉบับอีกครั้ง

* 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"))

ขอบคุณสำหรับการแฮ็ก! ดูเหมือนว่าการแก้ปัญหาทั้งสองทำงานได้ แต่เราค่อนข้างจะได้รับ "เพียงลองมันจะทำงานในแบบที่คุณคาดหวัง" ปรัชญาขององค์กร หากปรากฎว่าไม่มีวิธีอื่นฉันจะยอมรับคำตอบ
ต. Verron

@ T.Verron ฉันคิดว่าโซลูชันที่สอง ( :cache yes) เป็นโซลูชันมาตรฐาน มันยังได้อธิบายไว้ในคู่มือการใช้งานองค์กร (ดูหัวข้อ 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` และยังมีข้อได้เปรียบที่ถอดรหัสการบล็อคโค้ดได้อย่างสมบูรณ์แม้ว่าคุณจะแก้ไขบล็อคโค้ดแรกและลองบล็อกที่สองอันแรก ไม่ได้รับการประเมิน (ขึ้นอยู่กับงานที่อาจเป็นข้อได้เปรียบหรือความไม่พอใจคุณเพียงแค่จำไว้)
โทเบียส

เมื่อคืนฉันเหนื่อยฉันไม่ได้สังเกต ... แม้ว่าจะไม่มีข้อผิดพลาดในการประเมินบล็อกสุดท้ายมันจะทำงานได้ดีกว่าที่เขียนไว้ในคำถามหรือไม่ ท้ายที่สุดปัญหาไม่ใช่ว่าจะประเมินการโทรสำหรับการอ้างอิงแต่ละครั้ง (จะเป็นปัญหาด้วยและจากนั้นใช่แคชจะเป็นวิธีแก้ปัญหา) แต่ฉันไม่สามารถอ้างอิงได้เลย
ต. Verron

@ T.Verron Kyle Meyer ถูกต้อง การเปลี่ยนแปลงorgmode.org/w/…ยังไม่ได้ทำให้มันอยู่ในหีบ รุ่นใหม่ล่าสุดอยู่ที่นี่: orgmode.org/w/?p=org-mode.git;a=blob_plain;f=lisp/... แต่อาจมีการเปลี่ยนแปลงที่เข้ากันไม่ได้ ...
Tobias

@ T. Veron ด้านบนฉันหมายถึง "การปล่อยเสถียร" และไม่ใช่ "ลำตัว" ขอโทษด้วยกับเรื่องนั้น. คุณสามารถเห็นคำตอบของฉัน 1 เป็นวิธีแก้ปัญหาสำหรับคุณสมบัติที่ขาดหายไป
โทเบียส

3

ฉันสงสัยว่าคุณเพียงแค่ต้องอัพเกรดโหมด Org ของคุณ งานนี้ในส่วนของฉัน (รุ่นปัจจุบันพัฒนาการขององค์กร) release_8.3betaและโดยทั่วไปควรจะทำงานในฐานะของแท็ก ด้านล่างคือความมุ่งมั่นที่ฉันคิดว่าจะแก้ไขปัญหาที่คุณอธิบาย

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.

นอกเหนือจากการโหลดขององค์กรจาก repo คอมไพล์ตัวเลือกสำหรับการทำงานรุ่นใหม่อื่นคือการติดตั้งแพคเก ELPA


ดีฉันอาจจะไม่ใช้รุ่นพัฒนา แต่ไม่ได้หมายความว่าผมยังไม่ได้รับการปรับปรุงมาตั้งแต่ปี 2013 ผมไม่ได้ว่าปลาย ;)เพื่อความแม่นยำของฉันorg-versionคือ 8.2.10 ฉันได้แก้ไขคำถามด้วยข้อมูลนี้ซึ่งควรจะอยู่ในสถานที่แรก
ต. Verron

โอ๊ะโอขออภัยในความเข้าใจผิด นั่นควรจะเป็นความมุ่งมั่น แต่มันไม่ได้อยู่ใน 8.2.10
Kyle Meyer

คุณจะรู้ว่าฉันสามารถหาการสนทนาเกี่ยวกับความมุ่งมั่นนี้ได้ที่ไหน?
ต. Verron

หากมีการอภิปรายเกี่ยวกับเรื่องนี้น่าจะอยู่ในรายการโหมดองค์กร แต่ฉันไม่พบใครด้วยการค้นหาและไม่มีใครอ้างอิงในข้อความยืนยันดังนั้นจึงอาจไม่มี
Kyle Meyer
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.