help-gnu-emacs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

RE: In defense of Customize [was: Trying to right-align my window on s


From: Drew Adams
Subject: RE: In defense of Customize [was: Trying to right-align my window on startup]
Date: Thu, 16 Jan 2014 07:33:46 -0800 (PST)

> >> I would like to have a "custom-setq" which set a var, checked to see
> >> whether the types were correct wrt customize, then crashed if not. It
> >> would be nice to use the knowledge of customize from lisp.
> >
> > See commands `customize-set-variable' and `customize-set-value'.
> 
> These don't do quite what I want.

See below - you might change your mind about that.

> As a random example,

It would be better to choose an example from the distributed vanilla
Emacs code.  Emacs Dev is more likely (but far from guaranteed) to
use :type wisely and write accurate doc strings than is a random
3rd-party library developer.

> consider this:
> (defcustom pulse-flag (pulse-available-p)
>   "...
> If the value is nil, ...
> If the value is `never', ...
> Any other value means ...."
>   :group 'pulse :type 'boolean)

OK, the doc does not match the :type spec.  So let's see what
the story is.

There are a couple of possibilities.

1. It could be that the intention was that the value really must
be as the doc describes it, and any other value should raise an
error. In which case, code that uses the option can and even
perhaps should depend on that.  In that case, the :type is
incorrect.

Perhaps the programmer was lazy wrt specifying :type.  See my
earlier post about that - users of defcustom should get to know
:type and do their best to use it to advantage.

2. It could be that the :type spec is correct and the doc string
is inaccurate.  Seems unlikely in this case, but could be checked
by looking at how it is used in the library that defines it.
It is checked only by `eq'uality with symbol `never' and with nil.

One might conclude that the programmer in this case was lazy or
ignorant wrt :type, or just didn't care.  It's also possible,
however, that this was the intention: a disconnect between the
actual possible values and the values users can set using
Customize.  A programmer *can* intend such a disconnect (though
in that case it might be appropriate to document that, either
in the program doc or code comments).

The code itself never sets a value of `never', so it seems
unlikely that this is intended as an internal value (especially
since it is advertised in the doc string).  Rather, it is likely
intended as a value that users can use.

Is it intentional that users *cannot* set the value to `never'
using Customize?  Dunno.

My guess in this case would be that this is yet another case of
a programmer being lazy or not sufficiently :type-savvy.  That
is all too common - in part perhaps because some tend to give
Customize a back seat, thinking it is only for wimps.  (Akin to
a certain lack of respect for users, in my book.)

My guess is that what was meant was something like this:

:type '(choice
         (const :tag "Do not color"          never)
         (const :tag "Color without pulsing" nil)
         (sexp  :tag "Color with pulsing"    t))

That lets both `M-x customize-option' and `customize-set-variable'
DTRT.  They both let you choose one of the same three "values" -
the :tags, actually.  `customize-set-variable' lets you use
completion to do that.  If you choose `Color with pulsing' then
you are prompted for a sexp that will be the value.

But hey!  That's still not good enough.  No doubt the sexp here
should not be either `nil' or `never'.  To guard against that,
the :type should use `restricted-sexp' with an appropriate
predicate, instead of just `sexp'.  You can see that things can
get complicated if the logic and use of an optin is complicated.

Whether that kind of treatment is really needed here, or whether
the last `choice' possibility could (and should) be just
(const :tag "Color with pulsing" t), would depend on what the
intention is, and thus what the code does with it.

> In this case, the ability to set an "illegal" value is actually
> useful, because the :type is wrong, 

Yes.  (Or so it seems - something is wrong, at least.)

> as legal values are t, nil or 'never (according to the
> documentation) not just 'boolean.

Yes.

> Why has this never been discovered? I would suggest two
> possibilities: a) the developers have never, ever set
> 'pulse-flag or b) they just used setq in their .emacs.

See above.  Even if they use only setq, the code and doc do
not match.  The likely answer in this case (based on a quick
check of how the variable is used) is that the developers were
either lazy wrt :type or ignorant wrt :type or did not really
care.

> If the latter is true, having a way of only setting legal
> values according to customize would have been helpful,
> because this would have crashed, and they would have fixed it.

See above.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]