2024 状态 Clojure 问卷调查! 中分享你的想法。

欢迎!请参阅 关于 页面以了解这个平台的更多信息。

0
Clojure

如果你给 partition 传递一个非正的 'n' 或 'step' 值,你将会得到一个无限循环。以下是一些示例

(partition 0 [1 2 3])
(partition 1 -1 [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
by

评论人:kworam

因为'n'和'step'从初始函数调用到所有递归自调用保持不变,所以我只需要在初始调用时验证一次它们是正数。

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

我将'partition'和'partition-all'函数中的'step'和'n'必须为正的前置条件添加到这两个函数中,并使它们分别调用'internal-partition'和'internal-partition-all'来执行工作。

0
by

评论人:alexmiller

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

0
by

评论人:kworam

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

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

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

你能否给我一些建议,如何开发并添加这些测试?

0
by

评论人:alexmiller

你应该将#1添加到补丁中。对于#2,你只需在前后进行计时(criterium是一个很好的工具)并将结果放在描述中。

0
by
_评论者: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
  "返回一个 lazy 序列,其中包括每个列表有 n 个元素,且步长为 step
  分开。如果未提供 step,则默认为 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 的 lazy 序列,可能包括
  最后可以有少于 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) 的结果复制并执行(用 user/partition 替换 clojure.core/partition),user/partition 正常工作。我不明白为什么 clojure.core/partition 的修改没有生效。

0
已回答

评论由:jafingerhut 提出

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

0

评论人:alexmiller

这个问题的状态是什么?

0

评论人:kworam

Alex,我最近搬到了西雅图,在微软找到了一份永久职位。这使得我非常忙碌,我完全没时间花在 Clojure 上。我可能在下个月或两个月内都无法抽时间做 Clojure。

0

评论人:alexmiller

感谢提前通知。

0

评论由:alex+import 提出

Kevin,Alex,如果你们愿意,我可以接手这个事吗?

...