forked from wunsh/elixir-docs-ru
-
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Adds sigils tranlation, refs wunsh#6
- Loading branch information
Showing
1 changed file
with
188 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,188 @@ | ||
--- | ||
title: Сигилы | ||
--- | ||
|
||
# Сигилы | ||
|
||
Мы уже знаем, что в Эликсирe есть строки с двойными кавычками и списки символов с одинарными кавычками. Однако, есть и другие структуры, у которых есть текстовое представление. Например, атомы, которые в основном создаются как `:atom`. | ||
|
||
Одна из целей Эликсира - быть расширяемым. Разработчики должны иметь возможность расширить язык таким образом, чтобы решить любую задачу. Компьютерные науки стали слишком широкой областью, чтобы ядро любого языка смогло вместить в себя все решения всех возможных проблем. Однако, если сделать язык расширяемым, то разработчики, компании и сообщества сами смогут добавить в него все необходимое. | ||
|
||
В текущей главе, мы рассмотрим сигилы - один из встроенных в язык механизмов для работы с текстовыми представлениями. Сигилы начинаются с символа тильда (`~`), после которого идет буква (которая идентифицирует сигил) и разделитель. Опционально, после разделителя могут быть добавлены еще и модификаторы. | ||
|
||
## Регулярные выражения | ||
|
||
Самый часто-используемый сигил в Эликсире - сигил [регулярных выражений](https://en.wikipedia.org/wiki/Regular_Expressions): `~r`. | ||
|
||
```elixir | ||
# Регулярное выражение, которое находит в строки "foo" или "bar": | ||
iex> regex = ~r/foo|bar/ | ||
~r/foo|bar/ | ||
iex> "foo" =~ regex | ||
true | ||
iex> "bat" =~ regex | ||
false | ||
``` | ||
|
||
Эликсир предоставляет совместимый с Перл синтаксис регулярных выражений, который реализован в библиотеке [PCRE](http://www.pcre.org/). Регулярные выражения поддерживают модификаторы. Например, модификатор `i` делает регулярное выражение нечувствительным к регистру: | ||
|
||
```elixir | ||
iex> "HELLO" =~ ~r/hello/ | ||
false | ||
iex> "HELLO" =~ ~r/hello/i | ||
true | ||
``` | ||
|
||
В [модуле Regex](https://hexdocs.pm/elixir/Regex.html) доступно больше информации о других модификаторах и операциях с регулярными выражениями. | ||
|
||
Пока что во всех примерах мы использовали `/` для разделения сигилов. Однако, сигилы поддерживают 8 разных типов разделителей: | ||
|
||
```elixir | ||
~r/hello/ | ||
~r|hello| | ||
~r"hello" | ||
~r'hello' | ||
~r(hello) | ||
~r[hello] | ||
~r{hello} | ||
~r<hello> | ||
``` | ||
|
||
Причина, по которой сигилы поддерживают разные типы разделителей, заключается в возможности писать код без экранирования. Регулярное выражение с прямыми слешами записанное в виде `~r(^https?://)` читается гораздо проще, чем такое же выражение в другой форме записи `~r/^https?:\/\//`. Аналогично, если в регулярном выражении есть прямые слеши и группы (которые используют `()`), то можно использовать двойные кавычки вместо слешей. | ||
|
||
## Строки, списки символов и сигил списка слов | ||
|
||
Кроме регулярных выражений в языке Эликсир есть три других сигила. | ||
|
||
### Строки | ||
|
||
Сигил `~s` используется для создания строк, также как и двойные кавычки. Сигил `~s` полезен, когда в самой строке есть двойные кавычки: | ||
|
||
```elixir | ||
iex> ~s(this is a string with "double" quotes, not 'single' ones) | ||
"this is a string with \"double\" quotes, not 'single' ones" | ||
``` | ||
|
||
### Списки символов | ||
|
||
Сигил `~c` используется для создания списка символов, содержащих одинарную кавычку: | ||
|
||
```elixir | ||
iex> ~c(this is a char list containing 'single quotes') | ||
'this is a char list containing \'single quotes\'' | ||
``` | ||
|
||
### Списки слов | ||
|
||
Сигил `~w` используется для создания списка слов (сами слова - обычные строки). Внутри сигила `~w` слова разделены пробелами: | ||
|
||
```elixir | ||
iex> ~w(foo bar bat) | ||
["foo", "bar", "bat"] | ||
``` | ||
|
||
Сигил `~w` поддерживает модификаторы `c`, `s` и `a` (списки символов, строки и атомы соответственно) для указания типа данных членов итогового списка: | ||
|
||
```elixir | ||
iex> ~w(foo bar bat)a | ||
[:foo, :bar, :bat] | ||
``` | ||
|
||
Кроме сигилов в нижнем регистре, Эликсир также поддерживает сигилы в верхнем регистре, чтобы работать с экранированием и интерполяцией. Оба сигила `~s` и `~S` вернут строку, с той разницей, что сигилы в верхнем регистре не поддерживают экранирование и интерполяцию: | ||
|
||
```elixir | ||
iex> ~s(String with escape codes \x26 #{"inter" <> "polation"}) | ||
"String with escape codes & interpolation" | ||
iex> ~S(String without escape codes \x26 without #{interpolation}) | ||
"String without escape codes \\x26 without \#{interpolation}" | ||
``` | ||
|
||
Список поддерживаемых символов экранирования: | ||
|
||
- `\\` – одинарный обратный слеш | ||
- `\a` – звонок/тревога | ||
- `\b` – бекспейс | ||
- `\d` - удаление | ||
- `\e` - выход | ||
- `\f` - форма подачи | ||
- `\n` – новая строка | ||
- `\r` – возврат каретки | ||
- `\s` – пробел | ||
- `\t` – таб | ||
- `\v` – вертикальный таб | ||
- `\0` - нулевой байт | ||
- `\xDD` - представляет один байт в восьмеричной записи (например `\x13`) | ||
- `\uDDDD` и `\u{D...}` - представляют символ Юникода (например `\u{1F600}`) | ||
|
||
В добавок, двойная кавычка внутри двойной кавычки должна быть экранирована как `\"`, аналогично и одинарная кавычка внутри одинарной кавычки `\'`. Тем не менее, лучше изменить разделители, чем использовать экранирование. | ||
|
||
Сигилы также поддерживают heredocs, в качестве разделителей используются три двойных или одинарных кавычки: | ||
|
||
```elixir | ||
iex> ~s""" | ||
...> this is | ||
...> a heredoc string | ||
...> """ | ||
``` | ||
Чаще всего сигилы heredoc используют для написания документации. Например, если в документации встречается какой-то символ экранирования, то в документации могут появиться ошибки, потому что придется экранировать его дважды: | ||
```elixir | ||
@doc """ | ||
Converts double-quotes to single-quotes. | ||
## Examples | ||
iex> convert("\\\"foo\\\"") | ||
"'foo'" | ||
""" | ||
def convert(...) | ||
``` | ||
|
||
Но если использовать сигил `~S`, то такой проблемы можно полностью избежать: | ||
```elixir | ||
@doc ~S""" | ||
Converts double-quotes to single-quotes. | ||
## Examples | ||
iex> convert("\"foo\"") | ||
"'foo'" | ||
""" | ||
def convert(...) | ||
``` | ||
|
||
## Собственные сигилы | ||
|
||
Как уже было сказано в самом начале, сигилы - расширяемы. На самом деле использование сигила `~r/foo/i` равнозначно вызову `sigil_r` с двоичными данными и списком символов в качестве аргументов: | ||
|
||
```elixir | ||
iex> sigil_r(<<"foo">>, 'i') | ||
~r"foo"i | ||
``` | ||
|
||
Мы можем обратиться к документации сигила `~r` через `sigil_r`: | ||
|
||
```elixir | ||
iex> h sigil_r | ||
... | ||
``` | ||
|
||
Можно создавать собственные сигилы: нужно создать функцию, которая бы следовала формату `sigil_{имя_индентификатора}`. К примеру, давайте создадим сигил `~i`, который возвращает целое число (с опциональным модификатором `n`, чтобы сделать число отрицательным): | ||
|
||
```elixir | ||
iex> defmodule MySigils do | ||
...> def sigil_i(string, []), do: String.to_integer(string) | ||
...> def sigil_i(string, [?n]), do: -String.to_integer(string) | ||
...> end | ||
iex> import MySigils | ||
iex> ~i(13) | ||
13 | ||
iex> ~i(42)n | ||
-42 | ||
``` | ||
|
||
Сигилы могут быть использованы для выполнения работы на шаге компиляции. К примеру, регулярные выражения в Эликсире компилируются в производительные структуры, чтобы работать быстрее на шаге выполнения. Если вам интересен данный вопрос, то советуем изучить, как работают макросы, и посмотреть как реализованы сигилы в модуле `Kernel` (где реализованы все `sigil_*` функции). |