English 中文(简体)
How do you access an instance variable within a mixin method?
原标题:

How do you access an instance variable within a mixin method? I can think of 2 ways, but both seem problematic.

  1. Have the mixin method access the instance variable directly as any class method would, e.g self.text. Problem with this is that it places restrictions on where the mixin method can be used, and forces the class doing the mixing to have a particular instance method named in a particular way.

  2. Pass the instance variable as a parameter to the mixin method, which would result in code like this:

example

self.do_something(self.text)

or

@thing.do_something(@thing.text)

which looks nasty to me, and doesn t conform to the principles of object orientation.

Is there any other way to do it?, am I right to be concerned?

最佳回答

In general, avoid having mixins access member variables: It s a very tight form of coupling that can make future refactoring unnecessarily difficult.

One useful strategy is for the Mixin to always access variables via accessors. So, instead of:

#!/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"

the mixin accesses the "text" accessor, which is defined by the including class:

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"

What if you need to include the Mixin in this class?

class Foo

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

end

Using generic and common data names in mixins can lead to conflicts when the including class uses the same name. In that case, have the mixin look for data with a less common name:

module Mixin

  def do_something
    p mixin_text
  end

end

and let the including class define the appropriate accessor:

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"

In this way, the accessor acts as sort of "impedance matcher" or "translator" between the mix-in s data and the including class s data.

问题回答

Instance variable names start in ruby with an @ eg. @variable. You can acces them with this name from a Module you include

module M
  def t
    @t
  end
end

class A
  include M
  def initialize(t)
     @t= t
  end
end

A.new(23).t # => 23

If you wan t to access @t when it s not defined in your class before you can do it this way

module M
  def t
    instance_variable_defined?("@t") ? @t : nil
  end
end

You can provide this instance method yourself in this module, but you have to be careful not to overwrite existing method

Example (in module you are mixing in):

def text
    @text ||= ""
end




相关问题
Ruby parser in Java

The project I m doing is written in Java and parsers source code files. (Java src up to now). Now I d like to enable parsing Ruby code as well. Therefore I am looking for a parser in Java that parses ...

rails collection_select vs. select

collection_select and select Rails helpers: Which one should I use? I can t see a difference in both ways. Both helpers take a collection and generates options tags inside a select tag. Is there a ...

RubyCAS-Client question: Rails

I ve installed RubyCAS-Client version 2.1.0 as a plugin within a rails app. It s working, but I d like to remove the ?ticket= in the url. Is this possible?

Ordering a hash to xml: Rails

I m building an xml document from a hash. The xml attributes need to be in order. How can this be accomplished? hash.to_xml

multiple ruby extension modules under one directory

Can sources for discrete ruby extension modules live in the same directory, controlled by the same extconf.rb script? Background: I ve a project with two extension modules, foo.so and bar.so which ...

Text Editor for Ruby-on-Rails

guys which text editor is good for Rubyonrails? i m using Windows and i was using E-Texteditor but its not free n its expired now can anyone plese tell me any free texteditor? n which one is best an ...

热门标签