Skip to content

Commit

Permalink
Deprecate Dict, HashDict, and HashSet (elixir-lang#5044)
Browse files Browse the repository at this point in the history
  • Loading branch information
whatyouhide authored Jul 21, 2016
1 parent c6a2572 commit 7482564
Show file tree
Hide file tree
Showing 3 changed files with 106 additions and 5 deletions.
66 changes: 65 additions & 1 deletion lib/elixir/lib/dict.ex
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@ defmodule Dict do
@type value :: any
@type t :: list | map

# TODO: Deprecate every function by 1.4
defmacro __using__(_) do
# Use this import to guarantee proper code expansion
import Kernel, except: [size: 1]
Expand All @@ -22,56 +21,75 @@ defmodule Dict do
:elixir_errors.warn(line, file, "the Dict module is deprecated")

quote do
defmacrop __dict_warn_deprecated__() do
quote do
{function, arity} = __ENV__.function
IO.warn String.trim_trailing("""
#{inspect(__MODULE__)}.#{function}/#{arity} has been generated by a
call to "use Dict", and the Dict module has been deprecated
""")
end
end

def get(dict, key, default \\ nil) do
__dict_warn_deprecated__()
case fetch(dict, key) do
{:ok, value} -> value
:error -> default
end
end

def get_lazy(dict, key, fun) when is_function(fun, 0) do
__dict_warn_deprecated__()
case fetch(dict, key) do
{:ok, value} -> value
:error -> fun.()
end
end

def get_and_update(dict, key, fun) do
__dict_warn_deprecated__()
current_value = get(dict, key)
{get, new_value} = fun.(current_value)
{get, put(dict, key, new_value)}
end

def fetch!(dict, key) do
__dict_warn_deprecated__()
case fetch(dict, key) do
{:ok, value} -> value
:error -> raise KeyError, key: key, term: dict
end
end

def has_key?(dict, key) do
__dict_warn_deprecated__()
match? {:ok, _}, fetch(dict, key)
end

def put_new(dict, key, value) do
__dict_warn_deprecated__()
case has_key?(dict, key) do
true -> dict
false -> put(dict, key, value)
end
end

def put_new_lazy(dict, key, fun) when is_function(fun, 0) do
__dict_warn_deprecated__()
case has_key?(dict, key) do
true -> dict
false -> put(dict, key, fun.())
end
end

def drop(dict, keys) do
__dict_warn_deprecated__()
Enum.reduce(keys, dict, &delete(&2, &1))
end

def take(dict, keys) do
__dict_warn_deprecated__()
Enum.reduce(keys, new(), fn key, acc ->
case fetch(dict, key) do
{:ok, value} -> put(acc, key, value)
Expand All @@ -81,24 +99,28 @@ defmodule Dict do
end

def to_list(dict) do
__dict_warn_deprecated__()
reduce(dict, {:cont, []}, fn
kv, acc -> {:cont, [kv | acc]}
end) |> elem(1) |> :lists.reverse
end

def keys(dict) do
__dict_warn_deprecated__()
reduce(dict, {:cont, []}, fn
{k, _}, acc -> {:cont, [k | acc]}
end) |> elem(1) |> :lists.reverse
end

def values(dict) do
__dict_warn_deprecated__()
reduce(dict, {:cont, []}, fn
{_, v}, acc -> {:cont, [v | acc]}
end) |> elem(1) |> :lists.reverse
end

def equal?(dict1, dict2) do
__dict_warn_deprecated__()
# Use this import to avoid conflicts in the user code
import Kernel, except: [size: 1]

Expand All @@ -115,6 +137,7 @@ defmodule Dict do
end

def merge(dict1, dict2, fun \\ fn(_k, _v1, v2) -> v2 end) do
__dict_warn_deprecated__()
# Use this import to avoid conflicts in the user code
import Kernel, except: [size: 1]

Expand All @@ -130,6 +153,7 @@ defmodule Dict do
end

def update(dict, key, initial, fun) do
__dict_warn_deprecated__()
case fetch(dict, key) do
{:ok, value} ->
put(dict, key, fun.(value))
Expand All @@ -139,6 +163,7 @@ defmodule Dict do
end

def update!(dict, key, fun) do
__dict_warn_deprecated__()
case fetch(dict, key) do
{:ok, value} ->
put(dict, key, fun.(value))
Expand All @@ -148,6 +173,7 @@ defmodule Dict do
end

def pop(dict, key, default \\ nil) do
__dict_warn_deprecated__()
case fetch(dict, key) do
{:ok, value} ->
{value, delete(dict, key)}
Expand All @@ -157,6 +183,7 @@ defmodule Dict do
end

def pop_lazy(dict, key, fun) when is_function(fun, 0) do
__dict_warn_deprecated__()
case fetch(dict, key) do
{:ok, value} ->
{value, delete(dict, key)}
Expand All @@ -166,6 +193,7 @@ defmodule Dict do
end

def split(dict, keys) do
__dict_warn_deprecated__()
Enum.reduce(keys, {new(), dict}, fn key, {inc, exc} = acc ->
case fetch(exc, key) do
{:ok, value} ->
Expand Down Expand Up @@ -199,73 +227,98 @@ defmodule Dict do
end
end

defmacrop warn_deprecated() do
quote do
{function, arity} = __ENV__.function
IO.warn String.trim_trailing("""
Dict.#{function}/#{arity} is deprecated since the Dict module is
deprecated; use the Map module for working with maps or the Keyword
module for working with keyword lists
""")
end
end

@spec keys(t) :: [key]
def keys(dict) do
warn_deprecated()
target(dict).keys(dict)
end

@spec values(t) :: [value]
def values(dict) do
warn_deprecated()
target(dict).values(dict)
end

@spec size(t) :: non_neg_integer
def size(dict) do
warn_deprecated()
target(dict).size(dict)
end

@spec has_key?(t, key) :: boolean
def has_key?(dict, key) do
warn_deprecated()
target(dict).has_key?(dict, key)
end

@spec get(t, key, value) :: value
def get(dict, key, default \\ nil) do
warn_deprecated()
target(dict).get(dict, key, default)
end

@spec get_lazy(t, key, (() -> value)) :: value
def get_lazy(dict, key, fun) do
warn_deprecated()
target(dict).get_lazy(dict, key, fun)
end

@spec get_and_update(t, key, (value -> {value, value})) :: {value, t}
def get_and_update(dict, key, fun) do
warn_deprecated()
target(dict).get_and_update(dict, key, fun)
end

@spec fetch(t, key) :: value
def fetch(dict, key) do
warn_deprecated()
target(dict).fetch(dict, key)
end

@spec fetch!(t, key) :: value | no_return
def fetch!(dict, key) do
warn_deprecated()
target(dict).fetch!(dict, key)
end

@spec put(t, key, value) :: t
def put(dict, key, val) do
warn_deprecated()
target(dict).put(dict, key, val)
end

@spec put_new(t, key, value) :: t
def put_new(dict, key, val) do
warn_deprecated()
target(dict).put_new(dict, key, val)
end

@spec put_new_lazy(t, key, (() -> value)) :: t
def put_new_lazy(dict, key, fun) do
warn_deprecated()
target(dict).put_new_lazy(dict, key, fun)
end

@spec delete(t, key) :: t
def delete(dict, key) do
warn_deprecated()
target(dict).delete(dict, key)
end

@spec merge(t, t) :: t
def merge(dict1, dict2) do
warn_deprecated()
target1 = target(dict1)
target2 = target(dict2)

Expand All @@ -278,6 +331,7 @@ defmodule Dict do

@spec merge(t, t, (key, value, value -> value)) :: t
def merge(dict1, dict2, fun) do
warn_deprecated()
target1 = target(dict1)
target2 = target(dict2)

Expand All @@ -296,46 +350,55 @@ defmodule Dict do

@spec pop(t, key, value) :: {value, t}
def pop(dict, key, default \\ nil) do
warn_deprecated()
target(dict).pop(dict, key, default)
end

@spec pop_lazy(t, key, (() -> value)) :: {value, t}
def pop_lazy(dict, key, fun) do
warn_deprecated()
target(dict).pop_lazy(dict, key, fun)
end

@spec update!(t, key, (value -> value)) :: t
def update!(dict, key, fun) do
warn_deprecated()
target(dict).update!(dict, key, fun)
end

@spec update(t, key, value, (value -> value)) :: t
def update(dict, key, initial, fun) do
warn_deprecated()
target(dict).update(dict, key, initial, fun)
end

@spec split(t, [key]) :: {t, t}
def split(dict, keys) do
warn_deprecated()
target(dict).split(dict, keys)
end

@spec drop(t, [key]) :: t
def drop(dict, keys) do
warn_deprecated()
target(dict).drop(dict, keys)
end

@spec take(t, [key]) :: t
def take(dict, keys) do
warn_deprecated()
target(dict).take(dict, keys)
end

@spec empty(t) :: t
def empty(dict) do
warn_deprecated()
target(dict).empty(dict)
end

@spec equal?(t, t) :: boolean
def equal?(dict1, dict2) do
warn_deprecated()
target1 = target(dict1)
target2 = target(dict2)

Expand All @@ -358,6 +421,7 @@ defmodule Dict do

@spec to_list(t) :: list
def to_list(dict) do
warn_deprecated()
target(dict).to_list(dict)
end

Expand Down
Loading

0 comments on commit 7482564

Please sign in to comment.