77
88defmodule IO do
99 @ 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.
1511
12+ Many functions in this module expects an IO device as argument.
1613 An IO device must be a pid or an atom representing a process.
1714 For convenience, Elixir provides `:stdio` and `:stderr` as
1815 shortcuts to Erlang's `:standard_io` and `:standard_error`.
1916
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).
2120
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.
3023
3124 """
3225
26+ @ type device :: atom | pid
27+ @ type chardata :: char_list | String.Chars . t
28+ @ type nodata :: { :error , term } | :eof
29+
3330 import :erlang , only: [ group_leader: 0 ]
3431
3532 defmacrop is_iolist ( data ) do
@@ -50,6 +47,7 @@ defmodule IO do
5047 for instance `{:error, :estale}` if reading from an
5148 NFS file system.
5249 """
50+ @ spec read ( device , :line | non_neg_integer ) :: chardata | nodata
5351 def read ( device // group_leader , chars_or_line )
5452
5553 def read ( device , :line ) do
@@ -72,6 +70,7 @@ defmodule IO do
7270 for instance `{:error, :estale}` if reading from an
7371 NFS file system.
7472 """
73+ @ spec binread ( device , :line | non_neg_integer ) :: iodata | nodata
7574 def binread ( device // group_leader , chars_or_line )
7675
7776 def binread ( device , :line ) do
@@ -105,8 +104,9 @@ defmodule IO do
105104 #=> "error"
106105
107106 """
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 )
110110 end
111111
112112 @ doc """
@@ -115,6 +115,7 @@ defmodule IO do
115115
116116 Check `write/2` for more information.
117117 """
118+ @ spec binwrite ( device , iodata ) :: :ok | { :error , term }
118119 def binwrite ( device // group_leader ( ) , item ) when is_iolist ( item ) do
119120 :file . write map_dev ( device ) , item
120121 end
@@ -124,9 +125,10 @@ defmodule IO do
124125 but adds a newline at the end. The argument is expected
125126 to be a chardata.
126127 """
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
128130 erl_dev = map_dev ( device )
129- :io . put_chars erl_dev , [ item , ?\n ]
131+ :io . put_chars erl_dev , [ to_chardata ( item ) , ?\n ]
130132 end
131133
132134 @ doc """
@@ -142,13 +144,15 @@ defmodule IO do
142144 IO.inspect Process.list
143145
144146 """
147+ @ spec inspect ( term , Keyword . t ) :: term
145148 def inspect ( item , opts // [ ] ) do
146149 inspect group_leader ( ) , item , opts
147150 end
148151
149152 @ doc """
150153 Inspects the item with options using the given device.
151154 """
155+ @ spec inspect ( device , term , Keyword . t ) :: term
152156 def inspect ( device , item , opts ) when is_list ( opts ) do
153157 opts = Keyword . put_new ( opts , :pretty , true )
154158
@@ -178,6 +182,8 @@ defmodule IO do
178182 for instance `{:error, :estale}` if reading from an
179183 NFS file system.
180184 """
185+ @ spec getn ( chardata , pos_integer ) :: chardata | nodata
186+ @ spec getn ( device , chardata ) :: chardata | nodata
181187 def getn ( prompt , count // 1 )
182188
183189 def getn ( prompt , count ) when is_integer ( count ) do
@@ -194,8 +200,9 @@ defmodule IO do
194200 the number of unicode codepoints to be retrieved.
195201 Otherwise, `count` is the number of raw bytes to be retrieved.
196202 """
203+ @ spec getn ( device , chardata , pos_integer ) :: chardata | nodata
197204 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 )
199206 end
200207
201208 @ doc """
@@ -210,8 +217,9 @@ defmodule IO do
210217 for instance `{:error, :estale}` if reading from an
211218 NFS file system.
212219 """
220+ @ spec gets ( device , chardata ) :: chardata | nodata
213221 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 ) )
215223 end
216224
217225 @ doc """
@@ -230,8 +238,9 @@ defmodule IO do
230238 Enum.each IO.stream(:stdio, :line), &IO.write(&1)
231239
232240 """
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
235244 end
236245
237246 @ doc """
@@ -240,6 +249,7 @@ defmodule IO do
240249
241250 This reads the io as a raw binary.
242251 """
252+ @ spec binstream ( device , :line | pos_integer ) :: Enumerable . t
243253 def binstream ( device , line_or_bytes ) do
244254 fn ( acc , f ) -> binstream ( map_dev ( device ) , line_or_bytes , acc , f ) end
245255 end
@@ -272,4 +282,7 @@ defmodule IO do
272282 defp map_dev ( :stdio ) , do: :standard_io
273283 defp map_dev ( :stderr ) , do: :standard_error
274284 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 )
275288end
0 commit comments