2011-10-10 30 views
9

làm cách nào để biết liệu tên hàm được cung cấp dưới dạng chuỗi có thể gọi được hay không trong ngữ cảnh hiện tại? cái gì đó như:Clojure: xác định xem hàm có tồn tại

(callable? "asdasd") ;; false 
(callable? "filter") ;; true 

nhờ

+0

Cũng lưu ý từ "có thể gọi" đang bị quá tải tại đây. Tất cả các hàm Clojure là java.util.concurrent.Callables. –

Trả lời

17

Bạn đang tìm kiếm quyết,

(resolve (symbol "asd")) 

lợi nhuận bằng không

(resolve (symbol "filter")) 

return # 'clojure.core/filter

Để kiểm tra xem var có phải là hàm hay không (tín dụng chuyển đến @amalloy):

(-> s symbol resolve deref ifn?) 
+1

nó trả về những gì bạn nói, nhưng làm thế nào tôi có thể xác định xem nó có thể gọi được hay không? – pistacchio

+0

Bạn có thể gọi (fn? (Giải quyết (biểu tượng "bộ lọc"))) - Tôi muốn đề nghị điều này qua câu trả lời của tôi –

+0

@JoostDiepenmaat: trong trường hợp này '(fn? (Eval (symbol" filter ")))' - ' giải quyết' trả về lớp hoặc var, không phải cái gì với giao diện 'Fn' (xem câu trả lời của tôi) và do đó sẽ không hoạt động. – ffriend

-1
(defn callable? [name]  
    (clojure.test/function? (symbol name))) 

UPD. Tôi phát hiện ra rằng fn? chỉ kiểm tra giao diện Fn và không hoạt động đối với biểu tượng được giải quyết. Mặc dù, clojure.test/function? thực hiện những gì cần thiết, vì vậy tôi đã cập nhật một ví dụ.

1

rất có thể là nếu bạn cần điều này, bạn đang làm điều gì đó sai, nhưng ...

(defn callable? 
    [s] 
    (let [obj (try (eval (symbol s)) (catch Exception e))] 
    (and obj (fn? obj)))) 
+4

Augh no. Sử dụng 'giải quyết' là một dấu hiệu bạn có thể làm điều gì sai; sử dụng 'eval' để thực hiện nhiệm vụ tương tự là một dấu hiệu chắc chắn bạn đang làm điều gì sai. – amalloy

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