@@ -139,6 +139,10 @@ defmodule Record do
139
139
records flexibility at the cost of performance since
140
140
there is more work happening at runtime.
141
141
142
+ The above calls (new and update) can interchangeably accept both
143
+ atom and string keys for field names. Please note, however, that
144
+ atom keys are faster.
145
+
142
146
To sum up, `defrecordp` should be used when you don't want
143
147
to expose the record information while `defrecord` should be used
144
148
whenever you want to share a record within your code or with other
@@ -625,7 +629,17 @@ defmodule Record do
625
629
# the given key from the ordered dict, falling back to the
626
630
# default value if one does not exist.
627
631
selective = lc { k, v } inlist values do
628
- quote do: Keyword.get(opts, unquote(k), unquote(v))
632
+ string_k = atom_to_binary(k)
633
+ quote do
634
+ case :lists.keyfind(unquote(k), 1, opts) do
635
+ false ->
636
+ case :lists.keyfind(unquote(string_k), 1, opts) do
637
+ false -> unquote(v)
638
+ {_, value} -> value
639
+ end
640
+ {_, value} -> value
641
+ end
642
+ end
629
643
end
630
644
631
645
quote do
@@ -727,9 +741,17 @@ defmodule Record do
727
741
defp updater(values) do
728
742
fields =
729
743
lc {key, _default} inlist values do
744
+ string_key = atom_to_binary(key)
730
745
index = find_index(values, key, 1)
731
746
quote do
732
- Keyword.get(keywords, unquote(key), elem(record, unquote(index)))
747
+ case :lists.keyfind(unquote(key), 1, keywords) do
748
+ false ->
749
+ case :lists.keyfind(unquote(string_key), 1, keywords) do
750
+ false -> elem(record, unquote(index))
751
+ {_, value} -> value
752
+ end
753
+ {_, value} -> value
754
+ end
733
755
end
734
756
end
735
757
@@ -765,14 +787,15 @@ defmodule Record do
765
787
defp core_specs(values) do
766
788
types = lc { _, _, spec } inlist values, do: spec
767
789
options = if values == [], do: [], else: [options_specs(values)]
790
+ values_specs = if values == [], do: [], else: values_specs(values)
768
791
769
792
quote do
770
793
unless Kernel.Typespec.defines_type?(__MODULE__, :t, 0) do
771
794
@type t :: { __MODULE__, unquote_splicing(types) }
772
795
end
773
796
774
797
unless Kernel.Typespec.defines_type?(__MODULE__, :options, 0) do
775
- @type options :: unquote(options)
798
+ @type options :: unquote(options) | [{String.t, unquote(values_specs)}]
776
799
end
777
800
778
801
@spec new :: t
@@ -790,6 +813,11 @@ defmodule Record do
790
813
{ :|, [], [{ k, v }, acc] }
791
814
end, { k, v }, t
792
815
end
816
+ defp values_specs([{ _, _, v }|t]) do
817
+ :lists.foldl fn { _, _, v }, acc ->
818
+ { :|, [], [v, acc] }
819
+ end, v, t
820
+ end
793
821
794
822
defp accessor_specs([{ :__exception__, _, _ }|t], 1, acc) do
795
823
accessor_specs(t, 2, acc)
0 commit comments