• Что бы вступить в ряды "Принятый кодер" Вам нужно:
    Написать 10 полезных сообщений или тем и Получить 10 симпатий.
    Для того кто не хочет терять время,может пожертвовать средства для поддержки сервеса, и вступить в ряды VIP на месяц, дополнительная информация в лс.

  • Пользаватели которые будут спамить, уходят в бан без предупреждения. Спам сообщения определяется администрацией и модератором.

  • Гость, Что бы Вы хотели увидеть на нашем Форуме? Изложить свои идеи и пожелания по улучшению форума Вы можете поделиться с нами здесь. ----> Перейдите сюда
  • Все пользователи не прошедшие проверку электронной почты будут заблокированы. Все вопросы с разблокировкой обращайтесь по адресу электронной почте : info@guardianelinks.com . Не пришло сообщение о проверке или о сбросе также сообщите нам.

On my elm-knobs Elm package

Sascha Оффлайн

Sascha

Заместитель Администратора
Команда форума
Администратор
Регистрация
9 Май 2015
Сообщения
1,483
Баллы
155
Two years ago I made

Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.

to scratch my own itch, named agj/elm-knobs. I wanted a simple interface to tweak constants dynamically in order to see how they affect a visual algorithm (which was just a project I was working on for fun; I'll post about it if I actually get around to finishing it). I found a few packages that get close to what I wanted, but nothing matching precisely my needs, so I just coded the thing and eventually turned it into a simple package.


Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.



The intended use-case for the package is squarely prototyping, so I didn't put effort into making it look nice or visually versatile. What I did though is add “knobs” (interactive controls) for primitive types (Int, Float, String, Bool) and a few non-primitives.

The way it works is through a Knob a type value, where a could be any type at all, as long as you have the means to create it. This knob value contains the current value of a and a view function that returns HTML and emits updates to itself as an event whenever the controls get manipulated. Below is a quick rundown on how to use a knob.


knob : Knob Int
knob =
Knob.int { step = 1, initial = 0 }

knobValue : Int
knobValue =
Knob.value knob

type Msg =
KnobUpdated (Knob Int)

knobView : Html Msg
knobView =
Knob.view [] KnobUpdated knob




Please note that this example code and the rest of this post are actually based on unreleased v2 code. I guess I'll have to release that version soon, though.

And then there's ways to compose, transform and create custom knobs. You can also serialize and deserialize a knob into a string, in order to persist its value using the Web Storage API or however else you like. Some omissions I can think of are knobs for dates, and for data structures such as lists and dictionaries.

In the remainder of this blog post I'll describe a couple of ways in which I “over-developed” this package, beyond its content proper.

This was my first Elm package, and I put a lot of effort into the documentation, taking it as a chance to learn and just make it as useful as possible. Elm core package documentation is way above average, so I took a lot of inspiration from it. I think that the

Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.

I wrote are pretty clear and organized, meant to almost work as a tutorial.

One way I tried to improve the documentation was by creating

Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.

using

Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.

. It's comprised of code examples for each of the knob functions, whose resulting HTML you can see live in your browser. It's interactive in the sense that the example code shows up as interactive HTML, not in that you can tweak the code yourself, though.

One of the interesting things I did there was making sure that the example code matches what you see exactly, and that I don't have to forget to copy & paste something. Elm has no metaprogramming capabilities, so using an external tool to do this was necessary—here comes

Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.

to the rescue! (Think

Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.

, but for manipulating code syntax instead of plain text.)

Take a look at the Elm code below, describing an example for Knob.float. Using

Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.

, the string value in the code field gets filled with what's in the init_ field automatically. Having these two synchronized makes sure that example code is always valid, since otherwise the interactive docs would not compile either.


floatDoc : KnobDoc Float Model
floatDoc =
{ name = "float"
, link = Nothing
, description = Nothing
, init_ =
Knob.float { step = 0.01, initial = 0 }
, code =
"""
Knob.float { step = 0.01, initial = 0 }
"""
, get = \model -> model.float
, set = \model new -> { model | float = new }
, toString = String.fromFloat
}




Another thing you might notice from the code block above is that I used some tricks to make writing the documentation more DRY (i.e. more consistent, less error-prone). With ElmBook you write markdown to define the content of each page. I generate this markdown from records like the one you see above.

Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.

, although it might be a bit hard to follow, especially given that it's written to accomodate the ElmBook API. But at any rate, something like the above turns into

Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.

.


Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.



I'm not happy with having to split the “API docs” and the “interactive docs”, so at some point I might figure out a way of automatically parsing the Elm comment docs and inserting that content into the interactive documentation, to keep it all in one place. Sounds like a lot of effort for such a relatively useless package, so if I ever end up going through the trouble, it'll be for the learning opportunity (or perhaps my OCD.)

I test all knobs using property-based tests (which in

Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.

are called “fuzzers”, although that is

Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.

). The idea is that instead of each test checking for one or a few input values one by one against an expected result, we automatically generate a whole range of inputs, so we can make sure that our function behaves the way we expect given any possible input in the range. This technique receives this name because we can't use the same strategy for standard unit tests and just check one input against one result; we need to instead test that a given property holds.

For instance, I have a suite of serialization tests, of which there's two types:

  • Something I called “transitive equality”, for lack of a better term: If two knobs correspond to the same value, the result of serializing them should also be equal, and vice-versa.
  • A classic

    Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.

    : We serialize and then deserialize, and expect the value of the input knob and of the result to be identical.

Other tests check messages emitted when a user manipulates the controls, the behavior for invalid inputs, and such.

Let me give you an example of a problem I frequently run into when using third-party library code. At my day job, we're using Vue and a component library called

Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.

. We are using v1, and recently they released v2. As soon as they did, the documentation for v1 disappeared.

I don't like this experience. I want to decide when to upgrade, and as long as I'm using an old version, I want to have access to its documentation. Two libraries in the JavaScript space that do great in this respect are

Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.

and

Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.

. Elm packages automatically keep docs available for every version, so this is much less of a problem in our ecosystem. However, if I point a link at a latest URL, I'm effectively making my documentation expire.

So, all of the links to places in the documentation, including the package docs and the interactive docs, are versioned. And in order to make sure I don't forget to update any version string whenever I release a new version, I've implemented checks across the repo. For links in the readme, the

Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.


Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.

rule works great. For other cases, I wrote

Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.

that even checks the git tag and the changelog.

Interactive docs for older versions are also kept available in Github Pages and in compiled form in the repo.



Источник:

Пожалуйста Авторизируйтесь или Зарегистрируйтесь для просмотра скрытого текста.

 
Вверх Снизу