0

In the Emacs *scratch* buffer, I get different results when I use the same regular expression as a variable compared to a literal:

(setq splitter-string "9:20")
"9:20"

(string-match "[0-9]?[0-9]:[0-9][0-9]" splitter-string)
0

(defvar org-clock-split-absolute-time-regexp "[0-9]?[0-9]:[0-9][0-9]"
  "Regular expression to match an absolute time to split at.")
org-clock-split-absolute-time-regexp

(string-match org-clock-split-absolute-time-regexp splitter-string)
nil

What is the difference between a variable and a literal for regular expressions?

Update: The problem stems from the inability to overwrite a variable defined with defvar, as below in the scratch buffer:

(defvar pattern "some pattern"
  "Some regular expression")
pattern

pattern
"some pattern"

(defvar pattern "[a-z]*"
  "Some regular expression")
pattern

pattern
"some pattern"

(string-match "[a-z]*" "abcdefg")
0

(string-match pattern "abcdefg")
nil

I would not do this in final code, but may do it in the scratch buffer during development. The problem is about defvar, and a duplicate of this question, and not about regular expressions (I knew about the different syntaxes with re-builder and suspected it was about that).

4
  • 1
    If evaluating defvar clobbered an existing value of the variable, loading (or reloading) a library would trash the user's configuration for it. It's important that users can (setq VAR VALUE) even when the library which defines VAR hasn't yet been loaded.
    – phils
    Dec 16, 2019 at 22:41
  • 1
    However, there is a provision for doing this, for development purposes. If you use eval-defun -- C-M-x by default -- to evaluate the defvar form, it will set the value. (n.b. the same things apply to defcustom as well.)
    – phils
    Dec 16, 2019 at 22:43
  • 1
    Alternatively, if the value is intended to never vary, you can use defconst instead of defvar, and the value will be set every time the defconst is evaluated.
    – phils
    Dec 16, 2019 at 22:44
  • 1
    Finally, you can of course use setq (or any other way of "setting a variable") to update the value. (And unless you are working on the library which defines the variable, this is all you should be doing.)
    – phils
    Dec 16, 2019 at 22:52

1 Answer 1

1

That's not what I see. They both return 0, for me, starting with emacs -Q (no init file).

If you haven't already, try starting Emacs with emacs -Q. If that works then bisect your init file to find the problem.


Updated after your update (which really poses a separate question -- you should pose only one question per post).

  • You can evaluate a defvar by putting your cursor on it somewhere and using C-M-x.

  • The reason that defvar doesn't do anything just by evaluating it normally, if the variable already has a value, is to allow you to use a defvar in your own code (e.g. init file) to override any defvar for the same variable that might get evaluated when loading some library after you have set the variable value.

See the Emacs manual, node Lisp Eval. It describes the behavior this way:

The eval-defun command is bound to C-M-x in Emacs Lisp mode. It evaluates the top-level Lisp expression containing or following point, and prints the value in the echo area. In this context, a top-level expression is referred to as a “defun”, but it need not be an actual defun (function definition). In particular, this command treats defvar expressions specially.

Normally, evaluating a defvar expression does nothing if the variable it defines already has a value. But this command unconditionally resets the variable to the initial value specified by the defvar; this is convenient for debugging Emacs Lisp programs. defcustom and defface expressions are treated similarly. Note that the other commands documented in this section do not have this special feature.

6
  • Today I get the same result as you and the opposite of yesterday. Do you have an idea why? Dec 15, 2019 at 22:46
  • No idea. Did you use emacs -Q in both cases? If not, bisect your init file to perhaps find the culprit. If you did use no init file in both cases, did you do something else different, before your recipe?
    – Drew
    Dec 16, 2019 at 15:19
  • I discovered why and updated the question. Dec 16, 2019 at 22:35
  • I kept it in the same question as it was the reason for that behavior. Shall I create another question only on defvar evaluation? Dec 17, 2019 at 7:30
  • 1
    No need to pose that question - it would be a duplicate of this one: emacs.stackexchange.com/q/2298/105. It's a good idea to search first, to see if a question has already been posed. Searching for "defvar" finds this question (and answer).
    – Drew
    Dec 17, 2019 at 17:44

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

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