Как Вы получаете доступ к переменной экземпляра в рамках метода смешивания? Я могу думать о 2 путях, но оба кажутся проблематичными.
Имейте доступ метода смешивания переменная экземпляра непосредственно, как любой метод класса был бы, например, self.text. Проблема с этим состоит в том, что это устанавливает ограничения для того, где метод смешивания может использоваться и вынуждает класс, делающий смешивание назвать конкретный метод экземпляра конкретным способом.
Передайте переменную экземпляра в качестве параметра методу смешивания, который привел бы к коду как это:
пример
self.do_something(self.text)
или
@thing.do_something(@thing.text)
который выглядит противным мне и не соответствует принципам объектной ориентации.
Там какой-либо другой путь состоит в том, чтобы сделать это?, действительно ли я прав быть заинтересованным?
В общем, избегайте использования миксинов для доступа к переменным-членам: это очень жесткая форма связи, которая может излишне затруднить будущий рефакторинг.
Одна из полезных стратегий состоит в том, что Mixin всегда получает доступ к переменным через методы доступа. Итак, вместо:
#!/usr/bin/ruby1.8
module Mixin
def do_something
p @text
end
end
class Foo
include Mixin
def initialize
@text = 'foo'
end
end
Foo.new.do_something # => "foo"
миксин обращается к аксессору "text", который определяется включающим классом:
module Mixin
def do_something
p text
end
end
class Foo
attr_accessor :text
include Mixin
def initialize
@text = 'foo'
end
end
Foo.new.do_something # => "foo"
Что, если вам нужно включить Mixin в этот класс?
class Foo
def initialize
@text = "Text that has nothing to do with the mixin"
end
end
Использование общих и общих имен данных в примеси могут привести к конфликтам, когда включающий класс использует то же имя. В этом случае пусть миксин ищет данные с менее распространенным именем:
module Mixin
def do_something
p mixin_text
end
end
, и пусть включающий класс определяет соответствующий метод доступа:
class Foo
include Mixin
def initialize
@text = 'text that has nothing to do with the mixin'
@something = 'text for the mixin'
end
def mixin_text
@something
end
end
Foo.new.do_something # => "text for the mixin"
Таким образом, метод доступа действует как своего рода «сопоставитель импеданса» или «переводчик» между данными подмешивания и данными включающего класса.
Имена переменных экземпляра начинаются в ruby с символа @, например @variable
. Вы можете обращаться к ним с этим именем из включенного модуля
module M
def t
@t
end
end
class A
include M
def initialize(t)
@t= t
end
end
A.new(23).t # => 23
Если вы хотите получить доступ к @t
, когда она не определена в вашем классе, вы можете сделать это следующим образом
module M
def t
instance_variable_defined?("@t") ? @t : nil
end
end
Вы можете сами предоставить этот метод экземпляра в этом модуле, но вы должны быть осторожно, чтобы не перезаписать существующий метод
Пример (в модуле, который вы используете):
def text
@text ||= ""
end