From f248f9d257da2c703c469da05ca88206a7e6c15d Mon Sep 17 00:00:00 2001 From: Juan Facorro Date: Fri, 16 Sep 2016 22:43:13 +0200 Subject: [PATCH 1/4] Implement Access behaviour since the protocol has been deprecated --- lib/array.ex | 54 ++++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 42 insertions(+), 12 deletions(-) diff --git a/lib/array.ex b/lib/array.ex index 4fc9639..cc8b512 100644 --- a/lib/array.ex +++ b/lib/array.ex @@ -1,4 +1,5 @@ defmodule Array do + @behaviour Access @moduledoc """ A wrapper module for Erlang's array. """ @@ -15,7 +16,7 @@ defmodule Array do Creates a new, extendible array with initial size zero. The default value is the atom nil, not undefined. """ - @spec new() :: t + @spec new() :: t def new() do %Array{content: :array.new({:default, nil})} end @@ -85,7 +86,7 @@ defmodule Array do @doc """ Folds the elements of the array using the given function and initial accumulator value. - The elements are visited in order from the lowest index to the highest. + The elements are visited in order from the lowest index to the highest. If `fun` is not a function, the call raises `ArgumentError`. """ @@ -96,7 +97,7 @@ defmodule Array do @doc """ Folds the elements of the array right-to-left using the given function and initial accumulator value. The elements are visited in order from the highest index to the lowest. - + If `fun` is not a function, the call raises `ArgumentError`. """ @spec foldr(t, acc, (index, element, acc -> acc)) :: acc when acc: var @@ -184,7 +185,7 @@ defmodule Array do @doc """ Maps the given function onto each element of the array. The elements are visited in order from the lowest index to the highest. - + If `fun` is not a function, the call raises `ArgumentError`. """ @spec map(t, (index, element -> any)) :: t @@ -260,7 +261,7 @@ defmodule Array do Folds the elements of the array right-to-left using the given function and initial accumulator value, skipping default-valued entries. The elements are visited in order from the highest index to the lowest. - + If `fun` is not a function, the call raises `ArgumentError`. """ @spec sparse_foldr(t, acc, (index, element, acc -> acc)) :: acc when acc: var @@ -270,7 +271,7 @@ defmodule Array do @doc """ Maps the given function onto each element of the array, skipping default-valued entries. The elements are visited in order from the lowest index to the highest. - + If `fun` is not a function, the call raises `ArgumentError`. """ @spec sparse_map(t, (element -> any)) :: t @@ -320,16 +321,45 @@ defmodule Array do @spec to_orddict(t) :: [{index, element}] def to_orddict(%Array{content: c}), do: :array.to_orddict(c) -end -defimpl Access, for: Array do - def get(arr, idx) do - Array.get(arr, idx) + @doc """ + Access behavior `fetch/2` callback. + """ + def fetch(arr, idx) do + {:ok, get(arr, idx)} end + @doc """ + Access behavior `get/3` callback + """ + def get(arr, idx, value) do + if size(arr) < idx do + get(arr, idx) + else + value + end + end + + @doc """ + Access behavior `get_and_update/3` callback + """ def get_and_update(arr, idx, fun) do - {get, update} = fun.(Array.get(arr, idx)) - {get, Array.set(arr, idx, update)} + value = get(arr, idx) + case fun.(value) do + {get, update} -> {get, set(arr, idx, update)} + :pop -> {value, set(arr, idx, nil)} + end + end + + @doc """ + Access behavior `pop/2` callback + """ + def pop(arr, idx) do + if size(arr) < idx do + {get(arr, idx), set(arr, idx, nil)} + else + {nil, arr} + end end end From 5547ab6e0acb52db221b5ec4addf79a751078df7 Mon Sep 17 00:00:00 2001 From: Juan Facorro Date: Sat, 31 Oct 2020 19:21:35 +0100 Subject: [PATCH 2/4] Implement missing slice function for Enumerable protocol --- lib/array.ex | 9 +++++++++ mix.exs | 16 ++-------------- test/array_test.exs | 12 ++++++++++-- 3 files changed, 21 insertions(+), 16 deletions(-) diff --git a/lib/array.ex b/lib/array.ex index cc8b512..d07a71b 100644 --- a/lib/array.ex +++ b/lib/array.ex @@ -371,6 +371,15 @@ defimpl Enumerable, for: Array do def reduce(%Array{content: c}, acc, fun) do Enumerable.reduce(:array.to_list(c), acc, fun) end + + def slice(arr) do + slice_fun = fn (start, length) -> + for i <- start..(start + length - 1) do + Array.get(arr, i) + end + end + {:ok, Array.size(arr), slice_fun} + end end defimpl Collectable, for: Array do diff --git a/mix.exs b/mix.exs index 0c3e169..30146cf 100644 --- a/mix.exs +++ b/mix.exs @@ -6,26 +6,14 @@ defmodule Array.Mixfile do version: "1.0.1", elixir: ">= 1.0.0", description: "An elixir wrapper library for Erlang's array.", - package: package, - deps: deps] + package: package(), + deps: deps()] end - # Configuration for the OTP application - # - # Type `mix help compile.app` for more information def application do [applications: [:logger]] end - # Dependencies can be Hex packages: - # - # {:mydep, "~> 0.3.0"} - # - # Or git/path repositories: - # - # {:mydep, git: "https://github.com/elixir-lang/mydep.git", tag: "0.1.0"} - # - # Type `mix help deps` for more examples and options defp deps do [{:earmark, ">= 0.0.0", only: :dev}, {:ex_doc, "~> 0.6", only: :dev}] diff --git a/test/array_test.exs b/test/array_test.exs index 5d8af8b..08322c1 100644 --- a/test/array_test.exs +++ b/test/array_test.exs @@ -87,7 +87,7 @@ defmodule ArrayTest do test "fix" do a = Array.new() a = Array.set(a, 100, 0) - + a = Array.fix(a) assert_raise ArgumentError, fn -> Array.set(a, 101, 0) @@ -405,7 +405,7 @@ defmodule ArrayTest do test "to_erlang_array" do a = Array.from_list([1,2,3]) ea = Array.to_erlang_array(a) - + assert :array.is_array(ea) assert 3 == :array.size(ea) assert 1 == :array.get(0, ea) @@ -454,6 +454,14 @@ defmodule ArrayTest do assert 6 == sum end + test "Enumerable.slice" do + slice = Enum.slice(Array.from_list([1,2,3,4,5]), 1, 2) + assert [2,3] == slice + + slice = Enum.slice(Array.from_list([1,2,3,4,5]), 3, 1) + assert [4] == slice + end + test "Collectable.into" do a = Enum.into([1,2,3], Array.new()) assert Array.is_array(a) From 2d7cd9317f9a027a3aab5b64faf93d08ba10674d Mon Sep 17 00:00:00 2001 From: Juan Facorro Date: Sat, 31 Oct 2020 19:24:51 +0100 Subject: [PATCH 3/4] Change application's name --- mix.exs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mix.exs b/mix.exs index 30146cf..0060339 100644 --- a/mix.exs +++ b/mix.exs @@ -2,7 +2,7 @@ defmodule Array.Mixfile do use Mix.Project def project do - [app: :array, + [app: :elixir_array, version: "1.0.1", elixir: ">= 1.0.0", description: "An elixir wrapper library for Erlang's array.", From 112dd36810bec4c069ebd1488fd915f2a703503a Mon Sep 17 00:00:00 2001 From: Juan Facorro Date: Sat, 31 Oct 2020 19:25:49 +0100 Subject: [PATCH 4/4] Bump version to 2.1.0 and Elixir version to 1.11.1 --- mix.exs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mix.exs b/mix.exs index 0060339..1671cea 100644 --- a/mix.exs +++ b/mix.exs @@ -3,8 +3,8 @@ defmodule Array.Mixfile do def project do [app: :elixir_array, - version: "1.0.1", - elixir: ">= 1.0.0", + version: "2.1.0", + elixir: ">= 1.11.1", description: "An elixir wrapper library for Erlang's array.", package: package(), deps: deps()]