В 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)
Ответы:
Явно добавьте новый
#+name:
над#+results:
блоком.источник
#+name:
перед#+call:
строкой, поэтому она не добавляет никакой бухгалтерии к процессу: просто назовите результаты вместо определения. Может быть, это не так естественно, как могло бы, но, по крайней мере, это не обходной путь, требующий альтернативного решения.-result
результатов. Пожалуйста, добавьте примечание, что необходимо присвоить имя звонку и что имя результата должно совпадать с именем звонка-result
. По крайней мере, это то, что я заметил. (Если кто-то пропустит имя вызова, то при следующей переоценке будет добавлен новый результат, игнорирующий существующий именованный результат.-result
это просто соглашение об именах, которое я использовал для этого примера. Если вы явно ищете результаты исходного блока, добавьте его()
к имени при передаче имени в качестве переменной в другой блок или внутри ссылки на noweb.#+call
имя. Название результата можно выбрать произвольно. Если вызов не назван, вызовом генерируется дополнительная безымянная строка результата.Вы можете использовать
:post
-программу, которая выводит результат как:name
. Позвоните в ваш babel-block с помощью этой обычной процедуры и положите результат в ящик. В следующем примере эта пост-процедура называетсяasValue
.Другой способ избежать пересчета блоков кода -
:cache
аргумент заголовка. Если это установлено дляyes
блока кода, и его аргументы проверяются на наличие изменений, и если нет никаких изменений, предыдущий результат используется без переоценки блока исходного кода.источник
:cache yes
) является стандартным решением. Он также описан в руководстве org (см. Раздел 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`, а также имеет то преимущество, что он полностью разделяет блоки кода. Даже если вы редактируете первый блок кода и пробуете второй первый блок не оценивается. (В зависимости от задачи, которая может быть преимуществом или недостатком. Вы просто должны помнить об этом.)Я подозреваю, что вам просто нужно обновить свой режим Org. Это работает на моем конце (текущая версия разработки Org) и в целом должно работать как тег
release_8.3beta
. Ниже приведен коммит, который, я думаю, решает проблему, которую вы описываете.Помимо загрузки Org из репозитория git, другой вариант запуска более новой версии - это установка пакета ELPA .
источник
;)
Чтобы быть точным, мойorg-version
8.2.10. Я отредактировал вопрос с этой информацией, где он должен был быть в первую очередь.