在过去,请在2024 Clojure状态调查!中分享您的想法。

欢迎!请参阅关于页面获取更多关于如何使用本站的信息。

0
core.memoize by

用例:我有这段代码,它运行得很好

(require '[clojure.core.cache :as cache])
(require '[clojure.core.memoize :as memo])
(import 'clojure.core.memoize.PluggableMemoization)

(defn lru-ttl-cache [base threshold ttl]
  (-> base
      (cache/lru-cache-factory :threshold threshold)
      (cache/ttl-cache-factory :ttl ttl)))

(defn lru-ttl-memo
  ([f base threshold ttl]
   (memo/build-memoizer
      #(PluggableMemoization. %1 (lru-ttl-cache %4 %2 %3))
      f
      threshold
      ttl
      (@#'memo/derefable-seed base))))

但它依赖于私有变量。这实际上应该是公共的,以便客户更容易提供他们自己的实现。

顺便说一句,出色的库。我喜欢在Clojure生态系统中工作。

1 答案

+1
by
编辑 by
 
最佳答案

创建JIRA问题:}https://clojure.atlassian.net/browse/CMEMOIZE-28

可能有一种更好的方式来提供此类扩展,因为缓存元素是可取消引用的事实意味着它是实现细节。

by
这可能是个不错的想法。我写了一个辅助函数来抽象掉这些细节

   (defn build-helper [cache-factory f base & args]
     (build-memoizer
      #(PluggableMemoization. %1 (apply cache-factory %2 %3))
      f
      (derefable-seed base)
      args))

备忘实现因此变为(不含文档)

   (defn memo
     ([f] (memo f {}))
     ([f seed]
       (build-helper cache/basic-cache-factory f seed)))

我早期实现的lru-ttl-memo函数简化为

   (def lru-ttl-memo
      (partial memo/build-helper lru-ttl-cache))

这无疑极大地增加了简便性,并且与实现细节无关。

差异可参考https://github.com/john-shaffer/core.memoize/commit/669febe3af7f325de43cab82ab7d09469fd148a1

我实在不清楚您通常是怎样运行测试的。我不得不将代码链接到一个leiningen项目中,热修复它,并调用clojure.test/run-tests。
by
贡献项目通常使用Maven运行:mvn test

我维护的所有贡献项目也通常支持CLI/deps.edn,您可以使用以下命令运行这些测试:clojure -A:test:runner

可选提供要使用的Clojure版本别名:clojure -A:test:runner:1.8

目前build-memoizer之所以如此通用,是因为它需要能够支持任意缓存,这些缓存可以有任意顺序的任意参数(因此您的助手将仅适用于某些缓存)。
by
在查看这个过程中,我发现PluggableMemoization的种子函数中存在一个错误 https://clojure.atlassian.net/browse/CMEMOIZE-27
by
clojure.core.memoize的master分支已修复此问题:而不是将derefable-seed公开,我添加了一个新的memoizer函数,它接受一个函数、一个缓存(而不是缓存工厂)和一个可选的种子/基本哈希表。这使得创建自定义缓存的函数更加容易,同时暴露较少的库内部实现。

我将在“不久的将来”发布具有此更新功能的新版本。
谢谢。我现在正在使用https://github.com/john-shaffer/krulak/blob/ba09b5098eff2f614ffe2b98c6ed5c6fb2783dc5/src/krulak.clj#L34
我还创建了几个其他函数,它们访问memoize内部。我基本上需要core.cache接口中的每一项memoize等效项。有没有计划添加到core.memoize中的类似功能?
我不确定你在问什么 -- core.memoize基于一个实现了core.cache协议的可插拔memoization类型,所以所有的相同功能都存在。你能具体说明你感觉需要添加到core.memoize中的内容吗?你觉得需要使用core.memoize的私有部分来扩展和定制memoization,这让我感到不舒服。你可以针对你需要解决的问题的每个部分开始一个新的问题线程。
我想我不清楚如何替换PluggableMemoization。我可以访问:clojure.core.memoize/cache atom,但是cache-id的私有性让我觉得atom的位置可能是一个可能会改变的实现细节。依赖这个atom可以吗,还是有其他东西我没有理解到?
你是指这样的东西吗:[a href="https://github.com/clojure/core.memoize/blob/master/src/test/clojure/clojure/core/memoize_test.clj#L207-L217" rel="nofollow" target="_blank">https://github.com/clojure/core.memoize/blob/master/src/test/clojure/clojure/core/memoize_test.clj#L207-L217 使用 memo-swap!(与snapshot结合以访问当前缓存中的内容)吗?

如果不是,你能用我可以理解的方式解释你试图解决的问题,让我看看你为什么认为API中缺少什么吗?
...