2

Why does my code generate the error when used with org-table?

No error message when code used outside of org-table

#+NAME: get-country-or-area-name
#+HEADER: :var iso-alpha2-code="ca" 
#+HEADER: :var dc-list='((US . "United States of America") (CA . "Canada") (BR . "Brazil"))
#+BEGIN_SRC elisp 
  (setq s (upcase (substring iso-alpha2-code 0 2)))
  (cdr (assoc-string `,s dc-list)) 
#+END_SRC

#+NAME: Brazil
#+CALL: get-country-or-area-name(iso-alpha2-code="br")

#+RESULTS: Brazil
: Brazil

#+NAME: Canada
#+CALL: get-country-or-area-name(iso-alpha2-code="ca")

#+RESULTS: Canada
: Canada

#+NAME: United-States-of-America
#+CALL: get-country-or-area-name(iso-alpha2-code="us")

#+RESULTS: United-States-of-America
: United States of America

Error generated when called in #+TBLFM:

The error is generated when org-table-calc-current-TBLFM attempts to delete the temporary #+TBLFM: line.

Before:

| ISO Alpha 2 Code | Country or Area Name     |
|------------------+--------------------------|
| BR               |                          |
| CA               |                          |
| US               |                          |
#+TBLFM: $2='(org-sbe get-country-or-area-name (iso-alpha2-code $$1))

After:

| ISO Alpha 2 Code | Country or Area Name     |
|------------------+--------------------------|
| BR               | Brazil                   |
| CA               | Canada                   |
| US               | United States of America |
#+TBLFM: $2='(org-sbe get-country-or-area-name (iso-alpha2-code $$1))
#+TBLFM: $2='(org-sbe get-country-or-area-name (iso-alpha2-code $$1))

Excerpt from *Messages* buffer:

Re-applying formulas to 3 lines… done
Re-applying formulas… done
org-table-calc-current-TBLFM: Wrong type argument: integer-or-marker-p, "US"


Thanks for your help!!


Version Info

org-mode version: 8.3.5
emacs version: GNU Emacs 24.5.1 (x86_64-unknown-cygwin, GTK+ Version 3.14.13)

2

Ah, very nice. Remember that elisp is dynamically scoped, so any function that you call can see and overwrite any variable you define, and any function that you write can do the same for any variable defined anywhere in the call stack.

In this case, org-table-calc-current-TBLFM defines two variables s and e to hold the start and end positions of the temporary formula. After the table is recalculated it uses those markers to delete the temporary formula. However, your source block sets s to a string, and this overwrites the marker held by org-table-calc-current-TBLFM. You can see in the error message that it expected a marker and got the string "US".

To fix it, just define your own local variable rather than overwriting someone else's. It's still dynamically scoped, but it will shadow the other variable of the same name and then go away once your source block (aka a function) is done:

#+NAME: get-country-or-area-name
#+HEADER: :var iso-alpha2-code="ca"
#+HEADER: :var dc-list='((US . "United States of America") (CA . "Canada") (BR . "Brazil"))
#+BEGIN_SRC elisp
  (let ((s (upcase (substring iso-alpha2-code 0 2))))
    (cdr (assoc-string s dc-list)))
#+END_SRC

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.