Skip to content

Commit

Permalink
Edit pass over access.ex (elixir-lang#5369)
Browse files Browse the repository at this point in the history
  • Loading branch information
fxn authored and josevalim committed Oct 28, 2016
1 parent 4e0cb3e commit da6f6cf
Showing 1 changed file with 50 additions and 32 deletions.
82 changes: 50 additions & 32 deletions lib/elixir/lib/access.ex
Original file line number Diff line number Diff line change
Expand Up @@ -181,19 +181,20 @@ defmodule Access do
@callback get(term :: t, key, default :: value) :: value

@doc """
Invoked in order to access the value under `key` and updated it at the same time.
Invoked in order to access the value under `key` and update it at the same time.
The implementation of this callback should invoke the passed function on the
value under key `key` in the passed structure; this function should return
either `{value_to_return, new_value}` or `:pop`.
The implementation of this callback should invoke the passed function with the
value under key `key` in the passed structure, or `nil` if the key is not
present. This function should return either `{value_to_return, new_value}` or
`:pop`.
If it returns `{value_to_return, new_value}`, the return value of this
callback should be `{value_to_return, new_term}` where `new_term` is `term`
after updating the value of `key` with `new_value`.
If it returns `:pop`, the return value of this callback should be `{value,
new_term}` where `value` is the value under `key` and `new_term` is `term`
after removing the key `key`.
new_term}` where `value` is the value under `key` or `nil` if not present, and
`new_term` is `term` without the key `key`.
See the implementations of `Map.get_and_update/3` or `Keyword.get_and_update/3`
for more examples.
Expand All @@ -203,9 +204,12 @@ defmodule Access do
@doc """
Invoked to "pop" the value under `key` out of the given term.
The implementation should remove `key` from the given `term` and return a
`{value, new_term}` tuple where `value` is the value that was under `key` and
`new_term` is `term` without `key`.
When the key `key` exists in the given `term`, the implementation should
return a `{value, new_term}` tuple where `value` is the value that was under
`key` and `new_term` is `term` without `key`.
When the key `key` is not present in the given `term`, a tuple `{value, term}`
should be returned, where `value` is implementation-defined.
See the implementations for `Map.pop/3` or `Keyword.pop/3` for more examples.
"""
Expand All @@ -227,7 +231,7 @@ defmodule Access do

@doc """
Fetches the value for the given key in a container (a map, keyword
list, or anything that implements the `Access` behaviour).
list, or struct that implements the `Access` behaviour).
"""
@spec fetch(t, term) :: {:ok, term} | :error
def fetch(container, key)
Expand All @@ -239,15 +243,12 @@ defmodule Access do
raise_undefined_behaviour e, struct, {^struct, :fetch, [^container, ^key], _}
end

def fetch(%{} = map, key) do
:maps.find(key, map)
def fetch(map, key) when is_map(map) do
Map.fetch(map, key)
end

def fetch(list, key) when is_list(list) and is_atom(key) do
case :lists.keyfind(key, 1, list) do
{^key, value} -> {:ok, value}
false -> :error
end
Keyword.fetch(list, key)
end

def fetch(list, key) when is_list(list) do
Expand All @@ -261,7 +262,7 @@ defmodule Access do

@doc """
Gets the value for the given key in a container (a map, keyword
list, or anything that implements the `Access` behaviour).
list, or struct that implements the `Access` behaviour).
"""
@spec get(t, term, term) :: term
def get(container, key, default \\ nil) do
Expand All @@ -273,7 +274,7 @@ defmodule Access do

@doc """
Gets and updates the given key in a container (a map, keyword
list, or anything that implements the `Access` behaviour).
list, or struct that implements the `Access` behaviour).
This `fun` argument receives the value of `key` (or `nil` if `key`
is not present) and must return a two-element tuple: the "get" value
Expand All @@ -295,7 +296,7 @@ defmodule Access do
raise_undefined_behaviour e, struct, {^struct, :get_and_update, [^container, ^key, ^fun], _}
end

def get_and_update(%{} = map, key, fun) do
def get_and_update(map, key, fun) when is_map(map) do
Map.get_and_update(map, key, fun)
end

Expand All @@ -310,7 +311,7 @@ defmodule Access do

@doc """
Removes the entry with a given key from a container (a map, keyword
list, or anything that implements the `Access` behaviour).
list, or struct that implements the `Access` behaviour).
Returns a tuple containing the value associated with the key and the
updated container. `nil` is returned for the value if the key isn't
Expand Down Expand Up @@ -340,13 +341,15 @@ defmodule Access do
e in UndefinedFunctionError ->
raise_undefined_behaviour e, struct, {^struct, :pop, [^container, ^key], _}
end
def pop(list, key) when is_list(list), do: Keyword.pop(list, key)

def pop(map, key) when is_map(map) do
case map do
%{^key => value} -> {value, :maps.remove(key, map)}
%{} -> {nil, map}
end
Map.pop(map, key)
end

def pop(list, key) when is_list(list) do
Keyword.pop(list, key)
end

def pop(nil, key) do
raise ArgumentError,
"could not pop key #{inspect key} on a nil value"
Expand All @@ -355,10 +358,13 @@ defmodule Access do
## Accessors

@doc """
Accesses the given key in a map/struct.
Returns a function that accesses the given key in a map/struct.
The returned function is typically passed as an accessor to `Kernel.get_in/2`,
`Kernel.get_and_update_in/3`, and friends.
Uses the default value if the key does not exist
or if the value being accessed is `nil`.
Uses the default value if the key does not exist or if the value being
accessed is `nil`.
## Examples
Expand Down Expand Up @@ -403,7 +409,10 @@ defmodule Access do
defp to_map(data), do: raise "Access.key/1 expected a map/struct or nil, got: #{inspect data}"

@doc """
Accesses the given key in a map/struct.
Returns a function that accesses the given key in a map/struct.
The returned function is typically passed as an accessor to `Kernel.get_in/2`,
`Kernel.get_and_update_in/3`, and friends.
Raises if the key does not exist.
Expand Down Expand Up @@ -443,7 +452,10 @@ defmodule Access do
end

@doc ~S"""
Accesses the element at the given index in a tuple.
Returns a function that accesses the element at the given index in a tuple.
The returned function is typically passed as an accessor to `Kernel.get_in/2`,
`Kernel.get_and_update_in/3`, and friends.
Raises if the index is out of bounds.
Expand Down Expand Up @@ -483,7 +495,10 @@ defmodule Access do
end

@doc ~S"""
Accesses all the elements in a list.
Returns a function that accesses all the elements in a list.
The returned function is typically passed as an accessor to `Kernel.get_in/2`,
`Kernel.get_and_update_in/3`, and friends.
## Examples
Expand Down Expand Up @@ -540,7 +555,10 @@ defmodule Access do
end

@doc ~S"""
Accesses the element at `index` (zero based) of a list.
Returns a function that accesses the element at `index` (zero based) of a list.
The returned function is typically passed as an accessor to `Kernel.get_in/2`,
`Kernel.get_and_update_in/3`, and friends.
## Examples
Expand Down

0 comments on commit da6f6cf

Please sign in to comment.