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

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

RE: Inspecting functions returning complicated values


From: Drew Adams
Subject: RE: Inspecting functions returning complicated values
Date: Wed, 1 Oct 2014 20:06:42 -0700 (PDT)

> > M-x pp-eval-expression
> 
> What improvement is that?
>      (message "hello")
>      (eval-expression (message "hello"))
>      (pp-eval-expression (message "hello"))
> 
> Here, the first two seem to do the same, namely put it
> in the echo area for inspection and then you can use
> `C-h e'. pp-eval-expression also puts it in *Messages*
> but doesn't echo it what I can see.

Maybe it's because you don't know what you're doing?
Maybe you didn't read the doc for `pp-eval-expression'?
Hard to guess.  Just what are you trying to accomplish?

`pp-eval-expression' is a function.  As such, it evaluates its
argument.  What does the doc string tell us it does with its
argument?

  Evaluate EXPRESSION and pretty-print its value.
  Also add the value to the front of the list in the
  variable `values'.

So let's see what you did.  Somehow, you evaluated the sexp
`(pp-eval-expression (message "hello"))'.  Perhaps you used
`C-x C-e', or maybe `M-:', to do that?

However you did it, that evaluates the sexp `(message "hello")'
and passes the resulting value to function `pp-eval-expression'.
That resulting value is the string "hello".

So what does `pp-eval-expression' then do with its argument,
"hello"?

It evaluates it!  And then it pretty-prints the result of that
evaluation.

"hello" evaluates to "hello".  OK, whatever.  Since the
pretty-printed representation of string "hello" is "hello",
`pp-eval-expression' prints "hello" in the echo area.
End of story...almost.

And then, depending on how you evaluated
`(pp-eval-expression (message "hello"))', you might see the
value of _that_ sexp echoed (in the echo area).  What is that
value?  `nil'.

`pp-eval-expression' is used for its side effect, not its value.

Why do `C-x C-e' and `M-:' print the value of the sexp they
evaluate?  Ask them.  But it is generally handy that they do.

So in the echo area, and in `*Messages*', two things are printed:
a pretty-print of the string "hello", followed by `nil'.

In addition, you have access to the result of evaluating the
argument sexp (the string "hello"), which is "hello", as the car
of global variable `values': `C-h v values' or `M-: (car values)'.

Now what was it that you _wanted_ to do?

Typically, one uses `pp-eval-expression' to (1) evaluate an
expression and then (2) pretty-print the result of evaluation.

Because it wants to evaluate an expression argument, you need
to pass it an expression, and `pp-eval-expression' of course
evaluates its argument first, before the function body executes.
(It is not a macro or a special form.)

So a typical use of `pp-eval-expression' would be something
like `(pp-eval-expression 'ctl-x-map)' or
`(pp-eval-expression '(nth 2 (nth 2 font-lock-keywords)))', and
the result of pretty-printing would look something like this:

(keymap
 #^[nil nil keymap
        #^^[3 0 pop-global-mark nil list-buffers save-buffers-kill-terminal 
list-directory eval-last-sexp find-file nil nil indent-rigidly nil 
kmacro-keymap downcase-region
              (keymap
               (108 . set-language-environment)
               (99 . universal-coding-system-argument)
              ...

or this:

(2
 (let
     ((type
       (get
        (intern-soft
         (match-string 1))
        'lisp-define-type)))
   (cond
    ((eq type 'var)
     font-lock-variable-name-face)
    ((eq type 'type)
     font-lock-type-face)
    (t font-lock-function-name-face)))
 nil t)

The first of these is the same kind of representation you see if
you use `C-h v ctl-x-map'.  Why?  Because... `describe-variable'
uses function `pp', just like `pp-eval-expression' does.

But again, depending on how you evaluate the `pp-eval-expression'
sexp, you might be fooled.  If you evaluate it interactively then
you might be fooled by the _command_ that you use to evaluate it.

Using `M-:' or `C-x C-e' (without a prefix arg) prints the value
of the evaluated `pp-eval-expression' sexp, right after
`pp-eval-expression' prints the value of its argument expression.
The hand is quicker than the eye.

But lo and behold, `pp-eval-expression' is a command!  And that
means you can execute it using `M-x' or bind it to a key.  What
happens then?

M-x pp-eval-expression RET
Eval: (nth 2 (nth 2 font-lock-keywords)) RET

And the pretty-printed value is shown in buffer `*Pp Eval Output*'.
And a message tells you "See buffer *Pp Eval Output*."

(That message should not end in a period, but let's not nitpick.)

But wait, how come we didn't need to quote the expression?
Because interactively `pp-eval-expression' uses `read--expression',
and that, well,...reads an expression.  In this case there is no
need to evaluate something to provide `pp-eval-expression' with
its expression argument.

> But I agree with the other posters, IELM, with (ielm)
> is the best way to do this.

Good to know.  To do what?



reply via email to

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