summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJosé Valim <jose.valim@gmail.com>2015-09-27 18:04:56 +0200
committerJosé Valim <jose.valim@gmail.com>2015-09-27 18:04:56 +0200
commit31d6fbf3b75bcabb2a31e6d5f7ce3a26d6ba7a91 (patch)
treeefe44da353378600db0ee984b78c07969618a581
parent835f8b974dfcf4507f11d7401e58567f611894c9 (diff)
parent31a30afafdf5b82c086bd91efaa879ba3397ad75 (diff)
downloadelixir-31d6fbf3b75bcabb2a31e6d5f7ce3a26d6ba7a91.tar.gz
Merge pull request #3783 from eksperimental/fix_range_integer2
Fix Range validation
-rw-r--r--lib/elixir/lib/kernel.ex8
-rw-r--r--lib/elixir/lib/range.ex19
-rw-r--r--lib/elixir/test/elixir/range_test.exs11
3 files changed, 30 insertions, 8 deletions
diff --git a/lib/elixir/lib/kernel.ex b/lib/elixir/lib/kernel.ex
index 7ed359af6..38af77415 100644
--- a/lib/elixir/lib/kernel.ex
+++ b/lib/elixir/lib/kernel.ex
@@ -2444,16 +2444,18 @@ defmodule Kernel do
defmacro first .. last do
case is_float(first) or is_float(last) or
is_atom(first) or is_atom(last) or
- is_binary(first) or is_binary(last) do
+ is_binary(first) or is_binary(last) or
+ is_list(first) or is_list(last) do
true ->
raise ArgumentError,
- "ranges (left .. right) expect both sides to be integers, " <>
+ "ranges (first .. last) expect both sides to be integers, " <>
"got: #{Macro.to_string({:.., [], [first, last]})}"
false ->
{:%{}, [], [__struct__: Elixir.Range, first: first, last: last]}
end
end
+
@doc """
Provides a short-circuit operator that evaluates and returns
the second expression only if the first one evaluates to `true`
@@ -2677,7 +2679,7 @@ defmodule Kernel do
{:%{}, [], [__struct__: Elixir.Range, first: first, last: last]} ->
in_range(left, Macro.expand(first, __CALLER__), Macro.expand(last, __CALLER__))
_ ->
- raise ArgumentError, <<"invalid args for operator in, it expects a compile time list ",
+ raise ArgumentError, <<"invalid args for operator \"in\", it expects a compile time list ",
"or range on the right side when used in guard expressions, got: ",
Macro.to_string(right) :: binary>>
end
diff --git a/lib/elixir/lib/range.ex b/lib/elixir/lib/range.ex
index 0f34001aa..4d4a7cf68 100644
--- a/lib/elixir/lib/range.ex
+++ b/lib/elixir/lib/range.ex
@@ -31,12 +31,13 @@ defmodule Range do
@doc """
Creates a new range.
"""
- def new(first, last) do
+ @spec new(integer, integer) :: t
+ def new(first, last) when is_integer(first) and is_integer(last) do
%Range{first: first, last: last}
end
@doc """
- Returns `true` if the given argument is a range.
+ Returns `true` if the given `term` is a range.
## Examples
@@ -47,6 +48,12 @@ defmodule Range do
false
"""
+ # @spec range?(term) :: boolean
+ @spec range?(arg) :: false when arg: %Range{first: nil, last: nil}
+ @spec range?(arg) :: true when arg: %Range{}
+ @spec range?(term) :: false
+ def range?(term)
+ def range?(%Range{first: nil, last: nil}), do: false
def range?(%Range{}), do: true
def range?(_), do: false
end
@@ -95,10 +102,14 @@ defimpl Enumerable, for: Range do
end
end
- defp validate_range!(first, last) when is_integer(first) and is_integer(last), do: :ok
+ defp validate_range!(first, last) when is_integer(first)
+ and is_integer(last),
+ do: :ok
+
defp validate_range!(first, last) do
raise ArgumentError,
- "ranges (left .. right) expect both sides to be integers, got: #{inspect first..last}"
+ "ranges (first .. last) expect both sides to be integers, " <>
+ "got: #{Macro.to_string({:.., [], [first, last]})}"
end
end
diff --git a/lib/elixir/test/elixir/range_test.exs b/lib/elixir/test/elixir/range_test.exs
index 924644e22..d25883ba3 100644
--- a/lib/elixir/test/elixir/range_test.exs
+++ b/lib/elixir/test/elixir/range_test.exs
@@ -42,9 +42,18 @@ defmodule RangeTest do
test "integer only" do
x = 1.0
y = 3.0
- message = "ranges (left .. right) expect both sides to be integers, got: 1.0..3.0"
+ message = "ranges (first .. last) expect both sides to be integers, got: 1.0..3.0"
assert_raise ArgumentError, message, fn ->
Enum.map(x..y, &(&1 * 2))
end
+
+ first = []
+ last = []
+ message = "ranges (first .. last) expect both sides to be integers, got: []..[]"
+ assert_raise ArgumentError, message, fn ->
+ first..last
+ Enum.map(first..last, &(&1))
+ end
+
end
end