Yaml: Начните работу над v3: в направлении большего поведения, похожего на `encoding / json`

Созданный на 3 февр. 2016  ·  11Комментарии  ·  Источник: go-yaml/yaml

Есть ряд областей, в которых эта библиотека значительно отличается от поведения в encoding/json что, как правило, становится неожиданностью для многих разработчиков Go и может привести к значительным затратам времени на поиск скрытых сбоев. Многие из этих проблем потребуют критических изменений для исправления, если они должны быть поведением по умолчанию. Конечно, есть те, кто думает, что можно добиться большего, чем encoding/json , и я думаю, что для этих людей версия 3 должна предоставлять возможности для имитации поведения по умолчанию в версии 2 и других. Однако я твердо придерживаюсь мнения, что стандартное поведение по умолчанию, вероятно, должно быть как можно ближе к поведению encoding/json , при этом другие функции и параметры строго запрещены, поскольку это будет гораздо менее удивительно для среднего разработчика Go.

Я хотел бы попытаться составить список критических изменений, которые войдут в потенциальную версию 3, и посмотреть, будет ли достаточно поддержки, чтобы серьезно заняться этим. Итак, пожалуйста, добавьте любые критические изменения, которые вы хотели бы видеть в v3, в комментариях, давайте посмотрим, насколько существует консенсус, и я постараюсь получить несколько дней в следующем месяце, чтобы внести серьезный вклад в эти усилия, если это выглядит жизнеспособным.

Вот что мне бы хотелось увидеть в v3:

  • Простая сортировка имени поля. т.е. по умолчанию имена полей структуры будут закодированы так, как они написаны в Go, а не в нижнем регистре (см. # 149 и # 148)
  • Простое демаршалинг имени поля. то есть по умолчанию имена полей структуры будут декодированы, если они являются точным совпадением (регистр и все) с именами полей структуры, или будут немаршалированы нечувствительным к регистру способом, если не существует точных совпадений, например, в encoding/json.Unmarshal ( см. # 149, # 148, # 123 cc @moul) отредактировано, чтобы исправить форматирование
  • Немаршалинг анонимных полей структуры полей должен соответствовать способу обработки encoding/json , см. # 63 (cc @bcronin)

Также было бы здорово получить некоторые исправления ошибок для этой версии, хотя некоторые из них могут быть применимы и к v2, но определенно безопасны в новой версии, например, # 154 (cc @RichiH), # 125 (cc @wrouesnel @ 3рф).

Итак, кто-нибудь видел какие-либо другие отличия от encoding/json мы должны попытаться исправить в v3? Кто-нибудь хочет провести со мной выходные, работая над этим? :)

Самый полезный комментарий

Как человек, пользующийся библиотекой, я хочу прежде всего поблагодарить вас за библиотеку и проделанную вами работу. Говоря только о себе, мне бы очень хотелось, чтобы кодировщик и декодер были экспортированы для потокового использования. На мой взгляд, это решит проблему № 154 и будет вести себя больше как пакеты python и ruby ​​yaml (т.е. обновить значение базовых ключей новым значением, фактически игнорируя первое). Позвольте пользователю реализовать свою собственную бизнес-логику для обработки повторяющихся ключей. В любом случае я знаю, что не говорю того, чего вы не знаете, но это то, что я хотел бы видеть в пакете v3 go-yaml. Спасибо еще раз.

Все 11 Комментарий

Привет Сэм. Обоснование звучит разумно, и текущий список изменений тоже звучит хорошо. Мы должны немного поговорить об этих других проблемах, прежде чем тратить на них время, чтобы не тратить на это время зря.

Перед выпуском v3 нам также необходимо подумать об инструменте миграции. Он не должен фактически переносить код, но должен, по крайней мере, указывать, где искать потенциальные несовместимости.

Хорошо, звучит хорошо @niemeyer , но будет ли простого критические изменения, будет недостаточно, в конце концов, никто не сломается, если они продолжат использовать v2 ... Просто подумайте, что написание этого инструмента может быть довольно сложной задачей, чтобы получить это правильно.

Да, вполне возможно, нетривиально. Но противоположность этому - позволить любому другому разработчику самостоятельно выяснить, что может сломаться. Вместо этого люди, скорее всего, будут придерживаться версии 2, что тоже не очень хорошо.

Кстати, перечисленные выше изменения сами по себе тривиальны. Я бы сказал, что меньше 30 минут.

Хм, я думаю, что практически все, что использует Marshal v2 или Unmarshal , будет считаться неисправным в предлагаемой версии 3 до тех пор, пока оно не будет протестировано. В большинстве случаев Unmarshal по-прежнему будет работать, но дополнительно демаршалирует не встроенные анонимные элементы структуры, но Marshal будет выдавать совершенно другой результат ... Я не вижу общего способа проверить неисправность, не зная, что создали потребители данных этой библиотекой ожидают ...

Одна функция, которую я думаю, будет важной, будет иметь возможность настраивать библиотеку для обработки имен полей, анонимных структур и т. Д. По-разному. Фактически, вероятно, будет довольно легко предоставить 2 конфигурации по умолчанию, одна из которых json/encoding -подобна и будет включена по умолчанию, а другая - go-yaml/yaml.v2 -подобная. Например:

V2Config := yaml.Config{FieldNameTransform: yaml.LowercaseFieldNameTransform, AutoInlineAnonymousStructFields: false}
yaml.Configure(V2Config)
// or, just to tweak a single parameter away from default...
yaml.Configure(yaml.Config{AutoInlineAnonymousStructFields: false})

РЕДАКТИРОВАТЬ: приведенный выше код был отредактирован для ясности

Таким образом, если мы добавим жестко запрограммированный yaml.V2Config, для тех, кто хочет новую библиотеку, будет действительно простой путь обновления, но со старой конфигурацией без риска что-либо сломать.

Однако предложенное выше изменение не является полностью тривиальным, особенно для добавления достаточного количества тестовых примеров для различных комбинаций конфигурации. Я сделал удар в # 149, и, вероятно, я смогу просто настроить этот PR, чтобы достичь чего-то вроде вышеупомянутого. Обратите внимание, что для этого требуется отмена глобального кеша структур и его замена глобальным кодеком по умолчанию с собственным кешем, который становится недействительным при каждом изменении конфигурации.

Хм, я думаю, что практически все, что использует Marshal или Unmarshal v2, будет считаться неисправным в предлагаемой версии v3, пока это не будет протестировано. (...)

Это не просто техническая проблема. Существует вполне естественная тенденция к тому, что код никогда не обновляется. Если есть достоверная поломка, то инерция значительно возрастает. Если есть неизвестная, заведомо достоверная поломка, то инерция настолько велика, что мы вполне можем этого не делать.

У нас не может быть глобального флага, потому что в одном приложении разные пакеты могут зависеть от разного поведения. Тем не менее, у нас может быть локальный флаг для yaml.Decoder и yaml.Encoder, аналогичный json.Encoder / Decoder. Собственно, с этого я и начну. Добавьте в v2 флаг совместимости. Это приносит пользу всем, без поломок. В конце концов, мы можем ввести v3, который имеет этот режим по умолчанию, и убрать старую логику.

Как человек, пользующийся библиотекой, я хочу прежде всего поблагодарить вас за библиотеку и проделанную вами работу. Говоря только о себе, мне бы очень хотелось, чтобы кодировщик и декодер были экспортированы для потокового использования. На мой взгляд, это решит проблему № 154 и будет вести себя больше как пакеты python и ruby ​​yaml (т.е. обновить значение базовых ключей новым значением, фактически игнорируя первое). Позвольте пользователю реализовать свою собственную бизнес-логику для обработки повторяющихся ключей. В любом случае я знаю, что не говорю того, чего вы не знаете, но это то, что я хотел бы видеть в пакете v3 go-yaml. Спасибо еще раз.

Выпуск № 215 с доступным патчем !! https://github.com/go-yaml/yaml/pull/218 должен стать частью V3, если не раньше :)

Если эта проблема все еще рассматривается на каком-либо уровне, то я бы добавил еще один пункт - добавить поддержку сортировки объектов json.Number виде чисел, а не строк, чтобы соответствовать поведению encoding/json .

Вот пример программы, демонстрирующей разницу в поведении между yaml.v2 и encoding/json :

package main

import (
    "encoding/json"
    "fmt"
    "strings"

    "gopkg.in/yaml.v2"
)

func main() {
    jsonObj := `{"num":13}`

    decoder := json.NewDecoder(strings.NewReader(jsonObj))
    decoder.UseNumber()

    var unmarshalled map[string]interface{}
    if err := decoder.Decode(&unmarshalled); err != nil {
        panic(err)
    }
    fmt.Printf("%+v\n", unmarshalled)       // map[num:13]
    fmt.Printf("%T\n", unmarshalled["num"]) // json.Number

    bytes, err := json.Marshal(unmarshalled)
    if err != nil {
        panic(err)
    }
    fmt.Println(string(bytes)) // {"num":13}

    bytes, err = yaml.Marshal(unmarshalled)
    if err != nil {
        panic(err)
    }
    fmt.Println(string(bytes)) // num: "13"
}

Желательно, чтобы последняя строка выводила num: 13 а не num: "13" .

231 - еще одна открытая проблема, связанная с тем, чтобы сделать поведение более согласованным с encoding/json .

+1 было бы неплохо, если бы yaml -> json -> yaml работал так же.

Работа над v3 началась, и скоро у меня будет что-то готовое для тестирования.

Приведенные выше примечания принимаются во внимание, но сейчас я закрою это, поскольку это становится просто указателем на другие проблемы.

Была ли эта страница полезной?
0 / 5 - 0 рейтинги

Смежные вопросы

ldesplat picture ldesplat  ·  6Комментарии

johscheuer picture johscheuer  ·  13Комментарии

rojer picture rojer  ·  4Комментарии

niemeyer picture niemeyer  ·  6Комментарии

dmandelin picture dmandelin  ·  11Комментарии