Skip to content

Commit 04c8ca9

Browse files
author
José Valim
committed
Deprecate keywords, getter and list getter functionalities of defrecordp
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.
1 parent 08d69e3 commit 04c8ca9

File tree

5 files changed

+18
-64
lines changed

5 files changed

+18
-64
lines changed

CHANGELOG.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,12 @@
88

99
* Deprecations
1010
* [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
11+
* [Record] Deprecate `to_keywords`, `getter` and `list getter` funtionalities in `defrecordp`
1112

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

16-
1717
# v0.12.2 (2014-01-15)
1818

1919
* Enhancements

lib/elixir/lib/kernel.ex

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3026,22 +3026,13 @@ defmodule Kernel do
30263026
user() #=> { :user, "José", 25 }
30273027
user(age: 26) #=> { :user, "José", 26 }
30283028
3029-
# To get a field from the record
3030-
user(record, :name) #=> "José"
3031-
3032-
# To get many fields from the record
3033-
user(record, [:name, :age]) #=> ["José", 25]
3029+
# To get a field from the record use pattern matching
3030+
user(name: name) = user
3031+
name #=> "José"
30343032
30353033
# To update the record
30363034
user(record, age: 26) #=> { :user, "José", 26 }
30373035
3038-
# To convert the record to keywords
3039-
user(record) #=> [name: "José", age: 25]
3040-
3041-
# To match against the record
3042-
user(name: name) = record
3043-
name #=> "José"
3044-
30453036
By default, Elixir uses the record name as the first element of the tuple.
30463037
In some cases though, this might be undesirable and one can explicitly
30473038
define what the first element of the record should be:

lib/elixir/lib/macro/env.ex

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -81,12 +81,16 @@ defmodule Macro.Env do
8181
def stacktrace(record) do
8282
cond do
8383
nil?(record.module) ->
84-
[{ :elixir_compiler, :__FILE__, 1, location(record) }]
84+
[{ :elixir_compiler, :__FILE__, 1, relative_location(record) }]
8585
nil?(record.function) ->
86-
[{ module(record), :__MODULE__, 0, location(record) }]
86+
[{ module(record), :__MODULE__, 0, relative_location(record) }]
8787
true ->
8888
{ name, arity } = record.function
89-
[{ module(record), name, arity, location(record) }]
89+
[{ module(record), name, arity, relative_location(record) }]
9090
end
9191
end
92+
93+
defp relative_location(record) do
94+
[file: Path.relative_to_cwd(file(record)), line: line(record)]
95+
end
9296
end

lib/elixir/lib/record.ex

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -410,15 +410,15 @@ defmodule Record do
410410
end
411411

412412
defmacrop unquote(name)(record) when is_tuple(record) do
413-
Record.to_keywords(unquote(tag), unquote(escaped), record)
413+
Record.to_keywords(unquote(name), unquote(tag), unquote(escaped), record, __CALLER__)
414414
end
415415

416416
defmacrop unquote(name)(args) do
417417
Record.access(unquote(tag), unquote(escaped), args, __CALLER__)
418418
end
419419

420420
defmacrop unquote(name)(record, args) do
421-
Record.dispatch(unquote(tag), unquote(escaped), record, args, __CALLER__)
421+
Record.dispatch(unquote(name), unquote(tag), unquote(escaped), record, args, __CALLER__)
422422
end
423423
end
424424

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

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

528529
# Dispatch the call to either get, update or to_list depending on the args given.
529530
@doc false
530-
def dispatch(atom, fields, record, args, caller) do
531+
def dispatch(name, atom, fields, record, args, caller) do
531532
cond do
532533
is_atom(args) ->
534+
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)}"
533535
get(atom, fields, record, args)
534536
is_keyword(args) ->
535537
update(atom, fields, record, args, caller)
536538
is_list(args) ->
539+
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)}"
537540
to_list(atom, fields, record, args)
538541
true ->
539542
raise ArgumentError, message: "expected arguments to be a compile time atom, list or keywords"

lib/elixir/test/elixir/record/private_test.exs

Lines changed: 0 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -29,22 +29,6 @@ defmodule Record.PrivateTest do
2929
_user(user, name: name <> " bar")
3030
end
3131

32-
def age(user) do
33-
_user(user, :age)
34-
end
35-
36-
def to_keywords(user) do
37-
_user(user)
38-
end
39-
40-
def name_and_age(user) do
41-
_user(user, [:name, :age])
42-
end
43-
44-
def age_and_name(user) do
45-
_user(user, [:age, :name])
46-
end
47-
4832
def name_ix() do
4933
_user(:name)
5034
end
@@ -69,22 +53,6 @@ defmodule Record.PrivateTest do
6953
_my_user(user, name: name <> " bar")
7054
end
7155

72-
def my_age(user) do
73-
_my_user(user, :age)
74-
end
75-
76-
def my_to_keywords(user) do
77-
_my_user(user)
78-
end
79-
80-
def my_name_and_age(user) do
81-
_my_user(user, [:name, :age])
82-
end
83-
84-
def my_age_and_name(user) do
85-
_my_user(user, [:age, :name])
86-
end
87-
8856
def my_name_ix() do
8957
_my_user(:name)
9058
end
@@ -116,12 +84,6 @@ defmodule Record.PrivateTest do
11684
record = Macros.my_add_bar_to_name(record)
11785
assert Macros.my_name(record) == "Foo bar"
11886

119-
assert Macros.my_age(record) == 25
120-
assert Macros.my_to_keywords(record) == [name: Macros.my_name(record), age: Macros.my_age(record)]
121-
122-
assert Macros.my_name_and_age(record) == [Macros.my_name(record), Macros.my_age(record)]
123-
assert Macros.my_age_and_name(record) == [Macros.my_age(record), Macros.my_name(record)]
124-
12587
assert elem(record, 0) == :my_user
12688
end
12789

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

138-
assert record.age == 25
139-
assert record.to_keywords == [name: record.name, age: record.age]
140-
141-
assert record.name_and_age == [record.name, record.age]
142-
assert record.age_and_name == [record.age, record.name]
143-
144100
assert elem(record, 0) == Macros
145101
end
146102

0 commit comments

Comments
 (0)