Rails - применить массив областей

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

# garden.py
def trim(a):
    pass

def strip(a):
    pass

def bunch(a, b):
    pass

def _foo(foo):
    pass

class powertools(object):
    """
    Provides much regarded gardening power tools.
    """
    @staticmethod
    def answer_to_the_ultimate_question_of_life_the_universe_and_everything():
        return 42

    @staticmethod
    def random():
        return 13

    @staticmethod
    def promise():
        return True

def _bar(baz, quux):
    pass

class _Dice(object):
    pass

class _6d(_Dice):
    pass

class _12d(_Dice):
    pass

class _Smarter:
    pass

class _MagicalPonies:
    pass

class _Samurai:
    pass

class Foo(_6d, _Samurai):
    pass

class Bar(_12d, _Smarter, _MagicalPonies):
    pass

...

# tests.py
import unittest
import garden

class GardenTests(unittest.TestCase):
    pass

class PowertoolsTests(unittest.TestCase):
    pass

class FooTests(unittest.TestCase):
    pass

class BarTests(unittest.TestCase):
    pass

...

# interactive.py
from garden import trim, bunch, Foo

f = trim(Foo())
bunch(f, Foo())

...

# my_garden.py
import garden
from garden import powertools

class _Cowboy(garden._Samurai):
    def hit():
        return powertools.promise() and powertools.random() or 0

class Foo(_Cowboy, garden.Foo):
    pass

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

Я часто считаю целесообразным применить этот подход к организации кода утилиты проекта. Довольно часто люди сразу бросаются и создают пакет utils и в итоге получают 9 модулей, из которых 120 LOC, а остальные - два десятка LOC в лучшем случае. Я предпочитаю начать с этого и преобразовать его в пакет и создать модули только для тех зверей, которые их действительно заслуживают:

# utils.py
class socket(object):
    @staticmethod
    def check_if_port_available(port):
        pass

    @staticmethod
    def get_free_port(port)
        pass

class image(object):
    @staticmethod
    def to_rgb(image):
        pass

    @staticmethod
    def to_cmyk(image):
        pass

1
задан Mark 16 January 2019 в 17:04
поделиться

1 ответ

Из подробного руководства :

14 Области применения
[...]
Определить простая область, мы используем метод области действия внутри класса, передавая запрос, который мы хотели бы выполнить, когда вызывается эта область:

class Article < ApplicationRecord
  scope :published, -> { where(published: true) }
end

Это точно так же, как определение метода класса, и то, что вы используете, является вопросом личных предпочтений:

class Article < ApplicationRecord
  def self.published
    where(published: true)
  end
end

Так что scope в основном просто причудливый способ создания метода класса, который должен иметь определенное поведение (т.е. возвращать отношение ) и любой метод метода класса, который возвращает отношение, является областью действия. scope раньше было чем-то особенным, но теперь они просто методы класса, и все методы класса копируются в отношения для поддержки цепочки.

Нет способа узнать, является ли метод Model.m «реальной» областью действия, которая будет возвращать отношение или некоторый метод случайного класса, не выполняя его и не проверяя, что он возвращает, или вручную проверяя его исходный код. Метод scopes, к которому вы стремитесь, исчез и никогда не вернется.

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

Единственный разумный вариант - вносить в белый список каждый классовый метод, который, как вы знаете, хорош и является тем, что вы хотите, чтобы пользователи могли вызывать. Затем вы должны отфильтровать массив scopes в контроллере и внутри AssignableLearningObjectives::Collector. Я бы проверил в обоих местах, потому что у вас могут быть разные критерии для того, что разрешено, в зависимости от того, какая информация доступна и по какому пути вы проходите через код; Я полагаю, немного меньше СУХОГО, но эффективность и надежность не дружат.

Вы можете применить белый список областей видимости в конструкторе AssignableLearningObjectives::Collector или в available_objectives.


Если вы хотите что-то более красивое, чем:

scopes.each{ |scope| objectives = objectives.send(scope) }
objectives

, тогда вы можете использовать inject:

def available_objectives
  objectives = assignable_objectives....
  scopes.inject(objectives) { |objectives, scope| objectives.send(scope) }
end
0
ответ дан mu is too short 16 January 2019 в 17:04
поделиться
Другие вопросы по тегам:

Похожие вопросы: