Skip to content

Commit f248f9d

Browse files
committed
Implement Access behaviour since the protocol has been deprecated
1 parent 4765c83 commit f248f9d

File tree

1 file changed

+42
-12
lines changed

1 file changed

+42
-12
lines changed

lib/array.ex

Lines changed: 42 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
defmodule Array do
2+
@behaviour Access
23
@moduledoc """
34
A wrapper module for Erlang's array.
45
"""
@@ -15,7 +16,7 @@ defmodule Array do
1516
Creates a new, extendible array with initial size zero.
1617
The default value is the atom nil, not undefined.
1718
"""
18-
@spec new() :: t
19+
@spec new() :: t
1920
def new() do
2021
%Array{content: :array.new({:default, nil})}
2122
end
@@ -85,7 +86,7 @@ defmodule Array do
8586

8687
@doc """
8788
Folds the elements of the array using the given function and initial accumulator value.
88-
The elements are visited in order from the lowest index to the highest.
89+
The elements are visited in order from the lowest index to the highest.
8990
9091
If `fun` is not a function, the call raises `ArgumentError`.
9192
"""
@@ -96,7 +97,7 @@ defmodule Array do
9697
@doc """
9798
Folds the elements of the array right-to-left using the given function and initial accumulator value.
9899
The elements are visited in order from the highest index to the lowest.
99-
100+
100101
If `fun` is not a function, the call raises `ArgumentError`.
101102
"""
102103
@spec foldr(t, acc, (index, element, acc -> acc)) :: acc when acc: var
@@ -184,7 +185,7 @@ defmodule Array do
184185
@doc """
185186
Maps the given function onto each element of the array.
186187
The elements are visited in order from the lowest index to the highest.
187-
188+
188189
If `fun` is not a function, the call raises `ArgumentError`.
189190
"""
190191
@spec map(t, (index, element -> any)) :: t
@@ -260,7 +261,7 @@ defmodule Array do
260261
Folds the elements of the array right-to-left using the given function and initial accumulator value,
261262
skipping default-valued entries.
262263
The elements are visited in order from the highest index to the lowest.
263-
264+
264265
If `fun` is not a function, the call raises `ArgumentError`.
265266
"""
266267
@spec sparse_foldr(t, acc, (index, element, acc -> acc)) :: acc when acc: var
@@ -270,7 +271,7 @@ defmodule Array do
270271
@doc """
271272
Maps the given function onto each element of the array, skipping default-valued entries.
272273
The elements are visited in order from the lowest index to the highest.
273-
274+
274275
If `fun` is not a function, the call raises `ArgumentError`.
275276
"""
276277
@spec sparse_map(t, (element -> any)) :: t
@@ -320,16 +321,45 @@ defmodule Array do
320321
@spec to_orddict(t) :: [{index, element}]
321322
def to_orddict(%Array{content: c}),
322323
do: :array.to_orddict(c)
323-
end
324324

325-
defimpl Access, for: Array do
326-
def get(arr, idx) do
327-
Array.get(arr, idx)
325+
@doc """
326+
Access behavior `fetch/2` callback.
327+
"""
328+
def fetch(arr, idx) do
329+
{:ok, get(arr, idx)}
328330
end
329331

332+
@doc """
333+
Access behavior `get/3` callback
334+
"""
335+
def get(arr, idx, value) do
336+
if size(arr) < idx do
337+
get(arr, idx)
338+
else
339+
value
340+
end
341+
end
342+
343+
@doc """
344+
Access behavior `get_and_update/3` callback
345+
"""
330346
def get_and_update(arr, idx, fun) do
331-
{get, update} = fun.(Array.get(arr, idx))
332-
{get, Array.set(arr, idx, update)}
347+
value = get(arr, idx)
348+
case fun.(value) do
349+
{get, update} -> {get, set(arr, idx, update)}
350+
:pop -> {value, set(arr, idx, nil)}
351+
end
352+
end
353+
354+
@doc """
355+
Access behavior `pop/2` callback
356+
"""
357+
def pop(arr, idx) do
358+
if size(arr) < idx do
359+
{get(arr, idx), set(arr, idx, nil)}
360+
else
361+
{nil, arr}
362+
end
333363
end
334364
end
335365

0 commit comments

Comments
 (0)