1. Ruby / Говнокод #24427

    0

    1. 1
    course = course_id > 0 ? Course.find(course_id) : nil

    стаж - это багаж. Senior

    Запостил: AlexKlim, 29 Июня 2018

    Комментарии (32) RSS

    • А вдруг course_id может быть нулем, а пустое значение - минус единица?
      Ответить
    • Я не знаю ORMки рельсовой: что будет если подать туда ID несуществующего объекта? nil или Exception?
      Если nil, то это правда говнокод.

      Впрочем, мы можем сэкономить лишний запрос типа SELECT * from Courses where id=0.
      Или рельсы умны и так не сделают?
      Ответить
    • у ActiveRecord есть метод find_by который сам выполнит все проверки если надо и вернет либо объект либо nil
      Ответить
      • так а лишнего запроса не будет?
        Ответить
        • нет, ни в коем случае
          Ответить
          • id = 0
            Course.find_by id: id

            Откуда он знает что не надо искать если id==0? Он умный и понимает что ID не может быть нулем?
            Он типа сразу вернет nil?

            Ну тогда правда говнокод
            Ответить
            • > Ну тогда правда говнокод

              я лично не согласен. Просто defensive programming.
              Ответить
              • и в чем же defensive programming в этом случае?
                Ответить
                • В том, что тому, кто читает код, проще проверить, что граничные случаи корректно обработаны, не заглядывая в документацию фреймворка нужной версии.
                  Ответить
                  • А ты когда в джаве итерируешься по листу или массиву ты проверяешь что он не пустой?

                    Ну, что бы читающему было проще проверить все граничные случаи не заглядывая в доку.
                    Ответить
                    • я Вас понял.
                      как я понимаю Вы с RoR не знакомы. данный метод с первых дней жизни. и часто на собеседованиях даже спрашивают отличия find & find_by это так сказать основы
                      Ответить
                      • > на собеседованиях даже спрашивают отличия find & find_by

                        Как страшно жыть
                        Чтож, не быть мне погромистом в вашей конторе.
                        Ответить
                        • Мне кажется ты зря иронизируешь.

                          Рельсовый ORM для RoR программиста примерно как знание Collections API в Java.
                          Я вполне верю что это азы платформы и их всегда спрашивают
                          Ответить
                          • > знание Collections API в Java

                            Т.е. ты считаешь, что вопрос вроде

                            В чём отличие list.remove(0) от list.remove(Integer.valueOf(0))?

                            адекватен для собеседований?
                            Ответить
                            • Скорее уж "как поведет себя list.remove(-1)".

                              У RoR вон на сайте написано что
                              find и find_by! кидаются RecordNotFound
                              а find_by вертает nil

                              Учитывая тот факт что 80% программирования на RoR это вызов методов ORM find и find_by я думаю что это адекватный вопрос
                              Ответить
                              • > find и find_by! кидаются RecordNotFound
                                а find_by вертает nil

                                Ещё раз: у меня бомбит не от nil, а от того, что "лишнего запроса не будет".

                                Пошёл, посмотрел доку на оф. сайте http://api.rubyonrails.org/classes/ActiveRecord/FinderMethods.html#method-i-find_by

                                Ничего про особую обработку id:0 не сказано.

                                Мне кажется, вы всё врёти, а сеньёр героически сыкономил запрос.

                                https://github.com/rails/rails/issues/5982 lol
                                Ответить
                                • >>у меня бомбит не от nil, а от того, что "лишнего запроса не будет".
                                  ну если 0 не валидный id то почему нет?

                                  >>Мне кажется, вы всё врёти,
                                  Я не умею RoR, я немного умею Ruby и всякие похожести вроде Django, так что верю топикстартеру
                                  Ответить
                                  • > ну если 0 не валидный id то почему нет?

                                    Потому что БД должна решать, валидный это id или нет, а не ОРМ.

                                    Опять же, в доке ни слова про id:0, поэтому никакого особого говна в коде в топике не вижу.
                                    Ответить
                                    • >>Потому что БД должна решать, валидный это id или нет, а не ОРМ.
                                      RoR ORM расчитана на определенную структуру в базе, которую она создает

                                      Она не может работать со случайной структурой, это же понятно
                                      Ответить
                                      • Т.е., если я через их ORM эту колонку объявил как "целое число от 0 до 9", то она будет считать 0 валидным, а если как "целое число от 1 до 10" -- то не будет и даже не кинет запрос в базу? До чего дошёл прогресс...

                                        Или эта механика захардкожена только для id?
                                        Ответить
                                        • Понятия не имею, но думаю что да, может.

                                          RoR же знает всё про твою таблицу.
                                          Ответить
              • погоди, у нас контракт: передал 0 -- получит nil.
                Где тут defensive?

                Тут даже exceptionа не будет, не говоря уже о порче памяти (руби же)

                зы: а! ты наверное подумал что я назвал говнокодм функцию "find_by"?

                Вовсе нет! Я имел ввиду код в топике) прочитай всю ветку
                Ответить
                • У меня как раз к коду в топике претензий нет, а вот дизайн find_by, который для нуля даже запроса не сделает, вызывает большие сомнения.
                  Ответить
                  • Вполне себе в духе ruby.

                    Очень много чего получил мусор возвращает nil в ruby, objc, swift, вот недавно узнал что и в lua тоже
                    Ответить
                    • С каких пор 0 - это мусор? Вот nil это мусор и всегда был.
                      Ответить
                      • С тех пор как придумали контракт.

                        Смотри: я могу в контракте функции написать "передавать сюда только положительное число" или "передавать только число от 1 до 12" или "передавать только инстанс класса Foo".

                        Как должна вести себя функция, в которую передали что-то не то и это статически не проверилось (ну в руби у нас вообще стат типизации нет, могли и строку передать)?

                        Она может:
                        * кидать Exception (это защитное программирование и есть кмк)
                        * делать мусор (как сделает си, например)
                        * возвращать nil.

                        Если в RoR принято "возвращать nil" на всякую чушь то это вполне логичный и ожидаемый контракт

                        А как бы ты сделал? Кинул бы exception?

                        Я думаю что возврат nil позволяет экономить место. Например, "foo".to_i в руби == 0
                        То-есть любой мусор при преобразовании в Integer = 0.
                        Даже nil.to_i будет 0.

                        Так что какой бы мусор ты ни передал туда -- он превратится в 0, и будет nil
                        Ответить
                        • Я так понимаю, "контракт" тут немного другой:

                          1. Все записи в базе создаются через ОРМ
                          2. Если вы создали что-то не через ОРМ, то вы можете этого потом не найти, т.к. в ОРМ есть куча неявных допущений, завязанных на пункт 1.
                          Ответить
                          • Да, разумеется. Если у вас ID это signed int и там лежит 0 или если у вас ID это char(255) и там лежит слово "pitushok" то ORM не будет работать.

                            Это же RoR, он сам таблицы создает
                            Ответить
              • > defensive programming
                Тогда надо было сначала спросить "а есть ли запись с таким id в таблице?" и только потом звать find().
                Ответить
                • А тут пролетал давеча код на 1С где чувак сначала получает запись, потом проверяет что она есть, и если есть то получает ее снова.

                  Что-то типа (пишу по памяти т.к. не знаю 1с)
                  Если Запрос.Выполнить().ЕстьРезультат() Тогда
                       Запрос.Выполнить().Первая()


                  Ну понятно что Выполнить() собссно _выполняет_ запроос
                  Ответить

    Добавить комментарий