轨。使用类设置器创建模块

时间:2017-03-21 14:22:12

标签: ruby-on-rails ruby

我有一个模块(它是一个标准模块,而不是一个关注点。它应该是Concern吗?是什么使它成为Concern?)看起来像这样:

module TreeNutrient
   def grow
      "grows #{number} inches"
   end
end

当我将它包含在课堂中时,我希望能够像这样设置英寸:

class Tree
    include TreeNutrient
    set_number 5
    ...
end

class NotATree
    include TreeNutrient
    set_number 0
end

因此,当我在相应工厂调用grow时,它会以设定的英寸数增长。

我该怎么做? set_number方法必须是类级方法...而不仅仅是标准attr_writer

更新

我现在有这个解决方案(我认为这有效吗?),未经测试......但感觉很脏......

module TreeNutrient
  def self.set_number(number)
     @number = number
  end

  def self.number
     @number
  end

  def grow
     "grows #{self.class.number} inches"
  end
end

但我觉得我现在正在乱砍Ruby。想法?

2 个答案:

答案 0 :(得分:1)

如果您不想要包含ActiveSupport(您不应该为此而烦恼,这很简单),您可以进行一些元编程。关注还来自ActiveSupport。

这就是我要做的事情:

module TreeNutrient
  def self.included(klass)
    klass.extend ClassMethods
  end

  module ClassMethods
    def set_number n
      define_method(:number) { n }
    end
  end
end


class Tree
  include TreeNutrient
  set_number 5

  def grow
    "grows #{number} inches"
  end
end

puts Tree.new.grow
# grows 5 inches

答案 1 :(得分:0)

查看mattr_accessor

http://apidock.com/rails/Module/mattr_accessor

来自页面:

module HairColors
  mattr_accessor :hair_colors
end

class Person
  include HairColors
end

Person.hair_colors = [:brown, :black, :blonde, :red]
Person.hair_colors     # => [:brown, :black, :blonde, :red]
Person.new.hair_colors # => [:brown, :black, :blonde, :red]

注意:需要ActiveSupport / Rails才能工作