可以查询 clojure 多方法的调度值吗?
Can the dispatch values of a clojure multimethod be queried?
我正在编写一些如下所示的代码:
(def
authorized-access-levels
{:sales-rep-manager (fn [{{user :user} :session}]
)
:regional-sales-manager (fn [{{user :user} :session}]
)
:vp-of-sales (fn [{{user :user} :session}]
)
})
稍后在代码中:
(defn
get-my-housing
[{{user :user} :session :as request}]
(let [data-fn (authorized-access-levels (user :access-level))]
(data-fn request)))
从表面上看,这似乎是多方法的一个很好的用例,其中 defmulti
看起来像这样:
(defmulti get-my-housing (fn [{{{access-level :access-level} :user} :session}] access-level))
(defmethod get-my-housing :vp-of-sales [{{user :user} :session}]
)
但我还有一个需求是这样的:
:auth-fn (fn [user] (contains? authorized-access-levels (user :access-level)))
所以(长话短说)我需要密钥来确定用户是否有权获取数据,然后我使用密钥通过映射分派给函数。
我可以查询一个多方法来查看它的调度值吗?如果是这样,那么我可以把它写成一个多方法,然后查询它以获得授权。还有其他想法吗?
我不确定我是否理解正确,但让我试试。您有三个不同的概念,我们希望将其建模为三个不同的功能:获取用户访问级别,从访问级别获取用户授权,最后获取住房。我会这样建模:
(defn get-access-level [user]
(:access-level user))
(defn authorized? [user]
(contains? authorized-access-levels (get-access-level user)))
(defmulti get-my-housing (fn [req]
(get-access-level (get-in req [:session :user]))
(defmethod get-my-housing :vp-of-sales
[req]
((:vp-of-sales authorized-access-levels) req))
如果每个 defmethod
都有不同的行为,这是值得的。如果他们都使用不同的密钥访问同一个地图,那么额外的间接访问可能不值得。
Can I query a multimethod to see what it's dispatch values are?
是的,您可以使用 methods
函数对多方法进行内省以获取多方法的分派 table,并使用 get-method
查找给定方法调度值。
user=> (defmulti authorized? :access-level)
user=> (defmethod authorized? :admin [_] true)
user=> (defmethod authorized? :user [_] false)
user=> (keys (methods authorized?))
(:user :admin)
user=> ((get-method authorized? :admin) {:access-level :admin})
true
我正在编写一些如下所示的代码:
(def
authorized-access-levels
{:sales-rep-manager (fn [{{user :user} :session}]
)
:regional-sales-manager (fn [{{user :user} :session}]
)
:vp-of-sales (fn [{{user :user} :session}]
)
})
稍后在代码中:
(defn
get-my-housing
[{{user :user} :session :as request}]
(let [data-fn (authorized-access-levels (user :access-level))]
(data-fn request)))
从表面上看,这似乎是多方法的一个很好的用例,其中 defmulti
看起来像这样:
(defmulti get-my-housing (fn [{{{access-level :access-level} :user} :session}] access-level))
(defmethod get-my-housing :vp-of-sales [{{user :user} :session}]
)
但我还有一个需求是这样的:
:auth-fn (fn [user] (contains? authorized-access-levels (user :access-level)))
所以(长话短说)我需要密钥来确定用户是否有权获取数据,然后我使用密钥通过映射分派给函数。
我可以查询一个多方法来查看它的调度值吗?如果是这样,那么我可以把它写成一个多方法,然后查询它以获得授权。还有其他想法吗?
我不确定我是否理解正确,但让我试试。您有三个不同的概念,我们希望将其建模为三个不同的功能:获取用户访问级别,从访问级别获取用户授权,最后获取住房。我会这样建模:
(defn get-access-level [user]
(:access-level user))
(defn authorized? [user]
(contains? authorized-access-levels (get-access-level user)))
(defmulti get-my-housing (fn [req]
(get-access-level (get-in req [:session :user]))
(defmethod get-my-housing :vp-of-sales
[req]
((:vp-of-sales authorized-access-levels) req))
如果每个 defmethod
都有不同的行为,这是值得的。如果他们都使用不同的密钥访问同一个地图,那么额外的间接访问可能不值得。
Can I query a multimethod to see what it's dispatch values are?
是的,您可以使用 methods
函数对多方法进行内省以获取多方法的分派 table,并使用 get-method
查找给定方法调度值。
user=> (defmulti authorized? :access-level)
user=> (defmethod authorized? :admin [_] true)
user=> (defmethod authorized? :user [_] false)
user=> (keys (methods authorized?))
(:user :admin)
user=> ((get-method authorized? :admin) {:access-level :admin})
true