7
7
8
8
defmodule IO do
9
9
@ moduledoc """
10
- Module responsible for doing IO. Many functions in this
11
- module expects an IO device and an io data encoded in UTF-8.
12
- Use the bin* functions if the data is binary, useful when
13
- working with raw bytes or when no unicode conversion should
14
- be performed.
10
+ Functions handling IO.
15
11
12
+ Many functions in this module expects an IO device as argument.
16
13
An IO device must be a pid or an atom representing a process.
17
14
For convenience, Elixir provides `:stdio` and `:stderr` as
18
15
shortcuts to Erlang's `:standard_io` and `:standard_error`.
19
16
20
- An io data can be:
17
+ The majority of the functions expect data encoded in UTF-8
18
+ and will do a conversion to string, via the `String.Chars`
19
+ protocol (as shown in typespecs).
21
20
22
- * A list of integers representing a string. Any unicode
23
- character must be represented with one entry in the list,
24
- this entry being an integer with the codepoint value;
25
-
26
- * A binary in which unicode characters are represented
27
- with many bytes (Elixir's default representation);
28
-
29
- * A list of binaries or a list of char lists (as described above);
21
+ The functions starting with `bin*` expects iodata as arguments,
22
+ i.e. iolists or binaries with no particular encoding.
30
23
31
24
"""
32
25
26
+ @ type device :: atom | pid
27
+ @ type chardata :: char_list | String.Chars . t
28
+ @ type nodata :: { :error , term } | :eof
29
+
33
30
import :erlang , only: [ group_leader: 0 ]
34
31
35
32
defmacrop is_iolist ( data ) do
@@ -50,6 +47,7 @@ defmodule IO do
50
47
for instance `{:error, :estale}` if reading from an
51
48
NFS file system.
52
49
"""
50
+ @ spec read ( device , :line | non_neg_integer ) :: chardata | nodata
53
51
def read ( device // group_leader , chars_or_line )
54
52
55
53
def read ( device , :line ) do
@@ -72,6 +70,7 @@ defmodule IO do
72
70
for instance `{:error, :estale}` if reading from an
73
71
NFS file system.
74
72
"""
73
+ @ spec binread ( device , :line | non_neg_integer ) :: iodata | nodata
75
74
def binread ( device // group_leader , chars_or_line )
76
75
77
76
def binread ( device , :line ) do
@@ -105,8 +104,9 @@ defmodule IO do
105
104
#=> "error"
106
105
107
106
"""
108
- def write ( device // group_leader ( ) , item ) when is_iolist ( item ) do
109
- :io . put_chars map_dev ( device ) , item
107
+ @ spec write ( device , chardata ) :: :ok
108
+ def write ( device // group_leader ( ) , item ) do
109
+ :io . put_chars map_dev ( device ) , to_chardata ( item )
110
110
end
111
111
112
112
@ doc """
@@ -115,6 +115,7 @@ defmodule IO do
115
115
116
116
Check `write/2` for more information.
117
117
"""
118
+ @ spec binwrite ( device , iodata ) :: :ok | { :error , term }
118
119
def binwrite ( device // group_leader ( ) , item ) when is_iolist ( item ) do
119
120
:file . write map_dev ( device ) , item
120
121
end
@@ -124,9 +125,10 @@ defmodule IO do
124
125
but adds a newline at the end. The argument is expected
125
126
to be a chardata.
126
127
"""
127
- def puts ( device // group_leader ( ) , item ) when is_iolist ( item ) do
128
+ @ spec puts ( device , chardata ) :: :ok
129
+ def puts ( device // group_leader ( ) , item ) do
128
130
erl_dev = map_dev ( device )
129
- :io . put_chars erl_dev , [ item , ?\n ]
131
+ :io . put_chars erl_dev , [ to_chardata ( item ) , ?\n ]
130
132
end
131
133
132
134
@ doc """
@@ -142,13 +144,15 @@ defmodule IO do
142
144
IO.inspect Process.list
143
145
144
146
"""
147
+ @ spec inspect ( term , Keyword . t ) :: term
145
148
def inspect ( item , opts // [ ] ) do
146
149
inspect group_leader ( ) , item , opts
147
150
end
148
151
149
152
@ doc """
150
153
Inspects the item with options using the given device.
151
154
"""
155
+ @ spec inspect ( device , term , Keyword . t ) :: term
152
156
def inspect ( device , item , opts ) when is_list ( opts ) do
153
157
opts = Keyword . put_new ( opts , :pretty , true )
154
158
@@ -178,6 +182,8 @@ defmodule IO do
178
182
for instance `{:error, :estale}` if reading from an
179
183
NFS file system.
180
184
"""
185
+ @ spec getn ( chardata , pos_integer ) :: chardata | nodata
186
+ @ spec getn ( device , chardata ) :: chardata | nodata
181
187
def getn ( prompt , count // 1 )
182
188
183
189
def getn ( prompt , count ) when is_integer ( count ) do
@@ -194,8 +200,9 @@ defmodule IO do
194
200
the number of unicode codepoints to be retrieved.
195
201
Otherwise, `count` is the number of raw bytes to be retrieved.
196
202
"""
203
+ @ spec getn ( device , chardata , pos_integer ) :: chardata | nodata
197
204
def getn ( device , prompt , count ) do
198
- :io . get_chars ( map_dev ( device ) , prompt , count )
205
+ :io . get_chars ( map_dev ( device ) , to_chardata ( prompt ) , count )
199
206
end
200
207
201
208
@ doc """
@@ -210,8 +217,9 @@ defmodule IO do
210
217
for instance `{:error, :estale}` if reading from an
211
218
NFS file system.
212
219
"""
220
+ @ spec gets ( device , chardata ) :: chardata | nodata
213
221
def gets ( device // group_leader ( ) , prompt ) do
214
- :io . get_line ( map_dev ( device ) , prompt )
222
+ :io . get_line ( map_dev ( device ) , to_chardata ( prompt ) )
215
223
end
216
224
217
225
@ doc """
@@ -230,8 +238,9 @@ defmodule IO do
230
238
Enum.each IO.stream(:stdio, :line), &IO.write(&1)
231
239
232
240
"""
233
- def stream ( device , line_or_bytes ) do
234
- fn ( acc , f ) -> stream ( map_dev ( device ) , line_or_bytes , acc , f ) end
241
+ @ spec stream ( device , :line | pos_integer ) :: Enumerable . t
242
+ def stream ( device , line_or_codepoints ) do
243
+ fn ( acc , f ) -> stream ( map_dev ( device ) , line_or_codepoints , acc , f ) end
235
244
end
236
245
237
246
@ doc """
@@ -240,6 +249,7 @@ defmodule IO do
240
249
241
250
This reads the io as a raw binary.
242
251
"""
252
+ @ spec binstream ( device , :line | pos_integer ) :: Enumerable . t
243
253
def binstream ( device , line_or_bytes ) do
244
254
fn ( acc , f ) -> binstream ( map_dev ( device ) , line_or_bytes , acc , f ) end
245
255
end
@@ -272,4 +282,7 @@ defmodule IO do
272
282
defp map_dev ( :stdio ) , do: :standard_io
273
283
defp map_dev ( :stderr ) , do: :standard_error
274
284
defp map_dev ( other ) , do: other
285
+
286
+ defp to_chardata ( list ) when is_list ( list ) , do: list
287
+ defp to_chardata ( other ) , do: to_string ( other )
275
288
end
0 commit comments