Makrolar için değişken kapsam belirlemesi nasıl belirlenir?


11

İçinde tanımlanmış olan aşağıdaki örnek makroyu ele alalım macro.el.

(defmacro some-macro (&rest body)
  `(let ((some-variable 1))
     ,@body))

Ve aşağıdaki işlevi, almak farklı bir dosyada tanımlanır , function.el.

(defun some-function ()
  (some-macro (do-something)))

function.elBayt ne zaman derlenir, some-variablesözcüksel veya dinamik bağlama altında mı bağlanır?

Bu dosyanın kullanıp kullanmadığına bağlı olduğunu anlıyorum -*- lexical-binding: t; -*-, bu yüzden sorum özellikle aşağıdaki durumlarla ilgili:

  1. Eğer function.elbağlayıcı, ancak kullanımları sözcüksel macro.eldeğildir.
  2. Eğer macro.elbağlayıcı, ancak kullanımları sözcüksel function.eldeğildir.

some-varİçinde küresel (bir defvar ile) ilan edilmişse bir fark yaratır function.elmı? Varsa, özellikle olmadığı durumla ilgileniyorum .


Sanırım Jisang Yoo bunu yoo2080.wordpress.com/2013/08/14/… adresinde biraz ayrıntılı olarak ele aldı
phils

Emin değilim, ama makro genişlemesinin bağlayıcı semantiği genişleme sitesinden miras alır, makro tanımından değil mi? Bu genişleme aslında çağrı sitesinde ikame edildiğinden bu mantıklı olacaktır. Ama: Neden bilmek istiyorsun? Bu detaylara dayanan bir kod yazmak istiyor musunuz ?!
lunaryorn

@lunaryorn makro buna tamamen güvenmez, ancak kullanıldığı dosyanın bağlayıcısına saygı
duymazsa

@Malabarba Makronuzu, hedef arabellekteki bağlamaya dayanmayacak şekilde yazın. Ya da daha iyisi, hiç makro kullanmayın.
lunaryorn

@lunaryorn Çok net değildim. Makro sadece izin verilen bir formdur ve her iki şekilde de ilan edildiği gibi çalışır. Ben sadece bu izin formu genişletilmiş dosyada belirtilen kapsamı izler emin olmak istiyorum. Bu soru bunun otomatik olarak olup olmadığını veya makroda kodlamak gerekiyorsa bulmanın bir parçasıdır.
Malabarba

Yanıtlar:


9

Örneğinizde için etkin olan kapsam belirleme türü (let ((some-variable ..)) ...), makro çağrısının sitesinde etkin olan kapsamdır (yani geçerli olan some-function).

Makro, lexical-bindingdeğişkenin değerini kontrol ederek döndürdüğü kod için ne tür bir kapsam belirleme kullanılacağını bilir .

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.