Erlang basics · Lesson 28 (open contents)
Keep the public API small
Separate file access, parsing, and pure summary logic.
Run this first
Run it once, change one input, and compare the new result.
%% Export a small parser and one summary call
-module(cleaner).
-export([run/1, parse_line/1]).
run(Records) -> {ok, count(Records)}.
parse_line(Line) ->
case binary:split(string:trim(Line), <<" ">>, [trim]) of
[] -> skip;
[<<"INFO">>, Message] -> {ok, {info, Message}};
[<<"WARN">>, Message] -> {ok, {warn, Message}};
[<<"ERROR">>, Message] -> {ok, {error, Message}};
_ -> {error, invalid_line}
end.
count(Records) ->
lists:foldl(fun({Level, _}, Acc) ->
maps:update_with(Level, fun(N) -> N + 1 end, 1, Acc)
end, #{}, Records).cleaner:run([{info,<<"ready">>},{info,<<"done">>}])returns{ok,#{info => 2}}.
Read from the first line down
- Read
-export([run/1]).: Expose one project entry point. - Read
count/1: Keep an unexported helper private. - Read
maps:update_with/4: Update one count in a map.
Symbols are not secret signs
-export([run/1]).Expose one project entry point.
count/1Keep an unexported helper private.
maps:update_with/4Update one count in a map.
Match each name to its meaning
public API
A small public API gives callers fewer contracts and protects internal changes.
pure core
Pure functions transform supplied data without opening files or changing outside state.
boundary module
A boundary performs IO and turns its failures into project results.
Why these forms are useful
Run the example first. Predict one result, then change one input and run it again.
A small public API gives callers fewer contracts and protects internal changes.
Pure functions transform supplied data without opening files or changing outside state.
Close the answer and try
Add a public total/1 function.
total(Records) -> ____.Target result: Return the list length.
Stuck? Read one hint
Use length/1 and remember to export the function.
After you run it, see one answer
total(Records) -> length(Records).Think about it: Can callers invoke `count/1`?
No. It is not exported, so the module can change that helper without changing its public API.
Remember these three lines
- 1
Export a narrow API.
- 2
Keep transformations pure.
- 3
Put IO and error conversion at boundaries.