`Setq-local` ne yapar ve ne zaman kullanmalıyım?


16

SX'de tüm dokümanı ve bir sürü mesajı okuduktan sonra bile, arabellek-yerel değişkenlerin tüm varyasyonları hakkında net değilim.

İşte anlayışlarımın bir özeti:

(defvar foo ..)dosya için dinamik bir değişken bildirir. Ancak, değişken (1) bir defvar ifade içermedikçe diğer dosyalar tarafından bilinmemektedir ve (2) değişken, yerel olarak tampon değil, kapsam olarak globaldir.

(make-variable-buffer-local foo)sonra defvaryukarıda değişken foo ayarlandıktan her yerde tespit edildiğinde tampon-yerel olarak muamele etmek olduğunu derleyici ve herkes söyler. Bu nedenle, bu örüntü her iki ifadeyi dosyaya arka arkaya koyarak arabellek-yerel değişkeni bildirmek için iyi bir stildir.

(defvar xxx ...)                    ;declare xxx with global scope
(make-variable-buffer-local 'xxx)   ;but now make it buffer-local everywhere

Kolaylık sağlamak için, (defvar-local xxx ...)form yukarıdaki iki satır yerine bir satır olarak kullanılabilir:

(defvar-local xxx ...)       ;make xxx buffer local everywhere

Yukarıdaki gibi bildirildikten sonra, xxx değişkeni setq deyimlerindeki diğer değişkenler gibi kullanılabilir.

Sadece bir global dinamik değişken olan bir arabellek-yerel değişkeninin tek bir örneğine sahip olmak istersem, aşağıdaki bildirimleri kullanırdım. Birincisi, global kapsam dinamik değişkenini bildirir ve ikinci deyim, geçerli tamponda bu değişkenin tampon yerel sürümünün yalnızca bir örneğini oluşturur:

(defvar xxx ...)             ;declare xxx with global scope
(make-local-variable 'xxx)   ;make xxx local in this buffer only

Şimdi benim açıklayıcı sorularım için (yukarıdakilerin hepsi, anlayışımın doğru olup olmadığı hakkında örtük sorulardı).

Değişkenlerin değerini ayarlarken setqveya tuşunu kullanabilirim setq-local. Ne zaman setq-localkullanılmalı? Neden?

setq-localBuffer-local değişkenlerinde veya buffer-local değişkenlerinde kullanırsam ne olur ?

Is setq-locala için gerekli defvar-localbildirilen değişkenin?

Will setq-localnormal üzerinde defvarbildirilen değişkenin bir tampon-yerel değişkene çevirmek? (Başka bir deyişle, bir setq-localşekilde bir (make-variable-local xxx)deklarasyona eşdeğer mi?


Fazladan emek için teşekkürler Scott. Buradan fazladan backquotes koyacağım.
Kevin

2
(setq-local VAR VALUE)sadece kısayoldur (set (make-local-variable VAR) VALUE), ki bu ortak bir deyimdi (ve hala da).
Drew

Yanıtlar:


18

Varsayımlarınızın çoğu yakın. Birkaç sonra bahsedeceğim. Ama önce ana soru.

Form setq-localyapıyor aynıdır, yalnızca bir kolaylık make-local-variableizledi setq. C-h f setq-localBelgeleri görmek için bir yapmış ve kaynağa tıklamışsanız, bunu görmüş olabilirsiniz. İlk izlenimimi böyle doğruladım. Yine de kod biraz belirsizdir, çünkü make-local-variabledeğişkenin kendisini döndüren gerçek gibi şeyleri optimize eder. Kullanmak setq-local, bazı kodlardaki yerelliği göstermenin bir yoludur, böylece diğerleri kodun değişkenin global değeri ile oynatılamayacağını bilir. Sen do not yerel değişkenlere erişmek için kullanmak gerekir. Herhangi bir değişken buffer-local olarak yapılabilir ve bu, değişkene dokunan tüm kodu etkileyecektir (global kopyayı setq-defaultveya benzeri ile elde etmek için kendi yolundan çıkması dışında ).

Bu birincil cevaptır. Şimdi, arka planınızda biraz kapalı olan birkaç şey var. Siz bunu sorduğunuzdan, bazı şeylere değineceğim.

Birincisi "diğer dosyalar tarafından bilinmiyor". Bu gerçekten doğru değil. Herhangi bir kod, herhangi bir global değişkene başvurabilir (bu yüzden "global" olarak adlandırılır) ve defvar(ve böyle C-h f defvarsöylemez). Aslında, her global değişken için sadece bir ana defvar(doktrin ve varsayılan değerle) olmalıdır. defvarBayt derleyici uyarısını bastırmak için yalnızca değişken adlı bir A kullanılabilir. Emacs sadece ilk gördüğü değerden¹ ve sonuncusundan gelen öğretiyi kullanır. defvarDeğer / docstring ile birden fazla s varsa , kodu okuyan insanlar için kafa karıştırıcı olabilir. Ve dosya yükleme sırası önemli olacaktır.

Bazı değişkenlerin yalnızca tampon-yerel olarak kullanılması amaçlanmıştır ve bunlar değişkenlerdir defvar-local(veya kısa kısmı eklenmeden önce daha eski kodda olmak üzere kısa olan iki kısmı defvar/ make-variable-buffer-local). Bu, tüm tamponlarda tampon-yerel olmasını sağlar. Bazı değişkenler için birincil kullanımları arabellek-yerel değildir, ancak bir nedenden ötürü bir arabellek farklı bir değere sahip olabilir. Bu make-local-variable, genellikle bazı arabellek kurulum kodunda neredeyse hiçbir zaman hemen sonra kullandığınız zaman defvar.

Ve genel bir şey olarak, defvarformların iki amacı vardır . Bunlardan biri, C-h vdeğişkenlerin ne için olduğunu bilmek için başkaları tarafından kullanılabilecek bazı belgelere sahip olmaktır. İkincisi, değişkenin her zaman ayarlanması için bir "varsayılan" değer bildirmektir. Varsayılan değerin bildirimi yalnızca bir değişkenin genel (veya varsayılan) örneğini etkiler ve yalnızca bu örnek zaten bir şeye ayarlanmamışsa kullanılır. Bu, eğer setqbir değişkene sahipseniz ve sonra dosyayı defvar(örneğin a yoluyla require) eklerseniz, defvar değeri değiştirmez.

¹ Daha doğrusu, defvarönceden ayarlanmışsa değişkenin değerini değiştirmez (ancak docstring'i ayarlar); bu, kullanıcının init dosyasının (setq some-variable)bir paket yüklenmeden önce paketin varsayılan değerini geçersiz kılmak için yapabileceği anlamına gelir .


1
Çok net cevap için teşekkürler, çok yardımcı olur. "Diğer dosyalar tarafından bilinmeyen" ifadesini kullandığımda, ben de onlara bir defvar eklemedikçe, bu diğer dosyalar değişken ücretsiz olduğunu düşünüyorum çünkü ücretsiz değişken uyarıları düşünüyordum. set-localOkuyuculara yerel bir değişkenin ayarlandığını söyleyen ifadenizi beğendim . Kodumun okunabilirliğini artırmak için yapabileceğim her şey iyi! PS. Kaynağa daha sık tıklamaya çalışacağım; şu anki gelişim düzeyimde, genellikle anlambilimde olmuyor ... :-)
Kevin

1
" defvarHer bir global değişken için sadece bir tane olmalıdır " kesinlikle doğru değildir - söz konusu VARNAME ürününün doğru tanımından (başlangıç ​​değeri ve ideal olarak bir öğretiyle) bağımsız olarak bir değer (defvar VARNAME) olmadan bildirilmesi gereken durumlar vardır .
phils

2
Ayrıca şunu da unutmayın setq-localve defvar-localyalnızca Emacs 24.3'te tanıtıldı.
phils

1
@phils, bahsettiğiniz durumları tanımlayabilir misiniz, değer olmadan nerede (defvar varname)beyan edilmelidir ? Ben başka bir yerde ilan küreseller için dosyalarımda ücretsiz değişken uyarıları kurtulmak için sorurken Drew başka bir iş parçacığında önerdiğini düşünüyorum. Bunu şimdi yapıyorum. Bahsettiğiniz durum bu mu?
Kevin

1
Bayt derleme uyarılarından kaçınmak bir nedendir, evet (bkz. C-h i g (elisp) Warning Tips). Diğeri, değişkenin sözlüksel olarak bağlı olmaktan ziyade dinamik olarak bağlı olmasını sağlamak için (gerekirse) sözcük bağlamayı kullanan kütüphaneler içindir.
phils
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.