Представляем Priora: утилиту приоритезации объектов для Ruby | Элиав Лави | Ruby Inside
TL;DR: я выпустил Priora , новый драгоценный камень, который помогает в удобной расстановке приоритетов коллекций объектов в Ruby! Проверьте это (GitHub/RubyGems).
В этом посте я расскажу о мотивах, дизайне и повестке дня, которые я выбрал при создании этой утилиты. Части этой истории были извлечены в файл README библиотеки на GitHub.
На днях коллега-разработчик спросил мое мнение по поводу одного запроса на включение. Она работала над задачей, которая требовала приоритезации массива объектов в соответствии с определенной бизнес-логикой. Я буду называть класс этих объектов Пост
в этой истории. Это класс данных, каждый экземпляр которого знает о author
, like_count
и is_sponsored
:
class Post
attr_reader :author, :like_count, :is_sponsoreddef initialize(author:, like_ кол-во:, is_sponsored:)
@author = автор
@like_count = like_count
@is_sponsored = is_sponsored
end
end
Мой коллега придумал специальный класс обслуживания для решения задачи расстановки приоритетов и спросил меня, что я думаю об этом подходе. Она объяснила, что столкнулась с некоторыми особенностями и различными деталями, о которых нужно было позаботиться при реализации процедуры расстановки приоритетов, и это заставило ее почувствовать, что выделенный класс был правильным решением. После ознакомления с различными бизнес-требованиями я спросил ее, действительно ли эти объекты сортируются сами по себе: возможно, вместо дополнительного класса для управления приоритетами она могла бы реализовать оператор космического корабля (
<=>
) после Post
, а затем просто отсортируйте и переверните массив.
Увы, логика расстановки приоритетов экземпляров Post
, требуемая в этой задаче, не была валидной в глобальном масштабе: стало очевидно, что другие применения этого класса имеют другие потребности в сортировке. Следовательно, невозможно было определить <=>
по Post
. Ruby предлагает Enumerable#sort_by
, который принимает блок для предоставления пользовательской схемы сортировки, которая могла бы подходить конкретно для рассматриваемого случая, но затем возникла другая проблема — некоторые атрибуты для определения приоритета массива были логическими. , и они не сортируются из коробки. Другие языки неявно конвертируют
true
на 1 и false
на 0 и, таким образом, разрешить их сортировку; Руби, однако, нет.
Поскольку об исправлении TrueClass
и FalseClass
не могло быть и речи, другим вариантом было преобразование этих значений ad-hoc. Интуитивно это казалось мне слишком сложным: этот класс приоритизации делал слишком много вещей, а фактические атрибуты для приоритизации были затенены отдаленно связанным кодом. Я сказал своему коллеге, что мне нужно время, чтобы подумать об этом.
Так как я не в первый раз сталкиваюсь с такой проблемой, я подумал, что было бы неплохо иметь служебную библиотеку, которая помогала бы расставить коллекции по приоритетам. В то время как сортировка как концепция хорошо известна благодаря изучению информатики и курсам по алгоритмам, расстановка приоритетов не является ее синонимом, , поскольку она находится на один абстрактный уровень выше; расстановка приоритетов — это использование сортировки для применимых целей («бизнес-логика») таким образом, чтобы наиболее важные объекты в коллекции располагались первыми. Я искал существующее решение на RubyGems и в Интернете, но не нашел того, что искал, поэтому решил записать его сам и придумал Приора .
Мне нужен был простой способ сортировки объектов данных в соответствии с приоритетами, которые в основном представляют собой точки данных, раскрываемые объектами (также известные как геттеры), без хлопот с преобразованием true,
false
и nil
в сортируемые значения. Я также хотел иметь возможность определять приоритеты для класса фиксированным способом, но достаточно гибкий API, чтобы разрешать специальные вызовы со списком приоритетов в качестве параметра.
Priora в действии
Для демонстрационных целей возьмем три Опубликовать
экземпляров с различными атрибутами:
low_like_count_sponsored = Post.new(автор: 'Jay C.',
like_count: 10, is_sponsored: true)high_like_count_unsponsored = Post.new(автор: 'Aaron R.',
like_count: 90, is_sponsored: false)high_like_count_sponsored = Post.new(автор: 'Don Y.',
like_count: 90, is_sponsored: true)
Используя Priora, мы можем легко расставить приоритеты в коллекции в соответствии с нашими потребностями:
unprioritized_array = [high_like_count_unsponsored, low_like_count_sponsored, high_like_count_sponsored]prioritized_array = [high_like_count_sponsored, high_like_count_unsponsored, low_like_count_sponsored]Priora.prioritize(unprioritized_array, by: [:like_count, :is_sponsored]) = = приоритетный_массив
=> true
В этом примере показано, как Priora.prioritize
принимает коллекцию без приоритетов и список приоритетов. Последний передается через параметр на
. Он ожидает массив символов, геттеров, которые представляют желаемую логику приоритизации. В этом примере мы хотим, чтобы объектов Post
с наибольшим количеством лайков были первыми, а спонсируемые посты имели второстепенный приоритет в случае, если два или более объекта Post
имеют одинаковые количество лайков
.
В случае, если мы можем зафиксировать приоритет между объектами Post
— т.е. нам не нужна гибкость изменения приоритетов каждый раз (чего не было у моего коллеги) — мы можем включить модуль Priora
в наш класс и объявить фиксированные приоритеты с помощью макроса класса Prioritize_by
и получить более короткий вызов позже. Тогда наш класс будет выглядеть так:
класс Post
включает Priora
Prioritize_by :like_count, :is_sponsored attr_reader :author, :like_count, :is_sponsored def initialize(author:, like_count:, is_sponsored:)
@author = author
@like_count = like_count 9000 5 @is_sponsored = is_sponsored
end
end
И получение приоритетного массива будет выглядеть так:
Priora.prioritize(unprioritized_array) == Prioritized_array
=> true
Использование Prioritize_by
макрос класса повышает читабельность кода за счет гибкости . Используя его, приоритеты объявляются
в классе, и Priora может получать их неявно. В некоторых случаях это может быть правильным выбором, в то время как для других больше подходит явный стиль.
Хотя может показаться, что эта опция определяет оператора космического корабля для включенного класса, на самом деле это не так. Единственное, что он делает, это сохраняет объявленные приоритеты в переменной класса-экземпляра, что позволяет Priora использовать их позже.
В качестве эквивалентного решения можно придумать следующий фрагмент кода:
unprioritized_array.sort { |a, b|
[a.like_count, a.is_sponsored ? 1 : 0] <=>
[b.like_count, b.is_sponsored ? 1 : 0] }.reverse == Prioritized_Array
=> true
Что, конечно, правильно. Однако я обнаружил несколько проблем с этим кодом:
- Он более многословен и подвержен ошибкам.
- Дважды объявляет логику определения приоритетов. Мы не можем использовать зажигалку
sort_by
, поскольку логические значения не сортируются по умолчанию. - Он обрабатывает преобразование логического значения (
true
/false
) в сортируемое значение (1
/0
) в строке, тем самым смешивая уровни абстракции и вводя в заблуждение потенциального читателя.
Как упоминалось ранее, Priora основана на предположении, что, когда мы говорим о наборе с приоритетом, мы часто имеем в виду результат его сортировки и последующего обращения результата. Это потому, что мы, естественно, думаем о сортировке по возрастанию, от меньшего к большему, в то время как когда мы говорим о «приоритетах» или «высших приоритетах», мы обычно думаем о самых крупных элементах, которые появляются первыми . Когда эти элементы являются объектами данных, мы должны определить, что делает один объект больше другого.
Направленные приоритеты
Очевидно, что это не всегда так, и некоторые процессы приоритизации должны сначала отдавать приоритет более мелким элементам; Приора также поддерживает это. Вы можете изменить направление приоритета для определенного приоритета:
Priora.prioritize(unprioritized_array, by: [[like_count: :asc], :is_sponsored])
=> [low_like_count_sponsored, high_like_count_sponsored, high_like_count_unsponsored]
Мы видим, что пост
с низким like_count
появляется первым, однако два поста с высоким like_count
имеют приоритет is_sponsored
, поэтому спонсируемый пост
появляется первым.
Как уже отмечалось, для того, чтобы предложить дружественный, ориентированный на предметную логику API, Priora позаботится о преобразовании несортируемых значений, таких как true
, false
или nil
, в сортируемые значения. По умолчанию предполагается, что true
больше, чем false
и что nil
оценивается как 0
.
Вы можете переопределить эти неявные преобразования своими собственными лямбда-выражениями, а также предоставить свои собственные лямбда-выражения для других классов (и, возможно, переопределить их существующую логику определения приоритетов!).
Например, если мы хотим установить приоритет атрибутов класса String
по их длине мы могли бы предварительно настроить
Priora.configuration.add_conversion_lambda(String, lambda { |value| value.length })
Конверсионные лямбды также удаляются, если возникнет такая необходимость:
Priora. configuration.remove_conversion_lambda(String)
Я следовал тому же правилу, что и раньше, предполагая разумное общее использование: логические атрибуты значение true
часто имеют более высокий приоритет, чем атрибуты ложь
значений. Это false < true
— распространенная идиома во многих других языках программирования. Тот факт, что кто-то может захотеть приоритизировать объекты по логическим атрибутам, подразумевает, что выбор должен быть сделан, поэтому я принял преобладающее соглашение. Я также думаю, что в большинстве случаев это имеет большой смысл. Если это не так, просто явно объявите приоритет как :asc
.
Влияние закона ЕС об авторском праве на новости Джулия Приора :: SSRN
Скачать эту статьюОткрыть PDF в браузере
Добавить бумагу в мою библиотеку
Делиться:7 страниц Опубликовано: 12 фев 2020
Просмотреть все статьи Джулии ПриораЮридическая школа NOVA Лиссабон
Дата написания: 1 июня 2018 г.
Аннотация
акон в распространение новостей по континентам. Их успех в основном связан с продуманным использованием и постоянным развитием телекоммуникационных технологий, которые заметно изменили методы работы всех участников новостной индустрии.
Количество юридических вопросов, связанных с созданием и распространением новостного контента, увеличилось вместе с развитием новейших технологий. Многие из рассматриваемых юридических вопросов лежат в основе закона об авторском праве, поскольку они вращаются вокруг требований и объема охраны созданного контента: являются ли новостные сообщения продуктом человеческого интеллекта или, скорее, фактами, следовательно, продуктами реальности? Действительно ли авторское право вознаграждает и стимулирует работу как автора, так и издателя?
Ключевые слова: Закон об авторском праве ЕС, журналистика, агрегация новостей, Директива CDSM
Рекомендуемое цитирование: Рекомендуемая ссылка
Приора, Джулия, Влияние закона ЕС об авторском праве на новости (1 июня 2018 г.