Обновить
38
0

Пользователь

Отправить сообщение

Лично в моей рабочей директории несколько десятков проектов только на ноде, и большинство из них живые. Есть ещё проекты, которые создаются временно для каких-нибудь экспериментов и потом благополучно удаляются. И да, почти каждый из них тянет за собой 300-500 dev-зависимостей, без которых неудобно работать с проектом. Но вот pnpm, отнюдь - не панацея. Глобальный набор зависимостей имеет свои минусы вроде отстуствия возможности по-быстрому подправить что-то прямо в исходнике установленного пакета при отладке или быстрой тотальной замены зависимостей. Но, кому-то, безусловно, подойдёт.

Не одному, но то, что будут отдавать патчи в апстрим, всё-таки верится. У нас же тут квоты на отечественное железо, а, следовательно, Linux, ну и, понятное дело , проще найти уязвимость и отдать в апстрим, чем каждую версию патчить, хотя, кто знает, можно же просить денег у казны на поддержку...

К сожалению, уровень технической подготовки клиентов таков, что все, что не работает из коробки для них сложно, а клиент, как известно, всегда прав. Им проще приобрести продукцию конкурента, чем заморачиваться с настройкой нашего решения, но что-то определенно, придется решать.

Не везде и не всегда есть такая возможность. Вот мы поставляем программно-аппаратный комплекс, который должен работать, в том числе без наличия интернета и привязки к конкретным рабочим станциям, для этого и был выбран веб-интерфейс. Причем, некоторые комплекты запускаются "в космос", то есть посылкой в другой регион. И для нас https-only становится серьезной проблемой, так как браузеры на АРМ обновляют клиенты самостоятельно.

17 дюймов - это прямо царский монитор. Помню как Win95 прекрасно умещалась на 13 дюймах, позднее, 14 и 15, а вот доступные 17 это уже более поздняя эпоха.

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

Работал с ним в 2008, а история гласит, что появился он и вовсе в 2001. А вот стандарт, да, был принят в 2013. Но это же рувдс, у них от автора к автору качествео вычитки скачет.

Возможно, не все люди в мире пользуются смартфонами "одной яблочной компании".

Речь про то, как работает "из коробки", и про качество звука через Bluetooth. Так что, нет, я ничего не трогал.

Зря думаете. У меня BT-наушники в linux хотя бы с ходу заработали, как и у вас, да, качество звука заметно, что не то, и автоматическое переключение режимов порой работало не в самый подходящий момент, а вот а винде, через какое-то время работы (20-30 минут) начинались щелчки, которые только усиливались со временем и решалось, да и до сих пор решается, отключением устройств "микрофон" и "головная гарнитура" в панели управления.

Это я ни к коем случае не хочу сказать, что в linux с bt все хорошо, скорее, что везде не демктопах одинаково плохо.

Такое чувство, что вы описали свои ощущения от пользования GNOME. К счастью, есть друг е популярные DE, которые не ломают пользовательский опыт каждый второй релиз. А вот насчёт точек восстановления, поправьте, если ошибаюсь, но в той же Ubuntu что-то такое было, кажется, и уже довольно давно как и своп файл.

Ну так берите сертифицированные устройства хоть под Ubuntu, хоть под RHEL, покупайте платную поддержку и будете приятно удивлены. А то, о чем вы говорите - "цена свободы выбора". Не хотите платить деньгами - платите своим временем.

Вы аппелируете к Community Help Wiki, где кто-то неравнодушный с десяток лет назад по доброте душевной оставил эти инструкции. Если коротко, то вы почему-то требуете от бесплатного продукта поддержки платного уровня. Выше в комментариях оставили ссылку на сертифицированные устройства, вот их и надо брать, чтоб "все гарантированно из коробки", а во всех остальных случаях это будет хакинтош.

Возможно, мое мнение субъективно, но когда говорят про то, что Linux готов к десктопу, то имеют ввиду отсутствие различных детских болячек, которые раньше не позволяли нормально пользоваться даже на совместимом железе. Сейчас, если компоненты подобраны корректно (открою вам секрет Полишинеля: некоторые производители устройств, в том числе, периферийных, официально пишут о совместимости устройств с семейством GNU/Linux, хотя некоторые и кривят душой, поставляя блобы драйверов под устаревшие ядра), то все, действительно, работает из коробки.

Я тут тоже пару экспериментов поставил и получил в результате что-то вроде версии 2.0, которая как раз возвращает объект, как у вас, но делает это только в конце, и функцию, которая преобразует в тот вид, что был у меня ранее для тех случаев, когда удобно получать именно значение, и даже порядок правил теперь прямой без массива. Осталось документацию обновить. А что касается строгого равно, так в js это нынче норма, лично я его везде "по умолчанию" использую, как и const вместо let. Без оного и null от undefined не отличить, так что я бы сказал, что в мире js что-то вроде true | ErrorType - тоже норма, но я тут пораскинул мозгами и решил, что кто-то может ожидать именно строго один тип объекта, и преобразовать объект в смешение типов проще, чем наоборот. Так что ещё раз спасибо за разъяснения.

Даже не знаю - что вам ответить, вроде как вся статья посвящена тому - почему такие решения, как Zod, не всем подходят, но за ссылку спасибо - буду иметь ввиду и эту библиотеку, однако размер пакета там не 9кб, а 470кб. А вот почему не подходят всякие vee-validate, я, вроде бы, достаточно ясно описал. Далеко не всегда удобно привязывать валидацию к представлению, для больших и сложных форм, состоящих из нескольких компонентов лучше делать это на уровне данных.

По всей видимости, мыслю свою мне донести в статье не удалось - надо учиться внятней писать.

Наверное, я неверно выразился. Не сам валидатор, конечно, а ValidationResult. У вас isBoolean возвращает лямбду, которая при вызове дергает один из статических методов ValidationResult, которые, в свою очередь, возвращают новый экземпляр этого класса

static DidPassed<T>(){
	return new ValidationResult<T>(true)
}

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

Да и бесит когда начинаешь например вводить email а форма говорит что он не валидный после первого же символа.

Чтобы такого не было, я вызываю валидатор в первый раз после первого изменения поля в форме, то есть нажали Enter или произошла потеря фокуса.

Я на C++ пишу оптимизированную математику, и по опыту - баланс выразительность/оптимизированность надо загибать в выразительность- оптимизировать узкое место проще чем сделать код человекопонятным.

Согласен, сам применяю всякие ухищрения только там, где это влияет на скорость работы заметно, понятно, что переписывать обработку массива из 10 элементов через for вместо reduce нет смысла. Быть может, вы и правы - удобнее получать на выходе объект, но как-то пока не могу себя убедить в том, что это даст какие-то ощутимые плюсы. Я исходил из той мысли, что решение должно быть максимально простым.

В общем, если вас не затруднит, можете более подробно описать преимущества возврата именно вот такого подобия монады? Кроме очевидного отсутствия ограничений на тип ErrorType, конечно.

Позволил себе немного переписать ваш вариант таким образом, чтобы он больше соответствовал моему видению. Минус, по-моему, тут только в том, что нужно явно каждый раз передавать значение сообщения, уже не получится просто автоматом как true/false использовать.

По правде говоря, я - тоже не настоящий TS разработчик, так, периодически приходится. Что касается каста string в boolean, то он происходит, только если делать нестрогое сравнение (==), а строгое сравнение работает без приведения типа (===). То, что вы накидали по ссылке, я уже встречал, но мне такой подход не сильно нравится, и вот почему: мы создаем экземпляр класса на каждое правило, причем не разово, а при каждом вызове каждого правила. Если вспомнить, что вся цепочка - это проверка лишь одного поля, которая должна повторяться при каждом изменении значения, то штука выглядит довольно накладной. Вместо списка мы получили массив, что, в принципе, почти равноценная замена, даже имеет плюс в том, что можно легко выстроить цепочку привычным образом слева-направо. А вот реализация правил выходит уже не такой удобной - дополнительная фабрика, да и, внешние правила, получается, должны знать о ValidationResult, то есть появляется ненужная, как по мне, связь, ведь сами правила довольно просты. Впрочем, последний пункт можно попытаться обыграть, понятно, что это - набросок.

Думаю, не сильно ошибусь, если скажу, что вы пишите на Haskell или Scala - от решения просто веет ФП. Не подумайте только, что я что-то против имею, просто, как мне кажется, несмотря на наличие всяких функциональных примочек в JS - он плохо переваривает чисто функциональные решения, map, forEach, reduce, и т.д. сильно медленнее for, и, полагаю, что для такой маленькой, но много раз вызываемой части лучше подумать немного об оптимизации. Впрочем, я тут сам хорош - вместо массива использую односвязный список и тоже создаю экземпляры Validator, но только одиножды - при создании цепочки.

Посмотрел на ваше решение, взвесил за и против, и, пожалуй, не вижу большой проблемы в том, чтобы исключить типs boolean и Function из ErrorType. Субъективно, это - меньшее зло, чем генерировать массу экземпляров на каждый вызов.

И, должен сказать спасибо за веское замечание об изначально неверном выборе `boolean | string` - уже переписал с использованием дженериков, завтра на свежую голову подправлю статью.

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

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

type Error<T> = T extends boolean ? never : T extends Function ? never : T;
function check<T = string, E extends Error<T> = Error<T>>(value: any, context: any): boolean | E;

Таким образом, если задать в качестве типа T boolean или Function - то мы увидим, что тип значения never. Потому что параметр message у нас опционален, и еще может быть фабрикой. А если мы message не указываем, то возвращает true или false.

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

Конечно, он решает мои проблемы, как и все решения, которые разработаны кем-либо - решают их проблемы, даже если эта проблема звучит как "найти универсальное решение", коих, как известно, не бывает.

Отобразить красиво или через API - это, пожалуйста, снаружи - ничего не мешает обернуть вызов. Что касается кодирования ошибки или какого-то более сложного типа, то да, в этом смысл, но не все так однозначно. Добавить тип number - быть может, было бы разумно (issues на гитхаб доступны для всех), а вот any - уже не так удобно, ведь это ломает смысл использования TS. Определить тип Valid как некоторый шаблонный тип, который, по дефолту равен true - можно, но тогда нужно еще требовать передавать внутрь либо функцию сравнения, которая будет возвращаеть булевый результат в виде валидно/не валидно - выполнение цепочки ведь должно быть управляемым, и мы хотим остановиться при первом невалидном результате, вернув именно его ошибку. Получается, что смысла делать положительную проверку отличной от true нет смысла, потому что положительная проверка - единственный результат, а вместо строки, да, можно использовать <T>, но тут, опять же, github открыт - будет запрос - будет результат какой-то. А обернуть положительную проверку в объект или что-то иное, опять же, можно и нужно снаружи.

В более унифицированном варианте сигнатура у check должна получиться примерно такой, если я правильно понимаю ваши требования:

type Error<T> = T extends boolean ? never : T;

function check<T = string, E extends Error<T> = Error<T>>(value: any, context: any = {}): boolean | E;

Можно и попроще сделать:

function check<T = string>(value: any, context: any = {}): true | T;

но тогда будет шанс того, что отличить результат с ошибкой (`true`) от корректного значения типа T (тоже true) будет нельзя.

Не понимаю только, почему вы мне предлагаете искать какое-то еще решение? Если оно у вас есть - поделитесь. Если нет - мы не на экзамене, и у меня достаточно забот помимо. Имеющееся решение я описал, считаю вашу критику вполне объективной и буду рад вашему вкладу в улучшение решения.

Информация

В рейтинге
Не участвует
Зарегистрирован
Активность