0

I've got the following issue:

(setq testvar '(link (:type "http" :path "//pygments.org/docs" :format 
bracket :raw-link "http://pygments.org/docs" :application nil)))

(setq testvar (nth 1 testvar))
(assoc :path testvar) ;;nil --- why?

I can't get a value of any of this keys, what I'm doing wrong?

  • 1
    How about: (plist-get testvar :path) The doc-string for assoc appears to indicate it is designed to be used differently: "Return non-nil if KEY is equal to the car of an element of LIST. The value is actually the first element of LIST whose car equals KEY." – lawlist Jun 11 '17 at 7:43
  • Awesome! Please provide this as the answer. – Anton Linevych Jun 11 '17 at 7:44
  • What makes you think that assoc would act as you expect? What did C-h f assoc or C-h S assoc tell you about its behavior? – Drew Jun 11 '17 at 17:24
4

According to the doc-string for assoc, it is used to: "Return non-nil if KEY is equal to the car of an element of LIST. The value is actually the first element of LIST whose car equals KEY." The manual contains a few examples: https://www.gnu.org/software/emacs/manual/html_node/elisp/Association-Lists.html

The function plist-get appears to be appropriate in this instance: (plist-get testvar :path). The doc-string for said function is as follows:

Extract a value from a property list.
PLIST is a property list, which is a list of the form
(PROP1 VALUE1 PROP2 VALUE2...).  This function returns the value
corresponding to the given PROP, or nil if PROP is not one of the
properties on the list.  This function never signals an error.
3

You've already received tips on what to use instead of assoc, but just to answer your original question: assoc expects a list of cons cells as input:

(setq testvar
      '((:type "http") (:path "//pygments.org/docs")
       (:format bracket) (:raw-link "http://pygments.org/docs")
       (:application nil)))

(assoc :path testvar)
==> (:path "//pygments.org/docs")

Note that when using symbols (or keywords, which are a special kind of keywords), it's more appropriate to use assq, because it uses eq for comparison, rather than equal.

Note also that you may think that (:path "//pygments.org/docs") isn't a cons cell, but it is. It's a cons cell with a list as second element:

(equal '(:path "//pygments.org/docs") '(:path . ("//pygments.org/docs")))
==> t

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.