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).

miguelmorin
  • 1,751
  • 11
  • 33
  • 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 '19 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 '19 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 '19 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 '19 at 22:52

1 Answers1

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.

Drew
  • 75,699
  • 9
  • 109
  • 225
  • Today I get the same result as you and the opposite of yesterday. Do you have an idea why? – miguelmorin Dec 15 '19 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 '19 at 15:19
  • I discovered why and updated the question. – miguelmorin Dec 16 '19 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? – miguelmorin Dec 17 '19 at 07:30
  • 1
    No need to pose that question - it would be a duplicate of this one: https://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 '19 at 17:44
  • You're right, and I updated my question to what I should have asked. – miguelmorin Dec 18 '19 at 14:21