-
Notifications
You must be signed in to change notification settings - Fork 3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Adds sigils translation, refs #6 #11
Merged
Merged
Changes from 1 commit
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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": | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. в строкЕ |
||
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}`) | ||
|
||
В добавок, двойная кавычка внутри двойной кавычки должна быть экранирована как `\"`, аналогично и одинарная кавычка внутри одинарной кавычки `\'`. Тем не менее, лучше изменить разделители, чем использовать экранирование. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
|
||
|
||
Сигилы также поддерживают 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_*` функции). |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
часто используемый
раздельно