У меня вопрос из двух частей
Лучшая практика
- У меня есть алгоритм, который выполняет некоторую операцию над структурой данных с помощью общедоступного интерфейса.
- В настоящее время это модуль с множеством статических методов, все частные, за исключением одного метода открытого интерфейса.
- Есть одна переменная экземпляра, которая должна использоваться всеми методами.
Вот варианты, которые я вижу, и какой из них лучший ?:
- Модуль со статическими ('модуль' в ruby) методами
- Класс со статическими методами
- Модуль Mixin для включения в структуру данных
- Выполните рефакторинг той части алгоритма, которая изменяет эту структуру данных (очень маленькую), и сделайте ее миксином, который вызывает статические методы модуля алгоритма.
Техническая часть
Есть ли способ сделать частный метод модуля ?
module Thing
def self.pub; puts "Public method"; end
private
def self.priv; puts "Private method"; end
end
private
Там , кажется, не имеют никакого эффекта , я все еще могу назвать Thing.priv
без проблем.
ruby
private-methods
access-specifier
Дэниел Бердсли
источник
источник
private
влияет только на методы экземпляра, но не на методы класса. используйтеprivate_class_method
вместо этого:module Thing; def self.pub; end; private_class_method :pub; end
Ответы:
Я думаю, что лучший способ (и в основном то, как пишутся существующие библиотеки) сделать это - создать класс внутри модуля, который имеет дело со всей логикой, а модуль просто предоставляет удобный метод, например
источник
perform
не тот метод, который должен быть здесь частным, частный метод - это частный метод вTranslator
классе (в примере @ ucron его нет, что очень прискорбно).GTranslate.translate
это всего лишь удобный методGTranslate::Translator#perform
, нет никакой реальной выгоды, скрывающей его, если бы это было вообще возможно.self.translate
объявляет метод класса / модуля.GTranslate::Translator.new.perform(text)
- запутанно, но не приватно!Есть также
Module.private_class_method
, что, возможно, выражает большее намерение.Для кода в вопросе:
Ruby 2.1 или новее:
источник
private
?источник
include Writer
выбора!Вы можете использовать "включенный" метод, чтобы делать необычные вещи при добавлении модуля. Я думаю, это делает то, что вы хотите:
источник
included do |base| [...] end
вместо defК сожалению,
private
относится только к методам экземпляра. Общий способ получить частные «статические» методы в классе - это сделать что-то вроде:По общему признанию, я не играл с этим в модулях.
источник
.foo
созданию метода частного класса: "private; def self.foo ()"private
иprivate_class_method
принадлежатModule
notClass
. Кстати, этот код работает и является альтернативой использованиюprivate_class_method
.Хороший способ такой
источник
Как насчет хранения методов в виде лямбда-выражений в переменных / константах класса?
Для теста:
UPD: огромное обновление этого кода через 6 лет показывает более чистый способ объявления частного метода
d
Здесь мы видим, что:
1)
@@L
не может быть доступен извне, но доступен практически отовсюду2)
class << self ; private ; def
успешно делает методd
недоступным извне и изнутри с ним,self.
но не без него - это странно3)
private ; self.
иprivate ; class << self
не делает методы закрытыми - они доступны как с и безself.
источник
Proc
, а методы - к типуMethod
.Сделайте приватный модуль или класс
Константы никогда не бывают закрытыми. Однако можно создать модуль или класс, не назначая его константе.
Таким образом, альтернативой
:private_class_method
является создание частного модуля или класса и определение на нем общедоступных методов.Использование:
См. Документацию для Module.new и Class.new .
источник
.self
в определениях методов, включить их в другой класс и использовать их как instance_methods включающего класса. Вы знаете, есть ли способ заставить его работать?Этот метод не позволит обмениваться данными с частными методами, если вы явно не передадите данные с помощью параметров метода.
источник