Skip to content

Latest commit

 

History

History

top-6-ways-to-make-your-elm-app-crash-at-runtime

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 

6 способов вызвать сбой во время выполнения Elm приложения

Перевод статьи Noah: Top 6 ways to make your Elm app crash at runtime.

Elm славится тем, что у него «нет исключений во время исполнения», и по большей части язык делает действительно, действительно отличную работу! Возможно писать Elm приложения без исключений во время исполнения, к тому же большинство пользователей их и так никогда не увидит.

Некоторое время назад я писал в twitter о 9 различных способах, как сделать исключения во время выполнения, которые нескольких дней я так и не смог выкинуть из головы. Вот небольшое исследование 6 способов, с которыми я столкнулся в реальности, и есть некоторые правила, которым я бы следовал, чтобы избежать возможных сбоев. И я следую этим правилам, чтобы гарантировать, что мои приложения Elm никогда не будут давать сбой, но в любом случае все эти эксперименты я делаю просто для собственного удовольствия.

Все способы актуальны для Elm 0.18.

Номер #1 — Регулярные выражения

Какое-то время регулярные выражения были поломаны, тем самым их использование создавало ошибки во время работы Elm приложения. Вот самый простой пример (пример в Ellie app):

https://gist.github.com/ufocoder/2c0f74c559a4fcc8d3e3fef99a0b9559

Если вы перейдете на вкладку Results (прим. пер.: этот и дальнейшие примеры рассматриваются как запущенные в Ellie app), вы ничего не увидите! Это связано с тем, что Regex.regex дает сбой, когда вы передаете ему недопустимое регулярное выражение. В этом случае я начал описывать группу в регулярном выражении, не закрывая ее, что означает, что мое Elm приложение даст сбой. Это приводит к сбоям при загрузке, поскольку Elm не является ленивым для значений верхнего уровня, однако, если вы будете использовать встроенные (inline) Regex, тогда сбоя при загрузке не будет, все это означает, что ошибки во время исполнения могут легко оказаться и в продакшене (пример в Ellie app):

https://gist.github.com/ufocoder/891ef91373254082a4d60d37ca855724

Перейдите на вкладку результатов, затем нажмите на кнопку и посмотрите, как ничего не меняется! Это связано с тем, что ошибка по время выполнения возникает только, когда функция update выполнена. Представьте, если бы это были несколько глубоко вложенных функций! Довольно запутанно, чтобы разобраться в этом.

Мое правило: задавайте регулярные выражения только в начале области видимости

Номер 2 — Массивы

Подобно регулярным выражениям, массивы также были сломаны в течение длительного времени! Вот небольшой пример (пример в Ellie app):

https://gist.github.com/ufocoder/8f101cc17691f3dd088cc6ff77d3339c

Перейдите на вкладку результатов, и вы ничего не увидите! Это происходит из-за того, как реализовано Array в основной библиотеке. Внутри реализации используется структура, основанная на числе 32, для размещения вложенного дерева массивов, что позволяет быстро индексировать. Вы можете узнать об этом больше, исследуя альтернативную реализацию, elm-array-exploration от Робина. Первоначальная реализация была почти полностью написана на JavaScript, но документация и автор уже давно пропали, как старый дуб в ночи. Реализация Робина направлена на то, чтобы писать как можно больше на чистом Elm - и использовать JavaScript исключительно для реализации необходимых ключевый частей.

Мое правило: никогда не используйте массив из библиотеки elm-lang/core, если вы хотите, чтобы все работало. Используйте elm-array-exploration до тех пор, пока не изменится реализация ядра.

Номер #3 — Эквивалентность функций

Эквивалентность функций одна из довольно сложных вещей для понимания в языках, где возможно частичное применение функций. Что означает для функции - быть эквивалентной другой функции? Например, в Python, я бы сказал, что если функции были бы одним и тем же объектом функции с одинаковыми аргументами, то это была бы одна и та же функция.

Однако в Elm функция эквивалентности не поддерживается (пример в Ellie app):

https://gist.github.com/ufocoder/1c25bfc944b20697ce783991c10e9aa5

Проверьте вкладку результатов в Ellie app, и вы ничего не увидите. Больше нечего сказать. Возможно следовало бы поддерживать эквивалентность функция, а возможно и нет. Я больше склоняюсь к тому, что нет, это как ни рыба ни мясо.

Мое правило: вы, вероятно, не должны использовать эквивалентность функций. Но если это необходимо, тогда свяжите их как значение с идентификатором какого-нибудь типа в словаре.

Номер 4 — Elm не ленивый язык!

Общей ошибкой разработчиков, которую я встречаю в каналах Slack, является то, что Elm рассматривается как ленивый язык программирования, когда это не так. Пример этого ниже (пример в Ellie app):

https://gist.github.com/ufocoder/0b66cfb386a61347ba99cf5ffeb69dc7

Обратите внимание на то, как Maybe.withDefault может показаться безобидной функцией, но на самом деле, если вы перейдете к результатам, то получите абсолютно пустую страницу. Это потому, что Debug.crash выполняется в то же время, когда вы передаете функции строку, не помещая ее в функцию, он просто запускается сразу же, даже если у нас есть Just!

Чтобы исправить это, достаточно использовать старое доброе case выражение:

https://gist.github.com/ufocoder/4317d9f1ce2b4d23975e1874d9964c9b

Мое правило: никогда не имейте дело с функцией Debug.crash, которая не используйте внутри выражения case или внутри функции.

Номер 5 — не всему следует быть закодированным

В алгоритмах ядра Elm существует небольшое отличие между JSON объектом и структурой записи. Фактически, разница между ними может быть найдена только во время компиляции. Union типы несколько отличаются - они содержат магическое поле ctor, одновременно с _n полем для каждого аргумента, который эти типы получают. После того как мы смогли создать эти объекты во время исполнения через Json.Encode, мы можем вызвать сбой с помощью трюка с использованием == или целым рядом других методов (пример в Ellie app):

https://gist.github.com/ufocoder/3d9b554b73dd96253c59dad20c715600

Обратите внимание, что нам пришлось создать новый объект дважды: иначе бы в Elm использовалось ссылочное равенство и этот трюк не сработал бы. Тем не менее, на практике я столкнулся с этими проблемами только один или может быть два раза - и ни разу этот трюк не был устранен Elm! У меня есть некоторая дополнительная документация об этих структурах здесь

Мое правило: не когда не используйте ==, toString и тому подобное для Json.Value. Используйте только функции, сигнатуры которых похожи на Json.Value -> _

Номер 6 — Невалидная функция Html.Attributes

В библиотеке Elm-Html возможно использовать невалидные свойства для Html-элементов. Например в функцию Html.select нельзя передать значение с числовым типом. Тем более это просто не имеет смысла! К тому же это вызвать сбой Elm приложения (пример в Ellie app):

https://gist.github.com/ufocoder/808b91145d5cdb2a1c9007f2e1c11360

Мое правило: убедитесь что вы действительно знаете спецификацию Html (шутка)

Заключение

Возможно, это далеко не то, с чем вы сталкиваетесь на практике, но когда вы с столкнетесь с этим, это может стать неприятным сюрпризом. Благодаря прилагаемым усилиям, мы придерживаемся в Elm высоких стандартов, чтобы предотвратить подобные способы, которые могут вызвать сбой. Я рад, что только какой-то непонятный JSON объект, сначала закодированный, а затем сравниваемый с другим, является одним из тех немногих способов, которые способны вызвать сбой приложения в моем любимом языке! И я не могу сказать то же самое про многие другие языки. А ты?

Примечание переводчика

На момент перевода версия Elm 0.19, и актуальным из этой статьи является только последний эксперимент. Это показывает, что разработчики Elm постоянно работают над качеством языка, придерживаясь принципов, где одним из них является отсутствие исключений во время исполнения.


Слушайте наш подкаст в iTunes и SoundCloud, читайте нас на Medium, контрибьютьте на GitHub, общайтесь в группе Telegram, следите в Twitter и канале Telegram, рекомендуйте в VK и Facebook.

Если вам понравилась статья, внизу можно поддержать автора хлопками 👏🏻 Спасибо за прочтение!