From 3829e5facc98f1c1d3113b648c0b9fa7362cad32 Mon Sep 17 00:00:00 2001 From: Tuncer Ayaz Date: Tue, 20 Apr 2010 20:43:10 +0200 Subject: Support nested record field access without parentheses Original patch from YAMASHINA Hio posted to erlang-patches@ on Tue Jun 12 11:27:53 CEST 2007: http://www.erlang.org/pipermail/erlang-patches/2007-June/000182.html http://fleur.hio.jp/pub/erlang/record2.patch Only had to do minor changes to port the patch to the current R14A development tree. Also added compiler/record_SUITE:nested_access/2 to test nested record access with or without parentheses. With this change the following will work. -record(nrec0, {name = <<"nested0">>}). -record(nrec1, {name = <<"nested1">>, nrec0=#nrec0{}}). -record(nrec2, {name = <<"nested2">>, nrec1=#nrec1{}}). nested_access() -> N0 = #nrec0{}, N1 = #nrec1{}, N2 = #nrec2{}, <<"nested0">> = N0#nrec0.name, <<"nested1">> = N1#nrec1.name, <<"nested2">> = N2#nrec2.name, <<"nested0">> = N1#nrec1.nrec0#nrec0.name, <<"nested0">> = N2#nrec2.nrec1#nrec1.nrec0#nrec0.name, <<"nested1">> = N2#nrec2.nrec1#nrec1.name, <<"nested0">> = ((N2#nrec2.nrec1)#nrec1.nrec0)#nrec0.name, N1a = N2#nrec2.nrec1#nrec1{name = <<"nested1a">>}, <<"nested1a">> = N1a#nrec1.name, N2a = N2#nrec2.nrec1#nrec1.nrec0#nrec0{name = <<"nested0a">>}, N2b = ((N2#nrec2.nrec1)#nrec1.nrec0)#nrec0{name = <<"nested0a">>}, <<"nested0a">> = N2a#nrec0.name, N2a = N2b, ok. Signed-off-by: Tuncer Ayaz --- lib/compiler/test/record_SUITE.erl | 39 +++++++++++++++++++++++++++++++------- lib/stdlib/src/erl_parse.yrl | 4 ++++ 2 files changed, 36 insertions(+), 7 deletions(-) diff --git a/lib/compiler/test/record_SUITE.erl b/lib/compiler/test/record_SUITE.erl index bd2ffd7f65..f26ff769c7 100644 --- a/lib/compiler/test/record_SUITE.erl +++ b/lib/compiler/test/record_SUITE.erl @@ -1,19 +1,19 @@ %% %% %CopyrightBegin% -%% -%% Copyright Ericsson AB 2003-2009. All Rights Reserved. -%% +%% +%% Copyright Ericsson AB 2003-2010. All Rights Reserved. +%% %% The contents of this file are subject to the Erlang Public License, %% Version 1.1, (the "License"); you may not use this file except in %% compliance with the License. You should have received a copy of the %% Erlang Public License along with this software. If not, it can be %% retrieved online at http://www.erlang.org/. -%% +%% %% Software distributed under the License is distributed on an "AS IS" %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See %% the License for the specific language governing rights and limitations %% under the License. -%% +%% %% %CopyrightEnd% %% %%% Purpose : Test records. @@ -24,7 +24,7 @@ -export([all/1,init_per_testcase/2,fin_per_testcase/2, errors/1,record_test_2/1,record_test_3/1,record_access_in_guards/1, - guard_opt/1,eval_once/1,foobar/1,missing_test_heap/1]). + guard_opt/1,eval_once/1,foobar/1,missing_test_heap/1, nested_access/1]). init_per_testcase(_Case, Config) -> ?line Dog = test_server:timetrap(test_server:minutes(2)), @@ -38,7 +38,7 @@ fin_per_testcase(_Case, Config) -> all(suite) -> test_lib:recompile(?MODULE), [errors,record_test_2,record_test_3,record_access_in_guards, - guard_opt,eval_once,foobar,missing_test_heap]. + guard_opt,eval_once,foobar,missing_test_heap,nested_access]. -record(foo, {a,b,c,d}). -record(bar, {a,b,c,d}). @@ -522,4 +522,29 @@ missing_test_heap_1(A = #foo_rec {foo_1 = _B, foo_3 = C + 1, foo_2 = D + 1}. +-record(nrec0, {name = <<"nested0">>}). +-record(nrec1, {name = <<"nested1">>, nrec0=#nrec0{}}). +-record(nrec2, {name = <<"nested2">>, nrec1=#nrec1{}}). + +nested_access(Config) when is_list(Config) -> + N0 = #nrec0{}, + N1 = #nrec1{}, + N2 = #nrec2{}, + ?line <<"nested0">> = N0#nrec0.name, + ?line <<"nested1">> = N1#nrec1.name, + ?line <<"nested2">> = N2#nrec2.name, + ?line <<"nested0">> = N1#nrec1.nrec0#nrec0.name, + ?line <<"nested0">> = N2#nrec2.nrec1#nrec1.nrec0#nrec0.name, + ?line <<"nested1">> = N2#nrec2.nrec1#nrec1.name, + ?line <<"nested0">> = ((N2#nrec2.nrec1)#nrec1.nrec0)#nrec0.name, + + N1a = N2#nrec2.nrec1#nrec1{name = <<"nested1a">>}, + ?line <<"nested1a">> = N1a#nrec1.name, + + N2a = N2#nrec2.nrec1#nrec1.nrec0#nrec0{name = <<"nested0a">>}, + N2b = ((N2#nrec2.nrec1)#nrec1.nrec0)#nrec0{name = <<"nested0a">>}, + ?line <<"nested0a">> = N2a#nrec0.name, + ?line N2a = N2b, + ok. + id(I) -> I. diff --git a/lib/stdlib/src/erl_parse.yrl b/lib/stdlib/src/erl_parse.yrl index 7145cf13fd..69807aad83 100644 --- a/lib/stdlib/src/erl_parse.yrl +++ b/lib/stdlib/src/erl_parse.yrl @@ -335,6 +335,10 @@ record_expr -> expr_max '#' atom '.' atom : {record_field,?line('$2'),'$1',element(3, '$3'),'$5'}. record_expr -> expr_max '#' atom record_tuple : {record,?line('$2'),'$1',element(3, '$3'),'$4'}. +record_expr -> record_expr '#' atom '.' atom : + {record_field,?line('$2'),'$1',element(3, '$3'),'$5'}. +record_expr -> record_expr '#' atom record_tuple : + {record,?line('$2'),'$1',element(3, '$3'),'$4'}. record_tuple -> '{' '}' : []. record_tuple -> '{' record_fields '}' : '$2'. -- cgit v1.2.3 From 45c380d1b77198449fb8e3beadb39dc8f77abb72 Mon Sep 17 00:00:00 2001 From: Tuncer Ayaz Date: Tue, 20 Apr 2010 20:44:45 +0200 Subject: Document R14 paren-less record access/update Add a section to the reference manual describing the R14 change to not require parentheses when accessing or updating fields in nested records. Signed-off-by: Tuncer Ayaz --- system/doc/reference_manual/records.xml | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/system/doc/reference_manual/records.xml b/system/doc/reference_manual/records.xml index e2fe5fe8de..e901b7bccf 100644 --- a/system/doc/reference_manual/records.xml +++ b/system/doc/reference_manual/records.xml @@ -144,6 +144,29 @@ is_person(_P) -> unbound variables.

+
+ Nested records +

Beginning with R14 parentheses when accessing or updating nested + records can be omitted. Assuming we have the following record + definitions:

+
+-record(nrec0, {name = "nested0"}).
+-record(nrec1, {name = "nested1", nrec0=#nrec0{}}).
+-record(nrec2, {name = "nested2", nrec1=#nrec1{}}).
+
+N2 = #nrec2{},
+    
+

Before R14 you would have needed to use parentheses as following:

+
+"nested0" = ((N2#nrec2.nrec1)#nrec1.nrec0)#nrec0.name,
+N0n = ((N2#nrec2.nrec1)#nrec1.nrec0)#nrec0{name = "nested0a"},
+    
+

Since R14 you can also write:

+
+"nested0" = N2#nrec2.nrec1#nrec1.nrec0#nrec0.name,
+N0n = N2#nrec2.nrec1#nrec1.nrec0#nrec0{name = "nested0a"},
+
+
Internal Representation of Records

Record expressions are translated to tuple expressions during -- cgit v1.2.3