2012-03-16 25 views
5

Tôi có thắc mắc về truyền tham số trong Tcl liên quan đến đoạn mã sau:Trong TCL, chúng ta có thể truyền tham số theo cách này không?

set name "Ronaldo" 

proc GET_PLAYER_INFO {player_id {player_name "$name"}} { 
    global name 
    puts $player_name 
} 

liên quan đến mã trên, chúng ta có một biến toàn cầu "tên", và trong danh sách tham số của proc GET_PLAYER_INFO, mặc định giá trị của tham số player_name được đặt thành "$ name"? nếu giá trị của tên là "ronaldo", nó đã được báo giá đôi, chúng ta cần phải đặt báo giá tăng gấp đôi trong danh sách các thông số như thế này: player_name "$ name"? và trước khi chúng ta thực hiện lệnh "tên toàn cục", giá trị mặc định của player_name có phải là "Ronaldo" không? là như vậy, tại sao chúng ta cần phải có lệnh "tên toàn cầu" trong proc của chúng ta?

Trả lời

7

Điều đó sẽ không hoạt động khi nó đứng; các $name sẽ không được đánh giá ở tất cả vì vậy mặc định sẽ là những năm ký tự chữ.

Nếu bạn đang ràng buộc giá trị mặc định tại thời điểm bạn tạo ra các thủ tục, bạn muốn làm điều đó như thế này:

proc GET_PLAYER_INFO [list player_id [list player_name $name]] { 
    ... 
} 

Đó là, các đối số proc là những thứ chỉ bình thường bạn có thể xây dựng với Tcl lệnh và thay thế. Đây là một trong những điều tuyệt vời về Tcl.

Tuy nhiên, nếu bạn muốn đánh giá rằng $name tại thời điểm quy trình được gọi, bạn phải làm điều đó khác đi. Nếu bạn đã có một số loại giá trị sẽ không bao giờ được sử dụng cho tên người chơi (ví dụ, chuỗi rỗng) thì nó khá dễ dàng:

proc GET_PLAYER_INFO {player_id {player_name ""}} { 
    if {$player_name eq ""} { 
     set player_name $::name 
    } 
    ... 
} 

Lưu ý rằng tôi đã sử dụng tên biến đủ điều kiện ở đó . Có nhiều cách khác để có được cái tên đó quá (ví dụ, với global, với upvar, với variable ...)

Nơi mọi thứ trở nên khó khăn là khi bạn đã không có một giá trị trọng điểm phù hợp ở tất cả các. Vào thời điểm đó, bạn phải xem có bao nhiêu đối số là thực cung cấp:

proc GET_PLAYER_INFO {player_id {player_name ""}} { 
    if {[llength [info level 0]] == 2} { 
     set player_name $::name 
    } 
    ... 
} 

Lệnh info level 0 trả về đầy đủ danh sách các từ lý luận đến các cuộc gọi thủ tục hiện hành. Điều này bao gồm chính bản thân số GET_PLAYER_INFO và sẽ là danh sách có độ dài 2 hoặc 3 trong cuộc gọi hợp lệ theo định nghĩa ở trên. Khi danh sách có sẵn, kiểm tra độ dài của nó là một bài tập nhỏ trong số llength và so sánh số. (Sử dụng một giá trị trọng điểm là dễ dàng hơn mặc dù, và làm việc tại 99,99% các trường hợp.)

Tùy chọn cuối cùng là sử dụng các tham số hình thức đặc biệt args và thực hiện phân tích cú pháp bằng tay:

proc GET_PLAYER_INFO args { 
    if {[llength $args] < 1 || [llength $args] > 2} { 
     return -code error "wrong # args: should be \"GET_PLAYER_INFO player_id ?player_name?\"" 
    } 
    set player_id [lindex $args 0] 
    if {[llength $args] > 1} { 
     set player_name [lindex $args 1] 
    } else { 
     set player_name $::name 
    } 
    ... 
} 

Như bạn có thể nhìn thấy , cái này khá dài ...