[Erlang 0006] record and macro in Erlang

Source: Internet
Author: User

When tuple is used in Erlang, the order and quantity of data items are determined. Once the order of data items is adjusted or the field is increased or decreased, badmatch is easy to appear.

At the same time, if some constants are hard-coded into the Code, once the value changes, it is difficult to replace them with new ones reliably.

The corresponding solutions in Erlang are as follows:Record macro

Record

In the code, we create a record:-record (man, {name, age = 0, school }).

16:11:04 update

Note that the following code is truncated from the Erl file.Code snippetTo use record in Erlang shell, see [Erlang 0027] using record in Erlang shell.

 

The following code shows the default values of the corresponding fields:

% See Default Value

M = # Man {},

IO: Format ("m is :~ P ~ N ", [m]),

We can see that the output m value is {MAN, undefined, 0, undefined}. In fact, from here we can see whether the internal implementation of record in Erlang is a tuple.

From the perspective of pure data, we find that {MAN, undefined, 0, undefined} = m, but record itself is a data abstraction mechanism. We do not directly record the tuple value form.

 

 

Let's assign values to specific fields, and then look:

M2 = # man {name = "Zen", age = 23, school = "no.14"}, IO: Format ("M2 is :~ P ~ N ", [m2]),

The output is m2 is: {Man, "Zen", 23, "no.14 "}

 

 

Using m2 data as a template, you can generate a new record:

M3 = m2 # man {name = "TT", age = 24}, IO: Format ("M3 is :~ P ~ N ", [m3]),

Result: M3 is: {Man, "TT", 24, "No. 14 "}

You can also use the data template as follows:

Birthday (m) When is_record (M, man)-> M # man {age = m # Man. Age + 1 }.

14:39:43 update

Blog garden-beach 14:07:08
There is a record list with the fields a, B, c, such as {user, a, B, c}. Now we want to use its list to generate another record list, its field is {user1, B, c}. How to Write it most conveniently?
User1 is a field less than user.
Strong ☆2002 14:39:00
Eshell V5.9  (abort with ^G)1> rd(u1,{a,b,c}).u12> rd(u2,{b,c}).u23> Users=[#u1{a=12,b="ligaoren",c=true},#u1{a=23,b="zen",c=false}].[#u1{a = 12,b = "ligaoren",c = true}, #u1{a = 23,b = "zen",c = false}]4> [begin #u1{b=B,c=C}=U, #u2{b=B,c=C} end|| U<-Users].[#u2{b = "ligaoren",c = true},#u2{b = "zen",c = false}]5>  

 

 

The following example shows how to set a value:

M4 = # man {name = "TT2", age = m3 # Man. Age}, IO: Format ("M4 is :~ P ~ N ", [M4]),

Result: M4 is: {Man, "TT2", 24, undefined}

 

 

We try to nest a record to man. Let's extend the name field:

-Record (name, {firstname, lastname }).

We use M2 as the data template to generate M5 and try to get the value of firstname:

M5 = m2 # man {name = # name {firstname = "K", lastname = "J"}, age = 24}, IO: Format ("M5 is :~ P ~ N ", [M5]),

IO: Format ("M5 firstname is :~ P ~ N ", [M5 # Man. name # name. firstname])

 

 

Matching is everywhere in Erlang. When using record, we can extract the values of some fields by matching:

For example, this method:

Show2 (# man {name = Name, age = age} = m) When is_record (M, man)->

IO: Format ("Name :~ P age :~ P ~ N ", [name, age]).

This method extracts the name and age from the entry. Note that only M is a record man, so we have added GUARD: is_record (M, man)

 

 

The above are some general operations on record. I will have some questions: in actual use of record, we often encounter badrecord errors. How does Erlang determine this error?

How is the same is_record determined? To understand this answer, we need to recompile our test file, add compilation options, and use the following method in Erlang shell:

C (test, ['E']). in this way, a test is generated in the same directory. E file, open this file, everything suddenly becomes open, we use m3 = m2 # man {name = "TT", age = 24 },

IO: Format ("M3 is :~ P ~ N ", [m3]). The compiled code is as follows:

M3 =
Begin
Rec1 = m2,
Case rec1
{Man, rec2, rec3, rec4}-> % is determined by matching tuple.
{Man, "TT", 24, rec4 };
_->
Error ({badrecord, man })
End
End,
IO: Format ("M3 is :~ P ~ N ", [m3]),

 

Let's take a look at the corresponding code generated by show2 in the previous section:

Show2 ({MAN, name, age, _ }= {MAN, _} = m) When true-> IO: Format ("Name :~ P age :~ P ~ N ", [name, age]).

Here is a matching value, which will affect our reading. Let's simplify it:

Show (m) When is_record (M, man)-> IO: Format ("show M :~ P ~ N ", [m]).

The compiled code is:

Show ({MAN, _} = m) When true->

IO: Format ("show M :~ P ~ N ", [m]).

Macro 

It is hard to imagine how hard our Erlang code is to read without macros. Magic number is everywhere. A brief summary of the usage of Macros in Erlang:

  1. Constant macros such as-define (timeout, 1000).-Define (servername, my_first_game_server ).
  2. Macro with parameters such as-define (eq (x, y), x =: = Y ).
    -Define (P (content), OK ).
  3. Conditional macros
    -Ifdef (product ).
    -Define (WHO, "product_db_adm ").
    -Else.
    -Define (WHO, "test_db_adm ").
    -Endif.
  4. Global Macro :? Machine (Vm name)
    ? Line Current code line
    ? File current code file
    What else are you most familiar? Module current Module
    There is also a macro commonly used to output debugging information:
    -Define (value (CALL), IO: Format ("~ P = ~ P ~ N ",[?? Call, call]).
    Test1 ()->? Value (length ([1, 2, 3]).

    Updated on May 16

  5. {D, macro}{D, Macro, value}

    Defines a macro to have the value. The default is true.

    Example:

    -module(m)....-ifdef(debug).-define(LOG(X), io:format("{~p,~p}: ~p~n", [?MODULE,?LINE,X])).-else.-define(LOG(X), true).-endif....

     

    When trace output is desired, debug shocould be defined when the module M is compiled:

    % erlc -Ddebug m.erlor1> c(m, {d, debug}).{ok,m}

     

    Official Document address:Http://www.erlang.org/doc/man/compile.html

    Http://www.erlang.org/doc/reference_manual/macros.html

Conditional macros can be compiled by selecting the production environment version or debug version. The production environment can be easily implemented by shielding the debug output;

 

In the same way, let's take a look at macro. You only need to use C (test, ['P']) during compilation. the following is an example of macro usage. Guess what it looks like after it is compiled?

View code

-module(mac).

-export([dump/1,go/1,show/2,len/1,say/0]).

-define(Func,X).
-define(Double,*2).
-define(F,dump(X)).
-define(Eq(X,Y),X=:=Y).
%-define(P(Content),ok).
-define(PF(Content,Args),io:format(Content,Args)).
-define(P(Content),io:format(Content)).

-define(Len(Call),io:format("~p=~p ~n",[??Call,Call])).

-ifdef(me).
-define(Who,"abcd").
-else.
-define(Who,"zen").
-endif.



say()->
?P(?Who).


len(List) when is_list(List) ->
?Len(length(List)).



dump(X)->
?Func?Double.

go(X)->
?F.

show(X,Y) when ?Eq(X,Y)->
?P("They are Equal. ~n");
show(_X,_Y)->
io:format("HAHA").

The generated P file is here:

View code

-file("./mac.erl", 1).

-module(mac).

-export([dump/1,go/1,show/2,len/1,say/0]).

say() ->
io:format("zen").

len(List) when is_list(List) ->
io:format("~p=~p ~n", ["length ( List )",length(List)]).

dump(X) ->
X * 2.

go(X) ->
dump(X).

show(X, Y) when X =:= Y ->
io:format("They are Equal. ~n");
show(_X, _Y) ->
io:format("HAHA").

 

In projects, these record macro files are often placed in HRL files and compiled and customized using emakefile. We have discussed this before and will not repeat it here;

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.