Digamos que eu defina uma variável local buffer foo
e seu valor padrão seja "a":
(defvar foo "a")
(make-variable-buffer-local 'foo)
(default-value 'foo) ;; => "a"
Imediatamente após isso, eu executo o seguinte código:
(let ((foo "b"))
(with-temp-buffer
(message "foo: %s" foo))) ;; => "b"
O resultado é "b", que é o valor que eu defini let
.
Agora, se eu usar setq
para definir a variável, execute novamente exatamente o mesmo código de antes:
(setq foo "c") ;; => "c"
(let ((foo "b"))
(with-temp-buffer
(message "foo: %s" foo))) ;; => "a"
O resultado é "a", que é o valor padrão agora.
A pergunta : para um buffer temporário, o valor padrão de foo
não é definido até que eu use setq
? E enquanto eu não usar setq
, posso usar let
para alterar o valor padrão em outros buffers?
EDIT : como disse @npostavs, é isso que make-varible-buffer-local
realmente significa. Se eu make-variable-buffer-local
me usar , sempre posso usá-lo setq
depois disso. Mas isso se torna realmente complicado para as variáveis locais do buffer "internas", como case-fold-search
. se eu, como autor do pacote, vincular- case-fold-search
me nil
ao exterior let
e desejar usar o valor padrão (ele pode ou não ser definido pelo usuário) no with-temp-buffer
, tenho que usar setq
antes with-temp-buffer
para garantir que o valor padrão seja realmente sendo usado no caso do usuário não tem que setq
em seu / sua init.el
. Para variáveis locais de buffer, provavelmente significa que setq
é sempre mais seguro do que let
quando queremos definir o valor. Gostaria de saber se o design ou a documentação poderiam ser melhorados.
fonte
with-temp-buffer
(em vez de antes dela), isso ajuda?with-temp-buffer
é uma macro e se comporta um pouco diferente de uma função padrão. Exemplo:(with-temp-buffer (let ((foo "b")) (message "foo: %s" foo)))
with-temp-buffer
(que disse, sem macros). Eu acho que é mais como um comportamento específico para variáveis locais de buffer.Respostas:
Nesse caso, eu recomendaria
O importante a ser observado aqui é que
make-variable-buffer-local
não torna uma variável buffer-local! Ele apenas organiza para que ele se torne local de buffer após ser definido . Você pode usar em seumake-local-variable
lugar.A segunda coisa a se notar é a interação
let
com variáveis locais buffer, de(elisp) Intro to Buffer-Local
:Assim, no primeiro caso, você ligar o valor mundial para
"b"
e que aparece no buffer temporário. No segundo caso, depois de ter definido o valor local em*scratch*
que"c"
, então você vincular o valor local para"b"
, mas outros buffers ainda ver o valor global"a"
.fonte
Make VARIABLE become buffer-local whenever it is set.
. Eu pensei que estava dizendo sempre que definimos o valor, apenas o valor do buffer-local é definido. Então, para evitar esse problema, provavelmente devemos sempre usarsetq
imediatamente depoismake-variable-buffer-local
?case-fold-search
efill-column
. O Emacs em si não os define depois de definir essas variáveis locais de buffer e exige que o usuário as defina para torná-las realmente locais de buffer. Esse design é intencional? Eu não acho que a maioria das pessoas esteja ciente disso.make-local-variable
ousetq
enquanto diz que essa variável é um buffer-local é realmente confuso. Mas talvez essa seja outra pergunta sobre o design.make-local-variable
quando vejo que a variável já é "buffer-local" do manual. Eu esperaria que olet
poderia vincular a cópia do buffer-local. Mas isso pode ser mais adequado para ser solicitado no Emacs-devel.Como sua solução proposta, podemos vincular isso a uma variável arbitrária interna e
let
, em seguida, alterar conforme desejado, permanecendo internalet
, antes de voltar ao valor original.O problema surge ao alterar o buffer interno
let
- devido ao escopo dinâmico, o valor das variáveis locais não será transferido para o novo buffer, mesmo quando internolexical-let
.Aqui está uma função que verifica esse problema e também define e reverte o valor padrão, que é o usado por um buffer temporário:
então
e "xyz" aparecerá no
*Messages*
buffer.Outras variáveis locais que vêm à mente neste contexto são
default-directory
euniquify-managed
...Em resumo, você pode definir uma função como essa e usá-la por dentro
let
, portanto, evite o incômodo de verificar se a variável (símbolo) é local ou não:fonte