Как Вы получаете доступ к переменной экземпляра в рамках метода смешивания?

Как Вы получаете доступ к переменной экземпляра в рамках метода смешивания? Я могу думать о 2 путях, но оба кажутся проблематичными.

  1. Имейте доступ метода смешивания переменная экземпляра непосредственно, как любой метод класса был бы, например, self.text. Проблема с этим состоит в том, что это устанавливает ограничения для того, где метод смешивания может использоваться и вынуждает класс, делающий смешивание назвать конкретный метод экземпляра конкретным способом.

  2. Передайте переменную экземпляра в качестве параметра методу смешивания, который привел бы к коду как это:

пример

self.do_something(self.text)

или

@thing.do_something(@thing.text)

который выглядит противным мне и не соответствует принципам объектной ориентации.

Там какой-либо другой путь состоит в том, чтобы сделать это?, действительно ли я прав быть заинтересованным?

14
задан dangerousdave 15 July 2014 в 09:21
поделиться

3 ответа

В общем, избегайте использования миксинов для доступа к переменным-членам: это очень жесткая форма связи, которая может излишне затруднить будущий рефакторинг.

Одна из полезных стратегий состоит в том, что 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"

Таким образом, метод доступа действует как своего рода «сопоставитель импеданса» или «переводчик» между данными подмешивания и данными включающего класса.

24
ответ дан 1 December 2019 в 10:02
поделиться

Имена переменных экземпляра начинаются в 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
2
ответ дан 1 December 2019 в 10:02
поделиться

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

Пример (в модуле, который вы используете):

def text
    @text ||= ""
end
1
ответ дан 1 December 2019 в 10:02
поделиться
Другие вопросы по тегам:

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