Skip to content

Commit 13ba96b

Browse files
committed
Keep backwards compatibility on range usage, closes #11110
1 parent edb5e7e commit 13ba96b

File tree

3 files changed

+63
-0
lines changed

3 files changed

+63
-0
lines changed

lib/elixir/lib/range.ex

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,12 @@ defmodule Range do
185185
def size(first..last//step) when step < 0 and first < last, do: 0
186186
def size(first..last//step), do: abs(div(last - first, step)) + 1
187187

188+
# TODO: Remove me on v2.0
189+
def size(%{__struct__: Range, first: first, last: last} = range) do
190+
step = if first <= last, do: 1, else: -1
191+
size(Map.put(range, :step, step))
192+
end
193+
188194
@doc """
189195
Checks if two ranges are disjoint.
190196
@@ -273,6 +279,12 @@ defimpl Enumerable, for: Range do
273279
reduce(first, last, acc, fun, step)
274280
end
275281

282+
# TODO: Remove me on v2.0
283+
def reduce(%{__struct__: Range, first: first, last: last} = range, acc, fun) do
284+
step = if first <= last, do: 1, else: -1
285+
reduce(Map.put(range, :step, step), acc, fun)
286+
end
287+
276288
defp reduce(_first, _last, {:halt, acc}, _fun, _step) do
277289
{:halted, acc}
278290
end
@@ -304,6 +316,13 @@ defimpl Enumerable, for: Range do
304316
end
305317
end
306318

319+
# TODO: Remove me on v2.0
320+
def member?(%{__struct__: Range, first: first, last: last} = range, value)
321+
when is_integer(value) do
322+
step = if first <= last, do: 1, else: -1
323+
member?(Map.put(range, :step, step), value)
324+
end
325+
307326
def member?(_, _value) do
308327
{:ok, false}
309328
end
@@ -316,12 +335,19 @@ defimpl Enumerable, for: Range do
316335
{:ok, Range.size(range), &slice(first + &1 * step, step, &2)}
317336
end
318337

338+
# TODO: Remove me on v2.0
339+
def slice(%{__struct__: Range, first: first, last: last} = range) do
340+
step = if first <= last, do: 1, else: -1
341+
slice(Map.put(range, :step, step))
342+
end
343+
319344
defp slice(current, _step, 1), do: [current]
320345
defp slice(current, step, remaining), do: [current | slice(current + step, step, remaining - 1)]
321346
end
322347

323348
defimpl Inspect, for: Range do
324349
import Inspect.Algebra
350+
import Kernel, except: [inspect: 2]
325351

326352
def inspect(first..last//1, opts) do
327353
concat([to_doc(first, opts), "..", to_doc(last, opts)])
@@ -330,4 +356,10 @@ defimpl Inspect, for: Range do
330356
def inspect(first..last//step, opts) do
331357
concat([to_doc(first, opts), "..", to_doc(last, opts), "//", to_doc(step, opts)])
332358
end
359+
360+
# TODO: Remove me on v2.0
361+
def inspect(%{__struct__: Range, first: first, last: last} = range, opts) do
362+
step = if first <= last, do: 1, else: -1
363+
inspect(Map.put(range, :step, step), opts)
364+
end
333365
end

lib/elixir/lib/string.ex

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2098,6 +2098,12 @@ defmodule String do
20982098
end
20992099
end
21002100

2101+
# TODO: Remove me on v2.0
2102+
def slice(string, %{__struct__: Range, first: first, last: last} = range) do
2103+
step = if first <= last, do: 1, else: -1
2104+
slice(string, Map.put(range, :step, step))
2105+
end
2106+
21012107
defp slice_range("", _, _), do: ""
21022108

21032109
defp slice_range(string, first, -1) when first >= 0 do

lib/elixir/test/elixir/range_test.exs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,4 +94,29 @@ defmodule RangeTest do
9494
assert Range.disjoint?(1..1, 1..1) == false
9595
end
9696
end
97+
98+
describe "old ranges" do
99+
test "enum" do
100+
asc = %{__struct__: Range, first: 1, last: 3}
101+
desc = %{__struct__: Range, first: 3, last: 1}
102+
103+
assert Enum.to_list(asc) == [1, 2, 3]
104+
assert Enum.member?(asc, 2)
105+
assert Enum.count(asc) == 3
106+
assert Enum.drop(asc, 1) == [2, 3]
107+
108+
assert Enum.to_list(desc) == [3, 2, 1]
109+
assert Enum.member?(desc, 2)
110+
assert Enum.count(desc) == 3
111+
assert Enum.drop(desc, 1) == [2, 1]
112+
end
113+
114+
test "string" do
115+
asc = %{__struct__: Range, first: 1, last: 3}
116+
desc = %{__struct__: Range, first: 3, last: 1}
117+
118+
assert String.slice("elixir", asc) == "lix"
119+
assert String.slice("elixir", desc) == ""
120+
end
121+
end
97122
end

0 commit comments

Comments
 (0)