2010-07-16 6 views
7

Tôi muốn có thể kiểm tra xem một biến được xác định, trước khi truy cập nó.Làm cách nào để kiểm tra xem biến có được xác định trước khi tham chiếu không?

Tôi muốn có toàn cầu chỉ định "mức gỡ lỗi". Nếu mức độ gỡ lỗi là 0, không có đầu ra thêm nào được đưa ra. Khi lớn hơn 1, đầu ra gỡ lỗi được đưa ra, với độ dài hơn ở số lớn hơn.

Tôi cũng muốn thiết lập nó để các quy trình sẽ chạy và giả định mức 0, nếu tôi không nhận được để xác định nó. Một cái gì đó như:?.. (Nơi defined? là sự kỳ diệu tôi không biết làm thế nào để làm

(if (and (defined? debug-level) (> debug-level 1)) 
    (diplay "Some debugging info")) 

Tôi đã nhìn qua bản tóm tắt các hình thức trong The Scheme Programming Language, 4th Edition Là người duy nhất mà tôi thấy như một khả năng là identifier? Nó đã làm . không hoạt động

tôi đang sử dụng SISC 1.16.6 (tuyên bố R5RS tuân thủ) và Chez Petite Scheme v8 (tuyên bố R6RS tuân thủ)

EDIT tôi đã cố gắng gói eval với một guard như:

(guard (x (else #f)) (eval 'debug-level)) 

Vì số 'debug-level được trích dẫn, nó có thể được đánh giá và chuyển đến eval. Sau đó, khi eval cố gắng để đánh giá nó, một lỗi sẽ xảy ra, mà tôi hy vọng guard sẽ bắt. Nó không.

EDIT 2 tôi nhận ra rằng tôi muốn quấn debug truy tìm thành một thủ tục riêng biệt và rằng tập tin định nghĩa rằng thủ tục cũng có thể xác định debug-level với một mặc định là 0. Mục đích sử dụng một thủ tục riêng biệt là để giảm số lượng các dòng trong các quy trình làm việc và cũng cho phép chuyển hướng đầu ra gỡ lỗi nếu cần.

Trả lời

4

Điều này hoàn toàn phụ thuộc vào việc triển khai để cung cấp, và có vẻ như hầu hết các triển khai không thỏa đáng cung cấp nó.

Trong chương trình SISC, có vẻ như bạn có thể sử dụng GETPROP đến hiệu ứng này, nhưng môi trường không cập nhật tự động oh, nhìn, có điều này được gọi là TƯƠNG TÁC-MÔI TRƯỜNG mà bạn có thể sử dụng:

 
#;> (getprop 'cons (interaction-environment)) 
#<native procedure cons> 
#;> (getprop 'x (interaction-environment)) 
#f 
#;> (define x 100) 
#;> (getprop 'x (interaction-environment)) 
100 

Nhưng nó chỉ hoạt động ở cấp cao nhất.

 
#;> (define (foo y) 
    (let ((e (interaction-environment))) 
    (display "Is X bound? ") (display (getprop 'x e)) 
    (newline) 
    (display "Is Y bound? ") (display (getprop 'y e)) 
    (newline))) 
#;> (foo 1) 
#;> Is X bound? 100 
Is Y bound? #f 

Đối với Chez, bạn có TOP-LEVEL-BOUND? và TƯƠNG TÁC-MÔI TRƯỜNG một lần nữa.

+0

Cảm ơn bạn. Tôi sợ câu trả lời sẽ không được di chuyển rộng rãi, rằng nó sẽ là một cái gì đó mới trong R6RS hoặc thực hiện cụ thể. 1, nhưng tôi sẽ để tuổi này trả lời một chút, để xem liệu có ý tưởng nào tốt hơn được đăng trước khi chấp nhận là đúng hay không. –

1

Để sao lưu một chút, vấn đề với một chức năng defined? là nếu bạn viết

(defined? debug-level) 

Đề án sẽ cố gắng để đánh giá debug-level, trong đó tất nhiên là một lỗi vì nó không được xác định. Một dạng như vậy sẽ phải được trình biên dịch/phiên dịch thực hiện trong nội bộ như một trường hợp đặc biệt.

Biểu mẫu đặc biệt như vậy không phải là một phần của tiêu chuẩn R5RS (trừ khi tôi bỏ lỡ, vui lòng double-check). Vì vậy, đối với các chương trình R5RS, bạn không may mắn trừ khi bạn tìm thấy một Đề án thực hiện điều này như là một phần mở rộng không chuẩn.

+0

Tôi đã không yêu cầu một hàm 'được định nghĩa? 'bởi vì, như bạn nói, một hàm sẽ không hoạt động. Nhưng một hàm sẽ không hoạt động đối với 'if' hoặc là, nhưng sơ đồ có' if'. Trong các workds khác, tìm kiếm một hình thức đặc biệt, hoặc cách khác để đạt được kết quả. (Macro có thể?) –

+1

Chắc chắn. Những gì tôi đã cố gắng để nói là đây sẽ là một trong những hình thức được xây dựng trong ngôn ngữ cung cấp, chẳng hạn như 'if', và spec (R5RS ít nhất) dường như không bao gồm một. –

2

giải pháp Clunky nhưng khả thi cho R5RS. Sử dụng khả năng bỏ qua/quên lãng thường xuyên của cú pháp để xác định lại từ khóa. điều này là clunky bởi vì toàn bộ tập tin của bạn được bao bọc trong một cú pháp cho phép và bởi vì nó thêm một số chi phí cho mỗi định nghĩa. Tôi sử dụng một danh sách liên kết để ghi nhớ các định nghĩa, một bảng băm sẽ là một lựa chọn beter.

(define define-list '()) 
(define define-list-add 
    (lambda (key value) 
    (set! define-list (cons `(,key ,value) define-list)))) 

(let-syntax (
      (define (syntax-rules() 
         ((_ (pro-name args ...) body ...) 
         (begin 
          (define (pro-name args ...) body ...) 
          (define-list-add pro-name '((pro-name args ...) body ...)))) 
         ((_ pro-name pro) (begin 
              (define pro-name pro) 
              (define-list-add 'pro-name 'pro))) 

         )) 
      (defined? 
       (syntax-rules() 
       ((_ sym) (begin (if (assoc (quote sym) define-list) #t #f))))) 
      ) 
    (define y (lambda() x)) 

    (display (defined? y)) 
    (newline) 
    (display (defined? x)) 
) 

in

#t 
#f 

Dưới đây trong vợt: một module được sử dụng để xác định lại xác định để lưu trữ mỗi ký hiệu và định nghĩa trong một danh sách gọi là xác định danh sách. Macro được xác định? tìm trong danh sách này để xem thời tiết hay không biểu tượng đã được xác định.

(module qdefine mzscheme 
    (provide ;(all-from-except mzscheme let) 
    (rename define olddefine) 
    (rename quote-define define) 
    defined?) 

    (define define-list '()) 
    (define define-list-add 
    (lambda (key value) 
     (set! define-list (cons `(,key ,value) define-list)))) 

    (define-syntax quote-define 
    (syntax-rules() 
     ((_ (pro-name args ...) body ...) 
     (begin 
     (define (pro-name args ...) body ...) 
     (define-list-add pro-name '((pro-name args ...) body ...)))) 
     ((_ pro-name pro) (begin 
          (define pro-name pro) 
          (define-list-add 'pro-name 'pro))) 

    )) 

    (define-syntax defined? 
    (syntax-rules() 
     ((_ sym) (begin (if (assoc (quote sym) define-list) #t #f))))) 
) 
(require 'qdefine) 

(define y (lambda() x)) 

(defined? y) 
(defined? x) 

Trong guile nó chỉ được xác định? rõ ràng: http://www.delorie.com/gnu/docs/guile/guile_289.html

+1

Racket không có công cụ phản chiếu để làm một cái gì đó như thế này, nhưng những thứ như vậy (bao gồm cả 'môi trường tương tác', bất cứ điều gì Guile làm, vv) luôn là các giải pháp run rẩy, bị cách này hay cách khác. –

+0

+1 cho giải pháp di động. –