1

When comparing the last-command against multiple possible strings, it doesn't seem possible to use the member function.

Is there a way to simplify this using something like member?

(when
  (or
    (string-equal last-command 'foo)
    (string-equal last-command 'bar)
    (string-equal last-command 'bob)
    (string-equal last-command 'baz))
  (do-something))

I tried doing this but it didn't work:

(when (member last-command (list 'foo 'bar 'bob 'baz))
  (do-something))
ideasman42
  • 8,375
  • 1
  • 28
  • 105
  • 1
    What you're showing here is not strings, but symbols. The only reason this works with `string-equal` is because it converts symbols to strings first. – wasamasa Dec 06 '19 at 15:09
  • Please don't change the question. If you have a new question, pose that separately. – Drew Dec 06 '19 at 15:21
  • Please specify what you mean by *"it didn't work"*. It works for me. I'm guessing that when you tried to test this `last-command` changed in the meantime, so it didn't match any of the symbols you expected. – Drew Dec 06 '19 at 15:22
  • I'm setting `this-command`, later comparing with `last-command`, using using `string-equal` succeeds, where as `member` does't. – ideasman42 Dec 06 '19 at 15:27
  • Sounds to me like you're setting one to a string and the other to a symbol, the only scenario where `string-equal` behaves differently from `equal`. – wasamasa Dec 06 '19 at 17:03

2 Answers2

2

Your code works fine, for me.

(when (member last-command (list 'foo 'bar 'bob 'baz)) (do-something))

First, last-command is typically a symbol, not a string. There is no reason to use string-equal for two symbols. It works, but it is slower - it just converts the symbols to strings and then compares those strings.

The best way to compare two symbols is with eq. eq compares two Lisp objects, i.e., they must be the same object to return non-nil. For a list, memq tests membership using eq.

Second, even if the things to compare were strings, member uses the test equal, which uses string-equal for string comparison.

If the question is really about last-command, and not about comparing symbols or strings, then be aware that last-command doesn't always return a symbol - see C-h v last-command.

The last command executed. Normally a symbol with a function definition, but can be whatever was found in the keymap, or whatever the variable `this-command' was set to by that command.

All the more reason to test with member, which uses equal.

(Also, you can just write '(foo bar bob baz) instead of (list 'foo 'bar 'bob 'baz). But this is unimportant.)

Drew
  • 75,699
  • 9
  • 109
  • 225
0

Assuming you actually intend comparing strings, many cl-lib functions support a :test keyword argument to specify the comparison function:

(cl-member "foo" '(foo bar baz) :test 'string-equal)
wasamasa
  • 21,803
  • 1
  • 65
  • 97