это может быть возможно, если вы выставите еще одну функцию, скажем :update
, включающую значение inum
.
(def inc-map (let [inum (atom 0)]
{:update (fn [f & args] (apply swap! inum f args))
:countup (fn [] (swap! inum inc))
:get (fn [] @inum)}))
user> (def inc-dec-map (assoc inc-map :countdown
(fn [] ((inc-map :update) dec))))
#'user/inc-dec-map
user> ((inc-dec-map :countup))
;;=> 1
user> ((inc-dec-map :countup))
;;=> 2
user> ((inc-dec-map :countdown))
;;=> 1
user> ((inc-dec-map :countdown))
;;=> 0
user> ((inc-dec-map :countdown))
;;=> -1
, а затем вы можете просто запечатать ее, disso c 'ing :update
, (скажем, если вы сделаете его общедоступным для какого-то другого пространства имен.
в противном случае вы можете предоставить средство получения / обновления объекта ops:
(def counter-ops (let [inum (atom 0)
ops (atom {:countup (fn [] (swap! inum inc))
:get (fn [] @inum)})]
(fn
;; get operations map snapshot
([] @ops)
;; get operation
([op] (-> ops deref op))
;; set operation
([op f & args] (swap! ops assoc op (fn [& args] (apply f inum args)))))))
user> (counter-ops :countdown (fn [inum] (swap! inum dec)))
user> (counter-ops :decrease-by (fn [inum n] (swap! inum - n)))
user> ((counter-ops :countdown))
;;=> -1
user> ((counter-ops :countdown))
;;=> -2
user> ((counter-ops :countup))
;;=> -1
user> ((counter-ops :countup))
;;=> 0
user> ((counter-ops :decrease-by) 10)
;;=> -10
запечатать его для блокировки для любых последующих оп дополнений:
user> (def counter-ops-sealed (counter-ops))
#'user/counter-ops-sealed
user> ((counter-ops-sealed :countup))
;;=> 2
user> ((counter-ops-sealed :countdown))
;;=> 1