2012-01-25 26 views
7

Tôi chỉ dành tuổi để tìm ra những gì sai với mã của tôi. Nó hoạt động tốt trong các bài kiểm tra đơn vị ert, nhưng thất bại khi tôi chạy nó trong một ngữ cảnh lớn hơn. Dưới đây là ví dụ về mã đã hoạt động:Tại sao mã trong bộ đệm-temp phàn nàn về biến void khi bộ đệm "cha" có một biến cục bộ cùng tên mà tôi đã ràng buộc?

(defun func (my-var) 
    (with-temp-buffer 
    (message my-var))) 

(func "z") 

Bản in z như mong đợi. Bây giờ tôi đã viết một chế độ chính có một số biến vùng đệm. Một trong số đó là của tôi-var. Mã này chứng minh sự cố của tôi:

(make-local-variable 'my-var) 
(setq my-var "y") 

(defun func (my-var) 
    (with-temp-buffer 
    (message my-var))) 

(func "z") 

Kết quả? Không có thông báo lỗi nào: chỉ có thông báo lỗi này:

eval-buffer: Symbol's value as variable is void: my-var 

Trong ví dụ này, dễ thấy rằng biến cục bộ đệm cản trở bằng cách nào đó bị ràng buộc động-var của tôi. Nó không phải là dễ dàng như vậy khi tôi đã có nhiều màn hình giá trị của mã mặc dù :-)

Vì vậy, câu hỏi của tôi là những gì đang thực sự xảy ra ở đây? Rõ ràng là bộ đệm tạm thời bằng cách nào đó thừa hưởng một biến từ bộ đệm "cha mẹ", nhưng tại sao nó lại có một giá trị void? Tôi sẽ hiểu nếu nó sẽ nhận được giá trị "y" bằng cách nào đó, nhưng hành vi này cảm thấy giống như một lỗi cho tôi.

PS. Tôi đang chạy Aquamacs mới nhất

Trả lời

3

Một vài điều.

Trước tiên, mã của bạn không hoạt động đúng. Bạn nên thử điều này trong một cuộc gọi mới của Emacs. Một khi bạn làm, bạn sẽ thấy rằng bạn cần phải vượt qua make-local-variable một biểu tượng, như vậy:

(make-local-variable 'my-var) 

Lưu ý `` `.

Thứ hai, bạn đã xác định biến bộ đệm cục bộ để có cùng tên với tham số là func, vì vậy, bất kỳ câu trả lời nào cần phân biệt giữa hai biến.

Vì vậy, đây là dọn dẹp phiên bản của tôi ví dụ của bạn:

(make-local-variable 'my-var) 
(setq my-var "y") 

(defun func (my-param) 
    (with-temp-buffer 
(message my-param))) 

(func "z") 

Và điều này chỉ hoạt động tốt.

Điều này khiến tôi tin rằng lỗi bạn đang gặp phải là từ cuộc gọi đến make-local-variable mà không có báo giá trước my-var.

Original câu trả lời cung cấp dưới đây, mặc dù nó không giải quyết vấn đề:


Kiểm tra các tài liệu cho make-local-variable. Chuỗi tài liệu là:

biến cục bộ là hàm tích hợp tương tác trong mã nguồn `C '.

(biến cục bộ VARIABLE)

Biến VARIABLE có giá trị riêng biệt trong bộ đệm hiện tại. Các bộ đệm khác sẽ tiếp tục chia sẻ giá trị mặc định chung.(Giá trị bộ đệm vùng đệm cục bộ của VARIABLE bắt đầu bằng giá trị tương tự VARIABLE trước đó đã có. Nếu VARIABLE bị vô hiệu, giá trị đó sẽ bị vô hiệu.) Trả lại VARIABLE.

Phần quan trọng đối với bạn là câu cuối cùng. If the variable was void, it remains void.

Điều này có nghĩa là nếu nó chưa được xác định trên toàn cầu, nó vẫn chưa được xác định trên toàn cầu. Nói cách khác, nó chỉ có một ràng buộc trong các bộ đệm trong đó nó đã được thiết lập rõ ràng.

Nếu bạn muốn nó có một giá trị toàn cầu, sử dụng setq-default như vậy:

(setq-default my-var "some-default-value") 
+0

Nhưng tôi vẫn không hiểu tại sao nó có hiệu lực. Tôi tạo nó với: (make-local-variable my-var) và sau đó tôi đặt giá trị "y" cho nó: (setq my-var "y"). Vì vậy, do thời gian tôi gọi hàm và macro-temp-buffer trong giá trị sẽ không bị vô hiệu. Tôi đang thiếu gì? – auramo

+0

"Nói cách khác, nó chỉ có một ràng buộc trong bộ đệm trong đó nó đã được thiết lập rõ ràng." <- Tôi đã không đặt nó một cách rõ ràng trong bộ đệm tạm thời được tạo ra trong macro với-temp-buffer. Bộ đệm bằng cách nào đó kế thừa biến nhưng không phải là giá trị của nó. Ngoài ra, tôi không muốn tạo ra một biến toàn cầu nếu tôi có thể tránh được điều đó. Tôi có thể sống với tính năng này tốt, tôi chỉ cần nhớ đặt tên cho các biến một cách cẩn thận. Tôi chỉ muốn biết tại sao điều này xảy ra. – auramo

+0

Trên thực tế, có một vài điều đang xảy ra ở đây trong mã của bạn, tôi sẽ cập nhật câu trả lời của mình. –

Các vấn đề liên quan