Elixir How to use help

# Elixir How to use help

## 概要
Elixir のヘルプの利用法

## 利用法

h コマンドで全体のヘルプ
h module_name でモジュール全体のヘルプ
h module_name.function_name で関数のヘルプ

~~~
# iex を起動します
$ iex
Erlang/OTP 17 [erts-6.1] [source] [64-bit] [smp:2:2] [async-threads:10] [kernel-poll:false]

Interactive Elixir (1.0.0) - press Ctrl+C to exit (type h() ENTER for help)

# h コマンドで全体のヘルプを表示します
iex(1)> h

                                  IEx.Helpers

Welcome to Interactive Elixir. You are currently seeing the documentation for
the module IEx.Helpers which provides many helpers to make Elixir's shell more
joyful to work with.

This message was triggered by invoking the helper h(), usually referred to as
h/0 (since it expects 0 arguments).

There are many other helpers available:

  ~ c/2       ? compiles a file at the given path
  ~ cd/1      ? changes the current directory
  ~ clear/0   ? clears the screen
  ~ flush/0   ? flushes all messages sent to the shell
  ~ h/0       ? prints this help message
  ~ h/1       ? prints help for the given module, function or macro
  ~ l/1       ? loads the given module's beam code and purges the current
    version
  ~ ls/0      ? lists the contents of the current directory
  ~ ls/1      ? lists the contents of the specified directory
  ~ pwd/0     ? prints the current working directory
  ~ r/1       ? recompiles and reloads the given module's source file
  ~ respawn/0 ? respawns the current shell
  ~ s/1       ? prints spec information
  ~ t/1       ? prints type information
  ~ v/0       ? prints the history of commands evaluated in the session
  ~ v/1       ? retrieves the nth value from the history
  ~ import_file/1
    x         ? evaluates the given file in the shell's context


Help for functions in this module can be consulted directly from the command
line, as an example, try:

x h(c/2)

You can also retrieve the documentation for any module or function. Try these:

x h(Enum)
x h(Enum.reverse/1)

To discover all available functions for a module, type the module name follow
by a dot, then press tab to trigger autocomplete. For example:

x Enum.

To learn more about IEx as a whole, just type h(IEx).

iex(2)> h String

                                     String

A String in Elixir is a UTF-8 encoded binary.

Codepoints and graphemes

The functions in this module act according to the Unicode Standard, version
6.3.0.As per the standard, a codepoint is an Unicode Character, which may be
represented by one or more bytes. For example, the character "e" is represented
with two bytes:

x iex> byte_size("e")
x 2

However, this module returns the proper length:

x iex> String.length("e")
x 1

Furthermore, this module also presents the concept of graphemes, which are
multiple characters that may be "perceived as a single character" by readers.
For example, the same "e" character written above could be represented by the
letter "e" followed by the accent ?:

x iex> string = "\x{0065}\x{0301}"
x iex> byte_size(string)
x 3
x iex> String.length(string)
x 1

Although the example above is made of two characters, it is perceived by users
as one.

Graphemes can also be two characters that are interpreted as one by some
languages. For example, some languages may consider "ch" as a grapheme.
However, since this information depends on the locale, it is not taken into
account by this module.

In general, the functions in this module rely on the Unicode Standard, but does
not contain any of the locale specific behaviour.

More information about graphemes can be found in the Unicode Standard Annex #29
(http://www.unicode.org/reports/tr29/). This current Elixir version implements
Extended Grapheme Cluster algorithm.

String and binary operations

To act accordingly to the Unicode Standard, many functions in this module runs
in linear time, as it needs to traverse the whole string considering the proper
Unicode codepoints.

For example, String.length/1 is going to take longer as the input grows. On the
other hand, byte_size/1 always runs in constant time (i.e. regardless of the
input size).

This means often there are performance costs in using the functions in this
module, compared to the more low-level operations that work directly with
binaries:

  ~ Kernel.binary_part/3 - retrieves part of the binary
  ~ Kernel.bit_size/1 and Kernel.byte_size/1 - size related functions
  ~ Kernel.is_bitstring/1 and Kernel.is_binary/1 - type checking function
  ~ Plus a number of functions for working with binaries (bytes) in the
    :binary module (http://erlang.org/doc/man/binary.html)

There are many situations where using the String module can be avoided in favor
of binary functions or pattern matching. For example, imagine you have a string
prefix and you want to remove this prefix from another string named full.

One may be tempted to write:

x iex> take_prefix = fn full, prefix ->
x ...>   base = String.length(prefix)
x ...>   String.slice(full, base, String.length(full) - base)
x ...> end
x ...> take_prefix.("Mr. John", "Mr. ")
x "John"

Although the function above works, it performs poorly. To calculate the length
of the string, we need to traverse it fully, so we traverse both prefix and
full strings, then slice the full one, traversing it again.

A first attempting at improving it could be with ranges:

x iex> take_prefix = fn full, prefix ->
x ...>   base = String.length(prefix)
x ...>   String.slice(full, base..-1)
x ...> end
x ...> take_prefix.("Mr. John", "Mr. ")
x "John"

While this is much better (we don't traverse full twice), it could still be
improved. In this case, since we want to extract a substring from a string, we
can use byte_size/1 and binary_part/3 as there is no chance we will slice in
the middle of a codepoint made of more than one byte:

x iex> take_prefix = fn full, prefix ->
x ...>   base = byte_size(prefix)
x ...>   binary_part(full, base, byte_size(full) - base)
x ...> end
x ...> take_prefix.("Mr. John", "Mr. ")
x "John"

Or simply used pattern matching:

x iex> take_prefix = fn full, prefix ->
x ...>   base = byte_size(prefix)
x ...>   <<_ :: binary-size(base), rest :: binary>> = full
x ...>   rest
x ...> end
x ...> take_prefix.("Mr. John", "Mr. ")
x "John"

On the other hand, if you want to dynamically slice a string based on an
integer value, then using String.slice/3 is the best option as it guarantees we
won't incorrectly split a valid codepoint in multiple bytes.

Integer codepoints

Although codepoints could be represented as integers, this module represents
all codepoints as strings. For example:

x iex> String.codepoints("ola")
x ["o", "l", "a"]

There are a couple of ways to retrieve a character integer codepoint. One may
use the ? construct:

x iex> ?o
x 111
x
x iex> ?a
x 225

Or also via pattern matching:

x iex> << eacute :: utf8 >> = "a"
x iex> eacute
x 225

As we have seen above, codepoints can be inserted into a string by their
hexadecimal code:

x "ol\x{0061}\x{0301}" #=>
x "ola"

Self-synchronization

The UTF-8 encoding is self-synchronizing. This means that if malformed data
(i.e., data that is not possible according to the definition of the encoding)
is encountered, only one codepoint needs to be rejected.

This module relies on this behaviour to ignore such invalid characters. For
example, length/1 is going to return a correct result even if an invalid
codepoint is fed into it.

In other words, this module expects invalid data to be detected when retrieving
data from the external source. For example, a driver that reads strings from a
database will be the one responsible to check the validity of the encoding.

# h モジュール名.関数名で関数のヘルプを表示します
iex(3)> h String.downcase

                              def downcase(binary)

Convert all characters on the given string to lowercase.

Examples

x iex> String.downcase("ABCD")
x "abcd"
x
x iex> String.downcase("AB 123 XPTO")
x "ab 123 xpto"
x
x iex> String.downcase("OLA")
x "ola"

# help の help を表示
iex(4)> h h

                                    def h()

Prints the documentation for IEx.Helpers.


                               defmacro h(other)

Prints the documentation for the given module or for the given function/arity
pair.

Examples

x h(Enum)
x #=> Prints documentation for Enum

It also accepts functions in the format fun/arity and module.fun/arity, for
example:

x h receive/1
x h Enum.all?/2
x h Enum.all?
~~~