Вы когда-нибудь использовали защищенную видимость в Rails?

Признание: я использую только частную и общедоступную видимость для своих методов!

У меня такое чувство, что это плохо. Но в Rails это просто не кажется проблемой.

Есть ли у кого-нибудь пример в Rails, где было бы большой ошибкой не использовать защищенную видимость?


person pez_dispenser    schedule 22.05.2009    source источник


Ответы (2)


Обновление. См. комментарий ниже, который ссылается на верное объяснение protected/private в Ruby. Это был глубоко укоренившийся предрассудок, оставшийся со времен моей работы на Java. Единственная важная часть, оставшаяся от моего ответа, заключается в том, что методы контроллера, которые не являются действиями, не должны быть public (или, по крайней мере, ваши маршруты должны их защищать).

Наследование одной таблицы — прекрасный пример того, когда protected полезен на уровне модели, поскольку это одно из наиболее распространенных применений наследования.

На уровне контроллера вспомогательные методы, определенные на ApplicationController, должны быть помечены как protected — если бы они были private, другие контроллеры не смогли бы получить к ним доступ, но если они public, Rails будет рассматривать их как действия.

Лично я обнаружил, что использую наследование классов чаще, чем многие мои друзья и коллеги, даже в приложениях Rails. Поскольку я использую его часто (и после того, как закончил свои дни Java), я предпочитаю protected для всех вспомогательных методов, чтобы дать свободу любому (обычно самому себе), кто хочет расширить класс - если только я действительно не смущен одним, тогда Я отмечаю это private. :)

person Ian Terrell    schedule 22.05.2009
comment
Это имеет большой смысл. (Хотя не знаю, что такое ИППП). - person pez_dispenser; 23.05.2009
comment
вспомогательные методы, определенные в ApplicationController, должны быть помечены как защищенные — если бы они были частными, другие контроллеры не смогли бы получить к ним доступ — к вашему сведению, это неправильно. См. пример здесь: pastie.org/842898 . Protected/private в Ruby касается «я» и получателей, а не наследования. Обратите внимание, что в отличие от таких языков, как Java, наследование не играет абсолютно никакой роли в определении видимости методов в Ruby. -- weblog.jamisbuck.org/2007/2/23/ метод-видимость-в-ruby - person Jordan Brough; 25.02.2010

У меня есть SingleTableInheritance

класс Человек ‹ AR::базовый класс Учитель ‹ Человек класс Студент ‹ Человек

И я использую защищенные методы для реализации частного метода, общего для Ученика и Учителя:

class Person < AR::base
  def self.find(*args)
    reject_leaves(super(*args))
  end
protected
  def self.reject_leaves(target) #like a private in Teacher and Student
    case target
      when Array target.select{|t| reject_leaves(t)}
      when Person (target.leave_date < Date.today ? target : nil)
      else target
    end
  end
end

Отказ от ответственности: существуют плагины, такие как act-as-paranoid и другие, для реализации функции, которую я использую здесь, чтобы показать вам случай, но у меня есть более сложный ландшафт, который я упростил здесь, чтобы добраться до вашей точки зрения.

person Oinak    schedule 22.05.2009
comment
к вашему сведению, ваш пример выше работает неправильно - вы можете без проблем вызвать Person.reject_leaves(...). «public/protected/private» в ruby ​​не являются ключевыми словами — это вызовы методов self, которые изменяют состояние self. Поскольку вы меняете self, когда делаете def self. reject_leaves, у вас больше не настроено состояние protected. чтобы получить то, что вы хотите, вам понадобится что-то вроде второго примера (Prot2) здесь: pastie.org/842952 - person Jordan Brough; 25.02.2010