Skip to content

Commit

Permalink
Deprecate keywords, getter and list getter functionalities of defrecordp
Browse files Browse the repository at this point in the history
Those functionalities can still be simulated via pattern matching
and perform basic operations. The reason for this deprecation is
that we are starting to unify defrecord/defrecordp syntaxes, so
instead of doing a big change at once, we are first bringing them
to a common set of functionalities to easy migration in the future.
  • Loading branch information
José Valim committed Jan 21, 2014
1 parent 08d69e3 commit 04c8ca9
Show file tree
Hide file tree
Showing 5 changed files with 18 additions and 64 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,12 @@

* Deprecations
* [Kernel] `binary_to_term/1`, `binary_to_term/2`, `term_to_binary/1` and `term_to_binary/2` are deprecated in favor of their counterparts in the `:erlang` module
* [Record] Deprecate `to_keywords`, `getter` and `list getter` funtionalities in `defrecordp`

* Backwards incompatible changes
* [Kernel] Remove `**` from the list of allowed operators
* [Range] `Range` is no longer a record, instead use `first .. last` if you need pattern matching


# v0.12.2 (2014-01-15)

* Enhancements
Expand Down
15 changes: 3 additions & 12 deletions lib/elixir/lib/kernel.ex
Original file line number Diff line number Diff line change
Expand Up @@ -3026,22 +3026,13 @@ defmodule Kernel do
user() #=> { :user, "José", 25 }
user(age: 26) #=> { :user, "José", 26 }
# To get a field from the record
user(record, :name) #=> "José"
# To get many fields from the record
user(record, [:name, :age]) #=> ["José", 25]
# To get a field from the record use pattern matching
user(name: name) = user
name #=> "José"
# To update the record
user(record, age: 26) #=> { :user, "José", 26 }
# To convert the record to keywords
user(record) #=> [name: "José", age: 25]
# To match against the record
user(name: name) = record
name #=> "José"
By default, Elixir uses the record name as the first element of the tuple.
In some cases though, this might be undesirable and one can explicitly
define what the first element of the record should be:
Expand Down
10 changes: 7 additions & 3 deletions lib/elixir/lib/macro/env.ex
Original file line number Diff line number Diff line change
Expand Up @@ -81,12 +81,16 @@ defmodule Macro.Env do
def stacktrace(record) do
cond do
nil?(record.module) ->
[{ :elixir_compiler, :__FILE__, 1, location(record) }]
[{ :elixir_compiler, :__FILE__, 1, relative_location(record) }]
nil?(record.function) ->
[{ module(record), :__MODULE__, 0, location(record) }]
[{ module(record), :__MODULE__, 0, relative_location(record) }]
true ->
{ name, arity } = record.function
[{ module(record), name, arity, location(record) }]
[{ module(record), name, arity, relative_location(record) }]
end
end

defp relative_location(record) do
[file: Path.relative_to_cwd(file(record)), line: line(record)]
end
end
11 changes: 7 additions & 4 deletions lib/elixir/lib/record.ex
Original file line number Diff line number Diff line change
Expand Up @@ -410,15 +410,15 @@ defmodule Record do
end

defmacrop unquote(name)(record) when is_tuple(record) do
Record.to_keywords(unquote(tag), unquote(escaped), record)
Record.to_keywords(unquote(name), unquote(tag), unquote(escaped), record, __CALLER__)
end

defmacrop unquote(name)(args) do
Record.access(unquote(tag), unquote(escaped), args, __CALLER__)
end

defmacrop unquote(name)(record, args) do
Record.dispatch(unquote(tag), unquote(escaped), record, args, __CALLER__)
Record.dispatch(unquote(name), unquote(tag), unquote(escaped), record, args, __CALLER__)
end
end

Expand Down Expand Up @@ -508,7 +508,8 @@ defmodule Record do
# It returns a quoted expression that represents
# converting record to keywords list.
@doc false
def to_keywords(_atom, fields, record) do
def to_keywords(name, _atom, fields, record, caller) do
IO.write "#{name}(record) for private records returning a keyword list is deprecated\n#{Exception.format_stacktrace(caller.stacktrace)}"
{ var, extra } = cache_var(record)

keywords = Enum.map fields,
Expand All @@ -527,13 +528,15 @@ defmodule Record do

# Dispatch the call to either get, update or to_list depending on the args given.
@doc false
def dispatch(atom, fields, record, args, caller) do
def dispatch(name, atom, fields, record, args, caller) do
cond do
is_atom(args) ->
IO.write "#{name}(record, field) for private records for retrieving a field is deprecated, please use pattern match instead\n#{Exception.format_stacktrace(caller.stacktrace)}"
get(atom, fields, record, args)
is_keyword(args) ->
update(atom, fields, record, args, caller)
is_list(args) ->
IO.write "#{name}(record, fields) for private records for retrieving a list of fields is deprecated, please use pattern match instead\n#{Exception.format_stacktrace(caller.stacktrace)}"
to_list(atom, fields, record, args)
true ->
raise ArgumentError, message: "expected arguments to be a compile time atom, list or keywords"
Expand Down
44 changes: 0 additions & 44 deletions lib/elixir/test/elixir/record/private_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -29,22 +29,6 @@ defmodule Record.PrivateTest do
_user(user, name: name <> " bar")
end

def age(user) do
_user(user, :age)
end

def to_keywords(user) do
_user(user)
end

def name_and_age(user) do
_user(user, [:name, :age])
end

def age_and_name(user) do
_user(user, [:age, :name])
end

def name_ix() do
_user(:name)
end
Expand All @@ -69,22 +53,6 @@ defmodule Record.PrivateTest do
_my_user(user, name: name <> " bar")
end

def my_age(user) do
_my_user(user, :age)
end

def my_to_keywords(user) do
_my_user(user)
end

def my_name_and_age(user) do
_my_user(user, [:name, :age])
end

def my_age_and_name(user) do
_my_user(user, [:age, :name])
end

def my_name_ix() do
_my_user(:name)
end
Expand Down Expand Up @@ -116,12 +84,6 @@ defmodule Record.PrivateTest do
record = Macros.my_add_bar_to_name(record)
assert Macros.my_name(record) == "Foo bar"

assert Macros.my_age(record) == 25
assert Macros.my_to_keywords(record) == [name: Macros.my_name(record), age: Macros.my_age(record)]

assert Macros.my_name_and_age(record) == [Macros.my_name(record), Macros.my_age(record)]
assert Macros.my_age_and_name(record) == [Macros.my_age(record), Macros.my_name(record)]

assert elem(record, 0) == :my_user
end

Expand All @@ -135,12 +97,6 @@ defmodule Record.PrivateTest do
record = record.add_bar_to_name
assert record.name == "Foo bar"

assert record.age == 25
assert record.to_keywords == [name: record.name, age: record.age]

assert record.name_and_age == [record.name, record.age]
assert record.age_and_name == [record.age, record.name]

assert elem(record, 0) == Macros
end

Expand Down

0 comments on commit 04c8ca9

Please sign in to comment.