get_line function for reading lines of text from an IoDevice?. The following are some useful procedures which use get_line to make it easy to process an entire file, one line at a time. This code was adapted from the comp.lang.scheme thread,
How to read lines from a text file.
for_each_line_in_file(Name, Proc, Mode, Accum0) ->
{ok, Device} = file:open(Name, Mode),
for_each_line(Device, Proc, Accum0).
for_each_line(Device, Proc, Accum) ->
case io:get_line(Device, "") of
eof -> file:close(Device), Accum;
Line -> NewAccum = Proc(Line, Accum),
for_each_line(Device, Proc, NewAccum)
end. |
mode parameters, see the
Erlang file module documentation.
complex.erl, with line numbers.
1> A = for_each_line_in_file("complex.erl",
1> fun(X, Count) -> io:fwrite("~10B: ~s", [Count, X]),
1> Count + 1 end, 0, [read]). |
0: -module(complex).
1: -export([make/2, is_complex/1, add/2, sub/2, mult/2, divide/2,
2: get_real/1, get_imaginary/1]).
3:
4: -record( complex, {real, imaginary}).
5:
6: is_complex(X) when record(X, complex) -> true;
7: is_complex(_) -> false.
8:
[ ... ]
40: ((A#complex.imaginary * B#complex.real)
41: - (A#complex.real * B#complex.imaginary)) / Divisor).
42:
43: get_real(X) -> X#complex.real.
44:
45: get_imaginary(X) -> X#complex.imaginary.
ok |
for_each_line helper function, and the user-supplied function is expected to accept an accumulator (or in this case, a count) variable that holds the current state.
This general pattern is called a fold, which is a functional generalization of iteration. There are many such examples in the Erlang distribution, such as the canonical lists:foldl function for folding over lists.
| CookbookForm | |
|---|---|
| TopicType: | Recipe |
| ParentTopic: | FileRecipes |
| TopicOrder: | 040 |