Erlang basics · Lesson 21 (open contents)
01 · Open erl02 · Meet common terms03 · Tell two kinds of text apart04 · Bind a variable once05 · Split and filter a list06 · Parse a number safely07 · Choose one path with case08 · Let a function keep going09 · Put code in a module10 · Compare terms and Boolean results11 · Read and update nested maps12 · Build and inspect UTF-8 binaries13 · Let clauses choose the function path14 · Solve a list twice15 · Choose with patterns, guards, and errors16 · Describe a module and one record17 · Put one tested module in Rebar318 · Return success or failure as data19 · Read and write one file safely20 · Build a data pipeline with functions21 · Keep records behind a module boundary22 · Define a module contract23 · Describe the data contract24 · Test small rules and whole flows25 · Shape builds and make a command26 · Write the project promise27 · Parse one real line28 · Keep the public API small29 · Make the promise executable30 · Package the edge and leave clues31 · Prove the project is done
ERLANG · INTERMEDIATE · LESSON 2125 minutes

Keep records behind a module boundary

Use a record internally and return a public map to callers.

01 · Start with the whole example

Run this first

Run it once, change one input, and compare the new result.

Erlang
%% Keep this record inside its owning module
-record(user, {name, age = 0}).

public(#user{name = Name, age = Age}) ->
  #{name => Name, age => Age}.
Check the result first
  • Calling public/1 inside the module returns a map such as #{name => <<"Maya">>,age => 12}.
02 · Take the code apart

Read from the first line down

  1. Read #user{}: Construct or match the private record.
  2. Read Record#user.name: Read one record field.
  3. Read #{key => value}: Return a public map.
03 · Meet the new symbols

Symbols are not secret signs

#user{}

Construct or match the private record.

Record#user.name

Read one record field.

#{key => value}

Return a public map.

04 · Ideas inside the code

Match each name to its meaning

01

record

A record gives compile-time names to tuple positions inside modules that share its definition.

02

public boundary

A public boundary is the data shape other modules are allowed to depend on.

03

conversion

Converting a private record to a map prevents callers from depending on tuple layout.

05 · Make the idea clear

Why these forms are useful

Run the example first. Predict one result, then change one input and run it again.

A record gives compile-time names to tuple positions inside modules that share its definition.

A public boundary is the data shape other modules are allowed to depend on.

06 · Change it yourself

Close the answer and try

Hide age and expose only the name.

Practice starting point
public(#user{name = Name}) -> #{____ => Name}.

Target result: Return a map with the name key.

Stuck? Read one hint

Use the atom name.

After you run it, see one answer
One answer
public(#user{name = Name}) -> #{name => Name}.
Think about it: Why not return a record from a public API?

Records compile to tuples, so changing a field can silently change the tuple layout expected by callers.

Take with you

Remember these three lines

  1. 1

    Treat records as private structure.

  2. 2

    Use stable public data shapes.

  3. 3

    Convert at module boundaries.

Lesson completeRun the code once, then mark this lesson as done.