Cách tốt nhất để làm nội tâm trong Clojure là gì? Có chức năng nào giống như chức năng dir
của Python không? Tôi đặc biệt quan tâm đến việc tìm kiếm các phương thức có sẵn trên các lớp java mà tôi đang tương tác với, nhưng tôi cũng quan tâm đến việc tìm ra bất kỳ thứ gì có sẵn trong Clojure liên quan đến sự mẫn cảm.Introspection ở Clojure
Trả lời
Nếu bạn muốn khám phá phương pháp, chỉ cần sử dụng đồng bằng Java phản ánh:
user=> (.getDeclaredMethods (.getClass {:a 1}))
#<Method[] [Ljava.lang.reflect.Method;@72b398da>
user=> (pprint *1)
[#<Method private int clojure.lang.PersistentArrayMap.indexOf(java.lang.Object)>,
#<Method public int clojure.lang.PersistentArrayMap.count()>,
#<Method public java.util.Iterator clojure.lang.PersistentArrayMap.iterator()>,
#<Method public boolean clojure.lang.PersistentArrayMap.containsKey(java.lang.Object)>,
#<Method public int clojure.lang.PersistentArrayMap.capacity()>,
#<Method public clojure.lang.IPersistentMap clojure.lang.PersistentArrayMap.empty()>,
...
Bạn cũng có thể viết nó một chút đẹp hơn với một macro luồng:
(-> {:a 1} .getClass .getDeclaredMethods pprint)
hoặc
(-> clojure.lang.PersistentArrayMap .getDeclaredMethods pprint)
(Tôi vừa học được từ #clojure IRC rằng tên của chính lớp đó đã là đối tượng Lớp!)
'(.getDeclaredMethods (class {: a 1}))' cũng hoạt động. – Mars
Nếu bạn đang sử dụng 1,3, có clojure.reflect cho phép bạn kiểm tra, thao tác, v.v. thông tin về các lớp Java. Tôi cũng thích số clojure.contrib.repl-utils/show từ thư mục cũ nếu đó là tùy chọn cho bạn.
Kiểm tra clojure.contrib.repl-utils
và show
nói riêng.
http://richhickey.github.com/clojure-contrib/repl-utils-api.html#clojure.contrib.repl-utils/show
Đây là những tiện ích cho bạn nội quan các đối tượng và các lớp học trong REPL, nhưng mã là một ví dụ tốt về làm thế nào để khai thác lớp programatically.
Michiel Borkent và Dave Ray có các tùy chọn interop được đề cập.
Để khám phá các chức năng Clojure, có một vài tùy chọn trong không gian tên clojure.repl
(có thể đã được nhắc đến REPL của bạn theo mặc định).
dir
:
=> (require 'clojure.set)
nil
=> (dir clojure.set)
difference
index
intersection
join
map-invert
project
rename
rename-keys
select
subset?
superset?
union
apropos
:
=> (apropos #"^re-")
(re-pattern re-matches re-matcher re-groups re-find re-seq)
find-doc
:
=> (find-doC#"^re-")
-------------------------
clojure.core/re-find
([m] [re s])
Returns the next regex match, if any, of string to pattern, using
java.util.regex.Matcher.find(). Uses re-groups to return the
groups.
-------------------------
clojure.core/re-groups
([m])
Returns the groups from the most recent match/find. If there are no
nested groups, returns a string of the entire match. If there are
nested groups, returns a vector of the groups, the first element
being the entire match.
-------------------------
....
Để tìm giao diện được thực hiện bởi một lớp, hãy thử supers
(supers clojure.lang.PersistentHashMap)
clojure.contrib.repl-utils
đã chuyển sang clojure.reflect
.
Bây giờ bạn có thể gọi nó như sau:
(->> (clojure.reflect/reflect java.lang.String)
:members
clojure.pprint/pprint)
lẽ clojure.reflect là giá trị xem xét là tốt. http://clojure.github.io/clojure/clojure.reflect-api.html – claj