Я проектирую / строю систему классов, которые все наследуются от одного базового класса.
Цель состоит в том, чтобы иметь простые в использовании унаследованные макро-методы, которые выглядят примерно так:
class Something < A::Base
full_name 'Something that goes bump in the night.'
end
Любой код должен иметь возможность запрашивать у класса эту информацию (или, вероятно, нормализованную / производную информацию) позже с помощью метода (ов) доступа уровня класса.
puts Something.full_name
# => "Some kind of calculated value that may or may not go bump in the night."
Учитывая, что A::Base
включает / расширяет / как-то иначе смешивает как модуль с макро-методом, который работает примерно так:
module MacroMethods
private
def full_name(full_name)
# non-trivial, one-time-only set-up code exists here in actual usage
end
end
, так и модуль с классом-метод доступа уровня, который работает примерно так:
module AccessorMethods
public
def full_name
# a non-trivial, runtime-calculated value is returned here in actual usage
end
end
независимо от того, как я их смешиваю, я постоянно сталкиваюсь с конфликтами имен (т. е. ' неверное количество аргументов (1 для 0) (ArgumentError) ') между двумя.
Примечание: full_name
- самый простой пример того, что необходимо;другие, более сложные макросы / средства доступа обеспечивают негибкие ограничения макро-методов, которые необходимо объявлять внутри класса и устанавливать их один раз и только один раз.
MyВопрос в два раза:
- Есть ли способ заставить все это работать внутри класса
A::Base
? - Этоправильный способ сделать это в Ruby? Есть ли лучший способ сделать это, достигнув того же результата?
Опции, которые были рассмотрены:
Вызов метода (методов) макроса или метода доступа к чему-либо еще.
(например, в классе Something: set_up_full_name 'Something that …'
)
Недостатком является то, что наименование сбивает с толкуи нетрадиционные.
Создание метода (ов) метода доступа на уровне экземпляра вместо уровня класса.
(например, puts a_something.full_name'
)
Недостатком является то, что черты, установленные макросами, присущи классу, а не каждому экземпляру (в некоторых случаях только ссылка накласс может быть доступен, но не экземпляр) .
Создание единого метода, который обрабатывает как макросы, так и функции доступа.
(например, в классе A :: Base: def self.full_name(*args) …
)
Недостатком является то, что методы макросов больше не могут быть закрытыми, а RDoc выглядит как sh * t.
Вместо этого используются методы abstact / virtual-ish.
(например, в классе Something: def self.full_name; 'Something that …'; end
)
Недостатком является то, что это больше кода в подклассах ибольше чем Objective-C (или C ++, или Java, ...) , чем хорошая парадигма Ruby.