Jwan622 Jwan622 -4 years ago 69
Ruby Question

Rails. Creating a module with a class setter

I have a module (it's a standard module, not a Concern. Should it be a

Concern
? What makes it a
Concern
?) that looks like this:

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


When I include it in a class, I want to be able to set inches like this:

class Tree
include TreeNutrient
set_number 5
...
end


or

class NotATree
include TreeNutrient
set_number 0
end


So that when I call
grow
on the respective plant, it grows by the set number of inches.

How do I do this? The
set_number
method has to be a class level method... not just a standard
attr_writer
.

Updated

I have this as a solution right now (I think this works?), not tested... but it feels dirty...

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

def self.number
@number
end

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


but I feel like I'm hacking around Ruby right now. Thoughts?

Answer Source

If you don't want to include ActiveSupport (you shouldn't for this, it's pretty heavy and this is simple) you could do a little meta programming. Concerns also come from ActiveSupport.

This is what I would do:

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
Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download