如何在mixin方法中访问实例变量?

dan*_*ave 14 ruby methods module mixins

如何在mixin方法中访问实例变量?我可以想到两种方式,但两者似乎都有问题.

  1. 让mixin方法直接访问实例变量,就像任何类方法一样,例如self.text.问题在于它限制了mixin方法的使用位置,并强制进行混合的类具有以特定方式命名的特定实例方法.

  2. 将实例变量作为参数传递给mixin方法,这将产生如下代码:

self.do_something(self.text)
Run Code Online (Sandbox Code Playgroud)

要么

@thing.do_something(@thing.text)
Run Code Online (Sandbox Code Playgroud)

这对我来说很讨厌,并且不符合面向对象的原则.

还有其他办法吗?我对此感到关心吗?

Way*_*rad 24

通常,避免使用mixins访问成员变量:这是一种非常紧密的耦合形式,可能会使未来的重构变得不必要.

一个有用的策略是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"
Run Code Online (Sandbox Code Playgroud)

mixin访问"text"访问器,它由include类定义:

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"
Run Code Online (Sandbox Code Playgroud)

如果您需要在此课程中包含Mixin,该怎么办?

class Foo

def initialize
  @text = "Text that has nothing to do with the mixin"
end

end
Run Code Online (Sandbox Code Playgroud)

当包含类使用相同的名称时,在mixin中使用通用和通用数据名称可能会导致冲突.在这种情况下,让mixin查找名称不太常见的数据:

module Mixin

  def do_something
    p mixin_text
  end

end
Run Code Online (Sandbox Code Playgroud)

并让include类定义适当的访问器:

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"
Run Code Online (Sandbox Code Playgroud)

通过这种方式,存取器在混合数据和包含类数据之间充当"阻抗匹配器"或"转换器".