Search code examples
elisp

Emacs lisp. One function to has no access to variables in another function


Code in emacs lisp:

 

(defun test-sub-fun-var() (message "SUB test-sub-fun-var: my-local-var: %s" my-local-var) )

(defun test-main() (message "\nSTART test-main") (let ( (my-local-var) ) (setq my-local-var "MY LOCAL VARIABLE VALUE") (message "MAIN my-local-var: %s" my-local-var) (test-sub-fun-var) ) (message "FINISH test-main") )

(test-main)

When run function "test-main" we have result:

START test-main

MAIN my-local-var: MY LOCAL VARIABLE VALUE

SUB test-sub-fun-var: my-local-var: MY LOCAL VARIABLE VALUE

FINISH test-main

As you can see, the function "test-sub-fun-var" has access to variable "my-local-var" that declare in function "test-main". But I need function "test-sub-fun-var" to has NO access to variable "my-local-var". How I can do this? Thanks.


Solution

  • You don't say what version of Emacs you're using. Before 24.1 there wasn't really a way to do what you want, you just had to be careful. But, quoting from the latest version of the Info manual (26.0.50.1):

    11.9.3 Lexical Binding

    Lexical binding was introduced to Emacs, as an optional feature, in version 24.1. [...] A lexically-bound variable has “lexical scope”, meaning that any reference to the variable must be located textually within the binding construct.

    You enable lexical binding on a per-file basis, with the file-local variable lexical-binding. So,

    ;; -*- lexical-binding:t -*-
    
    (defun test-sub-fun-var()
      (message "SUB test-sub-fun-var: my-local-var: %s" my-local-var))
    (defun test-main()
       (message "\nSTART test-main")
       (let ((my-local-var))
           (setq my-local-var "MY LOCAL VARIABLE VALUE")
           (message "MAIN my-local-var: %s" my-local-var)
           (test-sub-fun-var))
       (message "FINISH test-main"))
    
    (test-main)
    

    Now your output is:

    START test-main
    MAIN my-local-var: MY LOCAL VARIABLE VALUE
    test-sub-fun-var: Symbol’s value as variable is void: my-local-var