[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: `save-excursion' defeated by `set-buffer'
From: |
Uday Reddy |
Subject: |
Re: `save-excursion' defeated by `set-buffer' |
Date: |
Fri, 11 Mar 2011 23:06:30 +0000 |
User-agent: |
Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.2.15) Gecko/20110303 Thunderbird/3.1.9 |
On 3/11/2011 8:52 AM, Andreas Röhler wrote:
Maybe let's put the question another way:
is there an example, where save-excursion will fail, ie not restore the
buffer due to a set-buffer afterwards?
That is not the right question to ask, in my opinion. save-excursion
will restore the buffer. But save-current-buffer, which I recommended
right at the outset of this discussion, will also restore the buffer.
So, you should be asking the question, "why am I using save-excursion
instead of save-current-buffer?" After all, if you are changing
buffers, then you want to restore the current-buffer in the end. You
don't need to restore the point and mark.
Despite the obviousness of save-current-buffer/set-buffer pattern, there
is a lot of code out there that uses the save-excursion/set-buffer
pattern. Why that is, I don't know. But, here is the problem that can
arise with this misused pattern. Suppose you are in buffer A and you run:
(save-excursion
(set-buffer B)
(goto-char x)
..... lots of deep function calls, say
(....
(set-buffer A)
(goto-char y)
...))))
Two problems here:
- B's point has moved to x. Is that supposed to be permanent? It is
not clear. The save-excursion may seem to indicate that we want to
preserve its point. But, it is only A's point that is being preserved.
B's point is not.
- A's point is being moved to y deep inside the code. Is that supposed
to be permanent? Again, it is not clear. That movement is being
cancelled by the outer save-excursion. But if the intent is to restore
A's point after the temporary movement to y, shouldn't the
save-excursion be close to the (goto-char y) statement?
If tomorrow, you happen to run this code in buffer C, you will find that
A's point is suddenly moving. (The outer save-excursion will restore
C's point instead of A's point.) If your code is sufficiently
complicated, it will probably take quite some digging to find the problem.
So the right programming style is to use
(save-current-buffer
(set-buffer B)
...)
or
(save-excursion
(goto-char y)
....)
But
(save-excursion
(set-buffer B)
...)
is neither here nor there. Hence, the compiler warning.
Hope this helps.
Cheers,
Uday
PS: By the way, I maintain the mail reader VM, which has tons and tons
of the bad save-excursion/set-buffer pattern. But changing those
save-excursion's to save-current-buffer's is not easy. There could be
unprotected point movements buried deep inside which happen to work
coincidentally because they are buried under a stack of save-excursion
forms. So, it is best to use the right programming style from the
beginning to save unnecessary head aches down the road.
- Re: `save-excursion' defeated by `set-buffer', (continued)
- Re: `save-excursion' defeated by `set-buffer', Stefan Monnier, 2011/03/15
- Re: `save-excursion' defeated by `set-buffer', Jason Earl, 2011/03/15
- RE: `save-excursion' defeated by `set-buffer', Drew Adams, 2011/03/15
- Re: `save-excursion' defeated by `set-buffer', rusi, 2011/03/16
- Re: `save-excursion' defeated by `set-buffer', David Kastrup, 2011/03/16
- Re: `save-excursion' defeated by `set-buffer', rusi, 2011/03/17
- Re: `save-excursion' defeated by `set-buffer', rusi, 2011/03/17
- Re: `save-excursion' defeated by `set-buffer', Antoine Levitt, 2011/03/17
- Message not available
- RE: `save-excursion' defeated by `set-buffer', Uday S Reddy, 2011/03/16
- Message not available
- Re: `save-excursion' defeated by `set-buffer', Tim X, 2011/03/12
- Message not available
- Re: `save-excursion' defeated by `set-buffer',
Uday Reddy <=
Re: `save-excursion' defeated by `set-buffer', David Kastrup, 2011/03/10
Re: `save-excursion' defeated by `set-buffer', rusi, 2011/03/31