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 的 patch 文件

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点,你只需在之前/之后进行计时(criterium 是一个好的工具),并将结果放入说明中。

0 投票
评论由:kworam_作出

我已经编写了第1个测试,并使用 criterium 取出了一些 'before' 的时间。  

我已经被一个问题困扰了好几个小时,现在我需要一些帮助。我已经对 'partition' 和 'partition-all' 进行了更改,保存在 core.clj 中,然后执行了 '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个项目的分区。当没有提供集合时,返回一个有状态的
  transducer。"
  {: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 ...'命令是否指向target目录中的那个。这可能是你遇到问题的原因,但我还没有任何猜测其它的可能原因。

0 投票

评论者:alexmiller

这个状态是什么?

0 投票

评论者:kworam

Alex,我最近搬到了西雅图,并加入了微软,担任了一份永久职位。这让我非常忙碌,完全没有时间投入到Clojure上了。很可能我还需要一个月或者两个月才能再次投入Clojure的开发。

0 投票

评论者:alexmiller

谢谢提醒。

0 投票

评论者:alex+import

Kevin,Alex,如果你愿意我可以继续这个工作吗?

...