Permalink
Browse files

Add `ordered_iterator` function

Some of the Enum's functions assume an ordering is defined for the collection.
Since ordering is not defined for all types, using `ordered_iterator`
allows us to raise a runtime error for those types.
  • Loading branch information...
1 parent d79ba92 commit 2c4f17fff281277e62ac371b72c6fde1db0c8f1b @alco committed Apr 17, 2012
Showing with 55 additions and 69 deletions.
  1. +16 −10 lib/enum.ex
  2. +39 −59 test/elixir/enum_test.exs
View
@@ -114,7 +114,7 @@ defmodule Enum do
"""
def drop(collection, count) do
- { iterator, pointer } = I.iterator(collection)
+ { iterator, pointer } = I.ordered_iterator(collection)
drop(iterator, pointer, count)
end
@@ -131,7 +131,7 @@ defmodule Enum do
#=> [3,4,5]
"""
def drop_while(collection, fun) do
- { iterator, pointer } = I.iterator(collection)
+ { iterator, pointer } = I.ordered_iterator(collection)
drop_while(iterator, pointer, fun)
end
@@ -302,7 +302,7 @@ defmodule Enum do
"""
def join(collection, joiner // "") do
- { iterator, pointer } = I.iterator(collection)
+ { iterator, pointer } = I.ordered_iterator(collection)
join(iterator, pointer, joiner)
end
@@ -453,7 +453,7 @@ defmodule Enum do
"""
def split(collection, count) do
- { iterator, pointer } = I.iterator(collection)
+ { iterator, pointer } = I.ordered_iterator(collection)
split(iterator, pointer, count)
end
@@ -470,7 +470,7 @@ defmodule Enum do
#=> { [1], [2, 3, 4] }
"""
def split_with(collection, fun) do
- { iterator, pointer } = I.iterator(collection)
+ { iterator, pointer } = I.ordered_iterator(collection)
split_with(iterator, pointer, fun)
end
@@ -489,7 +489,7 @@ defmodule Enum do
"""
def take(collection, count) do
- { iterator, pointer } = I.iterator(collection)
+ { iterator, pointer } = I.ordered_iterator(collection)
take(iterator, pointer, count)
end
@@ -507,7 +507,7 @@ defmodule Enum do
"""
def take_while(collection, fun // fn(x, do: x)) do
- { iterator, pointer } = I.iterator(collection)
+ { iterator, pointer } = I.ordered_iterator(collection)
take_while(iterator, pointer, fun)
end
@@ -848,6 +848,8 @@ end
defimpl Enum.Iterator, for: List do
def iterator(list), do: { iterate(&1), iterate({ list, fn(list, do: list) }) }
+ def ordered_iterator(list), do: iterator(list)
+
def to_list(list), do: list
def iterate({ [h|t], ctor }) do
@@ -868,9 +870,13 @@ end
defimpl Enum.Iterator, for: Tuple do
import Enum.Iterator.List, only: [iterate: 1]
- def iterator(dict), do: { iterate(&1),
- iterate({ to_list(dict),
- fn(pairs, do: extend(PDict.empty(dict), pairs)) }) }
+ def iterator(dict) do
+ { iterate(&1), iterate({ to_list(dict), fn(pairs, do: extend(PDict.empty(dict), pairs)) }) }
+ end
+
+ def ordered_iterator(_) do
+ raise ArgumentError, message: "Dict does not support ordering"
+ end
def to_list(dict), do: PDict.to_list(dict)
@@ -202,21 +202,17 @@ defmodule EnumTest.Dict do
refute Enum.any?(Dict.new)
end
-# test :drop do
-# assert_equal [1,2,3], Enum.drop [1,2,3], 0
-# assert_equal [2,3], Enum.drop [1,2,3], 1
-# assert_equal [3], Enum.drop [1,2,3], 2
-# assert_equal [], Enum.drop [1,2,3], 3
-# assert_equal [], Enum.drop [1,2,3], 4
-# assert_equal [], Enum.drop [], 3
-# end
-#
-# test :drop_while do
-# assert_equal [4,3,2,1], Enum.drop_while [1,2,3,4,3,2,1], fn(x, do: x <= 3)
-# assert_equal [1,2,3], Enum.drop_while [1,2,3], fn(_, do: false)
-# assert_equal [], Enum.drop_while [1,2,3], fn(x, do: x <= 3)
-# assert_equal [], Enum.drop_while [], fn(_, do: false)
-# end
+ test :drop do
+ assert_raises ArgumentError, fn ->
+ Enum.drop Dict.new, 5
+ end
+ end
+
+ test :drop_while do
+ assert_raises ArgumentError, fn ->
+ Enum.drop_while Dict.new, fn(x, do: x)
+ end
+ end
test :find do
dict = Dict.new [:a, :b, :c], [1, 2, 3]
@@ -291,18 +287,11 @@ defmodule EnumTest.Dict do
assert_equal 7, Enum.reduce(dict, 1, fn({_, v}, acc, do: v + acc))
end
-# test :join_with_bin do
-# assert_equal "", Enum.join([], " = ")
-# assert_equal "1 = 2 = 3", Enum.join([1,2,3], " = ")
-# assert_equal "1 = 2 = 3", Enum.join([1,"2",3], " = ")
-# assert_equal "123", Enum.join([1,2,3])
-# end
-#
-# test :join_with_list do
-# assert_equal '', Enum.join([], ' = ')
-# assert_equal '1 = 2 = 3', Enum.join([1,2,3], ' = ')
-# assert_equal '1 = 2 = 3', Enum.join([1,"2",3], ' = ')
-# end
+ test :join do
+ assert_raises ArgumentError, fn ->
+ Enum.join Dict.new, ""
+ end
+ end
test :keyfind do
dict = Dict.new [a: 1, b: 2, c: 3]
@@ -332,36 +321,27 @@ defmodule EnumTest.Dict do
assert_equal { dict, Dict.new }, Enum.partition(dict, fn({_k, v}, do: v < 10))
end
-# test :split do
-# assert_equal { [], [1,2,3] }, Enum.split [1,2,3], 0
-# assert_equal { [1], [2,3] }, Enum.split [1,2,3], 1
-# assert_equal { [1,2], [3] }, Enum.split [1,2,3], 2
-# assert_equal { [1,2,3], [] }, Enum.split [1,2,3], 3
-# assert_equal { [1,2,3], [] }, Enum.split [1,2,3], 4
-# assert_equal { [], [] }, Enum.split [], 3
-# end
-#
-# test :split_with do
-# assert_equal { [1,2,3], [] }, Enum.split_with [1,2,3], fn(_, do: false)
-# assert_equal { [], [1,2,3] }, Enum.split_with [1,2,3], fn(_, do: true)
-# assert_equal { [1,2], [3] }, Enum.split_with [1,2,3], fn(x, do: x > 2)
-# assert_equal { [1,2,3], [] }, Enum.split_with [1,2,3], fn(x, do: x > 3)
-# assert_equal { [], [] }, Enum.split_with [], fn(_, do: true)
-# end
-#
-# test :take do
-# assert_equal [], Enum.take [1,2,3], 0
-# assert_equal [1], Enum.take [1,2,3], 1
-# assert_equal [1,2], Enum.take [1,2,3], 2
-# assert_equal [1,2,3], Enum.take [1,2,3], 3
-# assert_equal [1,2,3], Enum.take [1,2,3], 4
-# assert_equal [], Enum.take [], 3
-# end
-#
-# test :take_while do
-# assert_equal [], Enum.take_while [1,2,3], fn(x, do: x > 3)
-# assert_equal [1], Enum.take_while [1,2,3], fn(x, do: x <= 1)
-# assert_equal [1,2,3], Enum.take_while [1,2,3], fn(x, do: x <= 3)
-# assert_equal [], Enum.take_while [], fn(_, do: true)
-# end
+ test :split do
+ assert_raises ArgumentError, fn ->
+ Enum.split Dict.new, 5
+ end
+ end
+
+ test :split_with do
+ assert_raises ArgumentError, fn ->
+ Enum.split_with Dict.new, fn(x, do: x)
+ end
+ end
+
+ test :take do
+ assert_raises ArgumentError, fn ->
+ Enum.take Dict.new, 5
+ end
+ end
+
+ test :take_while do
+ assert_raises ArgumentError, fn ->
+ Enum.take_while Dict.new, fn(x, do: x)
+ end
+ end
end

0 comments on commit 2c4f17f

Please sign in to comment.