.. default-domain:: chpl .. module:: ChapelIO :synopsis: Basic types and utilities in support of I/O operation. ChapelIO ======== .. note:: All Chapel programs automatically ``use`` this module by default. An explicit ``use`` statement is not necessary. Basic types and utilities in support of I/O operation. Most of Chapel's I/O support is within the :mod:`IO` module. This section describes automatically included basic types and routines that support the :mod:`IO` module. Writing and Reading ~~~~~~~~~~~~~~~~~~~ The :proc:`writeln` function allows for a simple implementation of a Hello World program: .. code-block:: chapel writeln("Hello, World!"); // outputs // Hello, World! The :proc:`~IO.read` functions allow one to read values into variables as the following example demonstrates. It shows three ways to read values into a pair of variables ``x`` and ``y``. .. code-block:: chapel var x: int; var y: real; /* reading into variable expressions, returning true if the values were read, false on EOF */ var ok:bool = read(x, y); /* reading via a single type argument */ x = read(int); y = read(real); /* reading via multiple type arguments */ (x, y) = read(int, real); .. _readThis-writeThis-readWriteThis: The readThis(), writeThis(), and readWriteThis() Methods ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ When programming the input and output method for a custom data type, it is often useful to define both the read and write routines at the same time. That is possible to do in a Chapel program by defining a ``readWriteThis`` method, which is a generic method expecting a single :record:`~IO.channel` argument. In cases when the reading routine and the writing routine are more naturally separate, or in which only one should be defined, a Chapel program can define ``readThis`` (taking in a single argument - a readable channel) and/or ``writeThis`` (taking in a single argument - a writeable channel). If none of these routines are provided, a default version of ``readThis`` and ``writeThis`` will be generated by the compiler. If ``readWriteThis`` is defined, the compiler will generate ``readThis`` or ``writeThis`` methods - if they do not already exist - which call ``readWriteThis``. Note that arguments to ``readThis`` and ``writeThis`` may represent a locked channel; as a result, calling methods on the channel in parallel from within a ``readThis``, ``writeThis``, or ``readWriteThis`` may cause undefined behavior. Additionally, performing I/O on a global channel that is the same channel as the one ``readThis``, ``writeThis``, or ``readWriteThis`` is operating on can result in a deadlock. In particular, these methods should not refer to :var:`~IO.stdin`, :var:`~IO.stdout`, or :var:`~IO.stderr` explicitly or implicitly (such as by calling the global :proc:`writeln` function). Instead, these methods should only perform I/O on the channel passed as an argument. Because it is often more convenient to use an operator for I/O, instead of writing .. code-block:: chapel f.readwrite(x); f.readwrite(y); one can write .. code-block:: chapel f <~> x <~> y; Note that the types :type:`IO.ioLiteral` and :type:`IO.ioNewline` may be useful when using the ``<~>`` operator. :type:`IO.ioLiteral` represents some string that must be read or written as-is (e.g. ``","`` when working with a tuple), and :type:`IO.ioNewline` will emit a newline when writing but skip to and consume a newline when reading. This example defines a readWriteThis method and demonstrates how ``<~>`` will call the read or write routine, depending on the situation. .. code-block:: chapel class IntPair { var x: int; var y: int; proc readWriteThis(f) throws { f <~> x <~> new ioLiteral(",") <~> y <~> new ioNewline(); } } var ip = new IntPair(17,2); write(ip); // prints out // 17,2 delete ip; This example defines a only a writeThis method - so that there will be a function resolution error if the class NoRead is read. .. code-block:: chapel class NoRead { var x: int; var y: int; proc writeThis(f) throws { f <~> "hello"; } // Note that no readThis function will be generated. } var nr = new NoRead(); write(nr); // prints out // hello // Note that read(nr) will generate a compiler error. delete nr; .. _default-readThis-writeThis: Default writeThis and readThis Methods ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Default ``writeThis`` methods are created for all types for which a user-defined ``writeThis`` or ``readWriteThis`` method is not provided. They have the following semantics: * for a class: outputs the values within the fields of the class prefixed by the name of the field and the character ``=``. Each field is separated by a comma. The output is delimited by ``{`` and ``}``. * for a record: outputs the values within the fields of the class prefixed by the name of the field and the character ``=``. Each field is separated by a comma. The output is delimited by ``(`` and ``)``. Default ``readThis`` methods are created for all types for which a user-defined ``readThis`` method is not provided. The default ``readThis`` methods are defined to read in the output of the default ``writeThis`` method. Additionally, the Chapel implementation includes ``writeThis`` methods for built-in types as follows: * for an array: outputs the elements of the array in row-major order where rows are separated by line-feeds and blank lines are used to separate other dimensions. * for a domain: outputs the dimensions of the domain enclosed by ``{`` and ``}``. * for a range: output the lower bound of the range, output ``..``, then output the upper bound of the range. If the stride of the range is not ``1``, output the word ``by`` and then the stride of the range. If the range has special alignment, output the word ``align`` and then the alignment. * for tuples, outputs the components of the tuple in order delimited by ``(`` and ``)``, and separated by commas. These types also include ``readThis`` methods to read the corresponding format. Note that when reading an array, the domain of the array must be set up appropriately before the elements can be read. .. note:: Note that it is not currently possible to read and write circular data structures with these mechanisms. .. function:: proc halt() Prints an error message to stderr giving the location of the call to ``halt`` in the Chapel source, followed by the arguments to the call, if any, then exits the program. .. function:: proc halt(s: string) Prints an error message to stderr giving the location of the call to ``halt`` in the Chapel source, followed by the arguments to the call, if any, then exits the program. .. function:: proc halt(args ...?numArgs) Prints an error message to stderr giving the location of the call to ``halt`` in the Chapel source, followed by the arguments to the call, if any, then exits the program. .. function:: proc warning(s: string) Prints a warning to stderr giving the location of the call to ``warning`` in the Chapel source, followed by the argument(s) to the call. .. function:: proc warning(args ...?numArgs) Prints a warning to stderr giving the location of the call to ``warning`` in the Chapel source, followed by the argument(s) to the call. .. function:: proc write(const args ...?n) Equivalent to ``try! stdout.write``. See :proc:`IO.channel.write` .. function:: proc writeln(const args ...?n) Equivalent to ``try! stdout.writeln``. See :proc:`IO.channel.writeln` .. function:: proc writef(fmt: ?t, const args ...?k): bool Equivalent to ``try! stdout.writef``. See :proc:`FormattedIO.channel.writef`.