Концепция интересная: каждая следующая команда имеет на входе результат предыдущей , поэтому вместо обычной записи c(b(a())) можем иметь более наглядную а -> b -> c
Так это обычный pipe-оператор, который является одной из основных синтаксических конструкций в таких языках как Elixir и F#
На том же Elixir есть Flow - библиотека для потоковой обработки. Вот например, как посчитать частоту употребления слов в текстовом документе:
path_to_file
# потоковое чтение из файла
|> File.stream!()
# использовать IO-поток в качестве продьюсера для Flow
|> Flow.from_enumerable()
# разбить каждую строку по пробельным символам
|> Flow.flat_map(fn(line) -> String.split(line, ~r/\s+/) end)
# распараллелить дальнейшую обработку на несколько потоков
|> Flow.partition()
# отфильтровать то, что не является словами
|> Flow.filter(fn(word) -> Regex.match?(~r/^[\w-]+$/iu, word) end)
# выполнить свёртку с подсчётом слов
|> Flow.reduce(fn -> %{} end, fn(word, acc) ->
Map.update(acc, word, 1, fn(count) -> count + 1 end)
end)
# преобразовать в список - реальные вычисления инициируются тут
|> Enum.to_list()
# отсортировать результат по убыванию частотности слов
|> Enum.sort(fn({_w1, count1}, {_w2, count2}) -> count1 >= count2 end)
А как эту же задачу решить на Neva?
P.S. Другое дело, что несмотря на удобство pipe-оператора писать 100% кода только в этом стиле - это неудобно. Поэтому глупо весь язык под это затачивать.
Могу подтвердить, что HRы и нанимающие менеджеры обсуждают почти всегда только gross, так что он имеется в виду по умолчанию.
Сотрудники между собой может и обсуждают "на руки", но мы тут обсуждаем что сказала руководитель команды IT-рекрутинга. К гадалке не ходи, она говорила про gross. Тут вообще без вариантов.
Она написала что это потолок для лида. Откуда следует что там есть выше?
Бывают такие случаи, когда компания не нанимает выше середины вилки.
Ну, раз уж вы выбрали Коми, то вот вам варианты до 5 млн в местной столице на ДомКлик
Понятно, что автор исходного коммента несколько утрировал ситуацию, но и вы зачем-то додумали, что речь про Москву. А Россия за садовым кольцом не заканчивается.
Давайте проверим, только не со слов (не будем опираться на личный опыт), а источником: Хабр Карьера. Результат перед вами.
Хабр Карьера показывает нетто, а в разговорах HR всегда говорят о брутто.
На скриншоте видно, что наибольшее кол-во джунов (80%) попали в диапазон 73.5 - 140 т.р. брутто.
Ну, т.е. корректнее было сказать, что вилка для начинающих специалистов остается в пределах 70-140 т.р. за редким исключением.
Так ли велика проблема, что Анастасия промахнулась на 10 т.р. при размахе диапазона в 70 т.р.? По-моему нет, тем более что от компании к компании, а также от стека (для той же Java диапазон 90-160k gross) это может варьироваться.
Что ж ты сидишь страдаешь на таком плохом Хабре? Понятно, что на зарубежных форумах тебе прямым текстом не скажут, что ты токсичный дурачок с раздутым самомнением. Там толерантность такая, что нельзя ничего напрямую сказать.
А тут стоит твою карму посмотреть и уже всё понятно, вот ты и бесишься. По существу ничего ответить не можешь, только щёки раздуваешь «вот я, вот я - один д’Артаньян, а вы все думать не умеете» xD
P.S. Недостойно твоё подленькое поведение, чтобы с тобой на "Вы" общаться. Смирись. Ну, или меняйся к лучшему, чтобы с тобой можно было цивилизованную беседу вести.
Ну, прижали тебя по фактам, имей мужество признать свою ошибку. Но нет, извивается как уж на сковородке, лишь бы не признавать очевидного 🤦♂️
Сходи на elixirforum со своим кодом, там тебе точно так же скажут, что не надо код так писать. Нет, как наивный чудик, бегает по чужим веткам комментариев, пыжясь доказать, что кроме него никто думать не умеет. Просто пробиваешь новое дно с каждым твоим комментарием.
Вы так эпично обосрались с чтением книги вашего любимого автора, что теперь следите за всеми моими комментариями? xD
Я в отличии от вас освоил навык декомпозиции и уже больше 18 лет его применяю. А вы застряли на уровне джуновского пика глупости, и пытаетесь себя самого подсознательно убедить, что ваши простыни на сотни строк - это что-то приемлемое. Но нет, ваш говнокод останется говнокодом, сколько вы тут не пыжьтесь)
Однако, это будет не декомпозицией метода, а написание вообще отдельного функционала на уровне библиотеки или фреймворка.
Ну да, хороший фреймворк тем и отличается, что "из коробки" предусматривает возможность декомпозиции для популярных сценариев.
В вашем примере так же копируется строчка с render.
Да. Просто когда это же выражено более длинной записью `$this->responseFactory->createJsonResponse` это выглядит, как визуальный шум. В современном PHP есть возможность указать делегирование? Что мы, вызывая в контексте своего класса функцию createJsonResponse, автоматически делегируем обработку этого вызова в $this->responseFactory
В каких именно случаях нам передавать необязательный параметр? Что будет если я его не передам когда надо и передам, когда не надо (изменю дефолтное значение)?
Это всё элементарно решается: принимаем и мержим этот параметр в ответ вне зависимости от статуса. И указываем для него в качестве дефолтного значения пустой массив. Когда хочешь добавить пейлоада в ответ или переопределить дефолтное сообщение, тогда и передаёшь.
А именно метод buildLoginRespons не совсем соответствует принципу SRP т.к. занимается отправкой и удачных и ошибочных ответов.
Занимается отправкой ответов - это одна обязанность. Для браузера абсолютно параллельно какой там статус, так что странно их разделять на успешные и нет. И вообще хорошо, когда она совсем абстрагирована на уровне фреймворка, и функция render импортирована в твой контроллер. Тогда бы не пришлось бойлерплейт вида $this->responseFactory->createJsonResponseпостоянно дублировать и генерация ответа спокойно в 1 строку умещалась, а не в 4.
Тоже самое касается и валидации параметров. Она должна быть по-хорошему быть выделена за пределы экшена контроллера. И возвращать не boolean, а осмысленный список ошибок валидации, который можно сразу на фронт передать. И в идеале, чтобы была возможность её вообще в отдельную миддлевару вынести, тогда бы login сразу принимал валидные параметры.
И было бы что-то типа
public function login($params): ResponseInterface
{
// Authenticate user
$authResult = $this->authService->authenticate($params['username'], $params['password']);
if ($authResult->isSuccess()) {
return render('status' => 200, 'json' => ['token' => $authResult->getToken()]);
} else {
return render('status' => 401, 'json' => ['error' => 'Invalid credentials']);
}
}
Другими словами, изначально длинная функция не является необходимостью. Она является следствием 2 вещей: 1) непродуманной организации фреймворка 2) недостаточной выразительности языка
Так же странным выглядит момент с resp_params который вроде обязательный аргумент
Очевидно же из контекста, что он опциональный. Я просто не помню, как в PHP опциональные аргументы объявляются. И в явном виде об этом написал в комментарии.
У вас странное представление о декомпозиции. Изначальная функция занималась разбором параметров, их валидацией, аутентификацией по логину и паролю и формированием HTTP-ответа. Вот по этим аспектам и надо разделять, а не тупо каждую строку в отдельную функцию выделять.
public function login(ServerRequestInterface $request): ResponseInterface
{
$params = $request->getParsedBody();
// Validate request parameters
if (!$isValidLoginParameters($params)) {
return buildLoginResponse(400);
}
// Authenticate user (мы ж уже проверили, что всё валидно, зачем ещё раз на null проверять?)
$authResult = $this->authService->authenticate($params['username'], $params['password']);
if ($authResult->isSuccess()) {
return buildLoginResponse(200, ['token' => $authResult->getToken()]);
} else {
return buildLoginResponse(401);
}
}
function isValidLoginParameters($params): boolean
{
$isValidParameters = $this->validator->isValid($params, [
'username' => 'required|string',
'password' => 'required|string',
]);
return $isValidParameters;
}
function buildLoginResponse($code, $resp_params): ResponseInterface
{
switch ($code) {
case 200:
return $this->responseFactory->createJsonResponse(
200,
array_merge(['message' => 'Login successful'], $resp_params)
);
case 400:
return $this->responseFactory->createJsonResponse(
400,
['error' => 'Invalid request parameters']
);
case 401:
return $this->responseFactory->createJsonResponse(
401,
['error' => 'Invalid credentials']
);
}
}
P.S. Возможны ошибки синтаксиса, т.к. я в прошлый раз на PHP писал в 2009-м, но суть идеи, думаю, понятна.
Я вам фрагмент из книги предоставил, в котором прямым текстом написано, что ваш подход к структурированию кода является типичной ошибкой. При этом вы самонадеянно утверждали, что там не может быть такого написано. Но признать, что вы облажались, у вас силы духа не хватает. Вот и пытаетесь нелепо съехать с темы, переходя на личности. Это ещё один тупой мув в стиле джуна, потому что вы обо мне ничего не знаете. И выглядите во всей этой ветке максимально тупо и нелепо xD
Программисты как раз пишут алгоритмы, а кодеры кодят бизнес-логику.
Это крайне наивный взгляд)
Особенно забавно, что вы всерьёз думаете, что вы какие-то принципиально новые алгоритмы придумываете для своих библиотек. Хотя просто кодируете уже давно придуманные, как заправский техник.
Исключения конечно возможны, но тогда хотя бы ссылочку на диссертацию свою скиньте - почитаем какую вы там научную новизну в алгоритмы привнесли.
Вы не баг подсветили, а отрезали пользователям задокументированную возможность использовать свой синтаксис
Хотели сказать "незадокументированную" xD
Ни в самом коде, ни в README нет ни явного указания на кастомный синтаксис, ни примеров его создания. Просто по сути ещё один аргумент накинули, почему ваш код плох - содержит незадокументированные и не покрытые тестами "возможности".
у меня такое количество коммитов в корку эликсира
Ну, раз начали понтоваться, то пишите уж ваш ник на Github - посмотрим, как вы в корку эликсира функции по 50+ строк пропихивали. А то пустое сотрясание воздуха.
Так это обычный pipe-оператор, который является одной из основных синтаксических конструкций в таких языках как Elixir и F#
На том же Elixir есть Flow - библиотека для потоковой обработки. Вот например, как посчитать частоту употребления слов в текстовом документе:
А как эту же задачу решить на Neva?
P.S. Другое дело, что несмотря на удобство pipe-оператора писать 100% кода только в этом стиле - это неудобно. Поэтому глупо весь язык под это затачивать.
Да, можно вместо th расслаблено произносить d и носители вас прекрасно поймут.
А в чём смысл этой статьи? Вы хотя бы небольшой обзор языка сделали бы, с примерами и т.д.
Могу подтвердить, что HRы и нанимающие менеджеры обсуждают почти всегда только gross, так что он имеется в виду по умолчанию.
Сотрудники между собой может и обсуждают "на руки", но мы тут обсуждаем что сказала руководитель команды IT-рекрутинга. К гадалке не ходи, она говорила про gross. Тут вообще без вариантов.
Бывают такие случаи, когда компания не нанимает выше середины вилки.
Ну, раз уж вы выбрали Коми, то вот вам варианты до 5 млн в местной столице на ДомКлик
Понятно, что автор исходного коммента несколько утрировал ситуацию, но и вы зачем-то додумали, что речь про Москву. А Россия за садовым кольцом не заканчивается.
Так и есть. 2 месяца назад с ним подобную переписку вёл https://habr.com/ru/articles/855102/comments/#comment_27568354
Смотрю комменты к этой статье, а воз и ныне там(
Так он и не писал про Мск. Например, где-нибудь в Бологое 2 однушки вполне реально взять за год.
Хабр Карьера показывает нетто, а в разговорах HR всегда говорят о брутто.
На скриншоте видно, что наибольшее кол-во джунов (80%) попали в диапазон 73.5 - 140 т.р. брутто.
Ну, т.е. корректнее было сказать, что вилка для начинающих специалистов остается в пределах 70-140 т.р. за редким исключением.
Так ли велика проблема, что Анастасия промахнулась на 10 т.р. при размахе диапазона в 70 т.р.? По-моему нет, тем более что от компании к компании, а также от стека (для той же Java диапазон 90-160k gross) это может варьироваться.
Ну, естественно это джун, а кто ж ещё. Откуда взялась мода думать, что джун - это плохой/некомпетентный сотрудник? Джун - это начинающий специалист.
А почему без опыта? До 2 лет опыта - это тоже джун (начинающий специалист).
Что ж ты сидишь страдаешь на таком плохом Хабре? Понятно, что на зарубежных форумах тебе прямым текстом не скажут, что ты токсичный дурачок с раздутым самомнением. Там толерантность такая, что нельзя ничего напрямую сказать.
А тут стоит твою карму посмотреть и уже всё понятно, вот ты и бесишься. По существу ничего ответить не можешь, только щёки раздуваешь «вот я, вот я - один д’Артаньян, а вы все думать не умеете» xD
P.S. Недостойно твоё подленькое поведение, чтобы с тобой на "Вы" общаться. Смирись. Ну, или меняйся к лучшему, чтобы с тобой можно было цивилизованную беседу вести.
Ну, прижали тебя по фактам, имей мужество признать свою ошибку. Но нет, извивается как уж на сковородке, лишь бы не признавать очевидного 🤦♂️
Сходи на elixirforum со своим кодом, там тебе точно так же скажут, что не надо код так писать. Нет, как наивный чудик, бегает по чужим веткам комментариев, пыжясь доказать, что кроме него никто думать не умеет. Просто пробиваешь новое дно с каждым твоим комментарием.
Вы так эпично обосрались с чтением книги вашего любимого автора, что теперь следите за всеми моими комментариями? xD
Я в отличии от вас освоил навык декомпозиции и уже больше 18 лет его применяю. А вы застряли на уровне джуновского пика глупости, и пытаетесь себя самого подсознательно убедить, что ваши простыни на сотни строк - это что-то приемлемое. Но нет, ваш говнокод останется говнокодом, сколько вы тут не пыжьтесь)
Ну да, хороший фреймворк тем и отличается, что "из коробки" предусматривает возможность декомпозиции для популярных сценариев.
Да. Просто когда это же выражено более длинной записью `$this->responseFactory->createJsonResponse` это выглядит, как визуальный шум. В современном PHP есть возможность указать делегирование? Что мы, вызывая в контексте своего класса функцию createJsonResponse, автоматически делегируем обработку этого вызова в $this->responseFactory
Это всё элементарно решается: принимаем и мержим этот параметр в ответ вне зависимости от статуса. И указываем для него в качестве дефолтного значения пустой массив. Когда хочешь добавить пейлоада в ответ или переопределить дефолтное сообщение, тогда и передаёшь.
Занимается отправкой ответов - это одна обязанность. Для браузера абсолютно параллельно какой там статус, так что странно их разделять на успешные и нет. И вообще хорошо, когда она совсем абстрагирована на уровне фреймворка, и функция render импортирована в твой контроллер. Тогда бы не пришлось бойлерплейт вида
$this->responseFactory->createJsonResponseпостоянно дублировать и генерация ответа спокойно в 1 строку умещалась, а не в 4.Тоже самое касается и валидации параметров. Она должна быть по-хорошему быть выделена за пределы экшена контроллера. И возвращать не boolean, а осмысленный список ошибок валидации, который можно сразу на фронт передать. И в идеале, чтобы была возможность её вообще в отдельную миддлевару вынести, тогда бы login сразу принимал валидные параметры.
И было бы что-то типа
Другими словами, изначально длинная функция не является необходимостью. Она является следствием 2 вещей:
1) непродуманной организации фреймворка
2) недостаточной выразительности языка
Очевидно же из контекста, что он опциональный. Я просто не помню, как в PHP опциональные аргументы объявляются. И в явном виде об этом написал в комментарии.
У вас странное представление о декомпозиции. Изначальная функция занималась разбором параметров, их валидацией, аутентификацией по логину и паролю и формированием HTTP-ответа. Вот по этим аспектам и надо разделять, а не тупо каждую строку в отдельную функцию выделять.
P.S. Возможны ошибки синтаксиса, т.к. я в прошлый раз на PHP писал в 2009-м, но суть идеи, думаю, понятна.
Я вам фрагмент из книги предоставил, в котором прямым текстом написано, что ваш подход к структурированию кода является типичной ошибкой. При этом вы самонадеянно утверждали, что там не может быть такого написано. Но признать, что вы облажались, у вас силы духа не хватает. Вот и пытаетесь нелепо съехать с темы, переходя на личности. Это ещё один тупой мув в стиле джуна, потому что вы обо мне ничего не знаете. И выглядите во всей этой ветке максимально тупо и нелепо xD
Это крайне наивный взгляд)
Особенно забавно, что вы всерьёз думаете, что вы какие-то принципиально новые алгоритмы придумываете для своих библиотек. Хотя просто кодируете уже давно придуманные, как заправский техник.
Исключения конечно возможны, но тогда хотя бы ссылочку на диссертацию свою скиньте - почитаем какую вы там научную новизну в алгоритмы привнесли.
Бла-бла-бла от очередного джуна на пике глупости. Не интересно время больше тратить на то, чтобы вам ликбез проводить.
Хотели сказать "незадокументированную" xD
Ни в самом коде, ни в README нет ни явного указания на кастомный синтаксис, ни примеров его создания. Просто по сути ещё один аргумент накинули, почему ваш код плох - содержит незадокументированные и не покрытые тестами "возможности".
Ну, раз начали понтоваться, то пишите уж ваш ник на Github - посмотрим, как вы в корку эликсира функции по 50+ строк пропихивали. А то пустое сотрясание воздуха.