Subject: bug#16576: Binding `standard-output' to a function doesn't work -- function sometimes called with garbage

From: Anders Lindgren <[email-masked]>
Date: Tue, 28 Jan 2014 20:39:57 +0100

Hi!

I got the same result with your version. After running it 24 times, I got
the following output (on Emacs 22) -- please note the extra text and
control characters towards the end of the string (which I have changed to
the \xNN syntax, in order not to confuse the mail program).

\xdc\xac\\\"(\\\\\\\\(co\\\\\\\\(?:mbine-after-change-calls\\\\\\\\|n\""

When it comes to the original program, I believe that it's correct. The
function bound to `standard-output' is called from within `prin1', which is
called from inside the scope of `let'. Hence, it will work on the local
version of the variable. (If it wouldn't have been correct -- why would it
return the correct value *most* of the time?)

    -- Anders

On Tue, Jan 28, 2014 at 4:59 PM, Eli Zaretskii <[email-masked]> wrote:

> > Date: Tue, 28 Jan 2014 10:09:08 +0100
> > From: Anders Lindgren <[email-masked]>
> >
> >     emacs -Q
> >     Eval the following:
> >
> > (defvar bug-bind-output-str nil)
> >
> > (defun bug-bind-output-function (char)
> >   (setq bug-bind-output-str
> >         (concat bug-bind-output-str (list char))))
> >
> > (defun bug-bind-output-test ()
> >   (interactive)
> >   (let ((bug-bind-output-str "")
> >         (standard-output 'bug-bind-output-function)
> >         (s
> >
> >         s0)
> >     (prin1 s)
> >     bug-bind-output-str))
> >
> > Type this a number of times:
> >
> >     M-x (bug-bind-output-test) RET
>
> I think there's a bug in your test program.  You let-bind
> bug-bind-output-str, and print that local binding after you call
> prin1.  But your print function concatenates each character onto the
> _global_ binding of bug-bind-output-str, so the result is not in your
> local binding, it's in the global one.
>
> If you change your program like this:
>
>   (defun bug-bind-output-test ()
>     (interactive)
>     (setq bug-bind-output-str "")
>     (let ((standard-output 'bug-bind-output-function)
>           (s
>
>           s0)
>       (prin1 s)
>       bug-bind-output-str))
>
> i.e., work with the global binding, then the program works as
> expected, AFAICS.
>