2024 年 Clojure 状态调查! 中分享您的想法。

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

0
Clojure

如果你给 partition 传递一个非正数 'n' 或 'step',你会得到一个无限循环。这里有几个例子

(partition 0 (link: 1 2 3))
(partition 1 -1 (link: 1 2 3))

原因: partition 和 partition-all 并没有检查 n 和 step 是否为正数。

方法: 在 partition 和 partition-all 中添加检查以确保 n 和 step 是正数。

补丁: clj-1647_3.patch

预审者: Alex Miller

29 答案

0

评论者:alexmiller

另请参阅 CLJ-764

0

评论者:alexmiller

完成后需进行性能检查。

0

评论者:kworam

修复 clj-1647 的补丁文件

0

评论者:kworam

由于'n'和'step'在整个递归自调用过程中保持不变,因此我只需在初始调用时验证它们一次为正。

因此,我创建了名为'internal-partition'和'internal-partition-all'的函数,其实现方式与当前版本的'partition'和'partition-all'相同。

然后,我将'partition'和'partition-all'函数的先决条件添加为'step'和'n'必须为正,并且分别调用'internal-partition'和'internal-partition-all'来完成工作。

0

评论者:alexmiller

在此补丁中有许多无关的空白更改 - 您能否提供一个只包含问题的更改的较小补丁?还需要测试。

0

评论者:kworam

我将提供一个不带空白更改的补丁文件。

我在test_clojure\sequences.clj和test_clojure\transducers.clj中知道有些现有的功能测试用于'partition'和'partition-all'。我认为我不需要添加更多的功能测试,但我认为我应该添加

  1. 测试验证非正的'step'和'n'参数被拒绝。
  2. 测试表明'partition'和'partition-all'的性能没有显著下降。

您能提供有关如何开发和添加这些测试的指导吗?

0

评论者:alexmiller

您应该在补丁中添加#1。对于#2,您只需在 timings 之前/之后进行,(criterium 是一个好的工具)并将结果放入说明中。

0
_由 kworam 发表评论_

我已经编写了#1的测试,并且使用criterium取了一些“before”时间。

我现在遇到了一个困扰我几个小时的问题,我需要一些帮助。我修改了 core.clj 中的'partition'和'partition-all',然后执行了'mvn package'来构建 jar。然后我执行了 'target>java -cp clojure-1.7.0-master-SNAPSHOT.jar clojure.main' 以交互式测试我的修补后的 clojure 版本。(source ...) 函数显示我为'partition'和'partition-all'做的源代码更改已经生效。我的partition-all变更似乎正常,但我的 partition 变更不起作用。根据我的了解,它们都应该抛出一个 AssertionError,并带有我提供的输入参数。 

任何帮助都将非常感激。


user=> (source partition)
(defn partition
  "返回一个懒序列,其中包含由 n 项组成的列表,步长为offset
  。如果未提供步长,则默认为 n,即分区
  不重叠。如果提供了填充集合,则使用其元素作为
  完成最后一个分区,直到有 n 个项目为止所必需的。
  如果没有足够的填充元素,则返回一个包含少于 n 个项目的分区。
  {:added "1.0"}
   :static true}
  ([n coll]
     {:pre [(pos? n)]}
     (partition n n coll))
  ([n step coll]
     {:pre [(pos? n) (pos? step)]}
     (internal-partition n step coll))
  ([n step pad coll]
     {:pre [(pos? n) (pos? step)]}
     (internal-partition n step pad coll)))
nil
user=> (partition -1 [1 2 3])
()
user=> (source partition-all)
(defn partition-all
  "返回类似 partition 的懒序列列表,但可能包含
  末尾包含少于 n 个项目的分区。当未提供集合时,返回一个有状态的
  转换器。"
  {:added "1.2"}
   :static true}
  ([^long n]
     (internal-partition-all n))
  ([n coll]
     (partition-all n n coll))
  ([n step coll]
     {:pre [(pos? n) (pos? step)]}
     (internal-partition-all n step coll)))
nil
user=> (partition-all -1 [1 2 3])
AssertionError 断言失败:(pos? n)  clojure.core/partition-all (core.clj:6993)


0

评论者:alexmiller

你运行了mvn clean?还是rm target?

0

评论者:kworam

是的,我已经运行了 mvn clean,并在执行交互式测试之前验证了 clojure-1.7.0-master-SNAPSHOT.jar 具有预期的日期时间戳。我甚至在我的 Macbook 上回溯了我的步骤,根据理论,可能存在特定于 Windows 的构建问题。

我的 partition-all 修改按预期工作,但是我的 partition 修改没有。然而,如果我将调用 (source partition) 的结果复制并执行它(将 clojure.core/partition 替换为 user/partition),user/partition 按预期工作。我不明白为什么 clojure.core/partition 的修改没有生效。

0

评论者:jafingerhut

Kevin,我不知道你的 Clojure 源代码历史,但如果你在其中运行了 'ant',它会在根目录中创建 jar 文件,而 'mvn package' 则会在 target 目录中创建它们。从你上面的更长的评论中不清楚你运行的 'java -cp ...' 命令是否指向目标目录中的那个。这可能不是你看到问题的原因,但我还没有其他任何猜测。

0
by

评论者:alexmiller

这个状态如何?

0
by

评论者:kworam

Alex,我最近搬到西雅图,并在微软获得了永久职位。这让我非常忙碌,我完全没有时间去做Clojure。我可能需要再过一两个月才能抽出时间来。

0
by

评论者:alexmiller

感谢提前通知。

0
by

评论者:alex+import

Kevin,Alex,你们需要我来负责这项工作吗?

...