1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
module StringReader def string_reader(*params) params.each do |param| variable_name = "@" + param.to_s define_method(param) do self.instance_variable_get(variable_name).to_s end end end end class MyClass class << self include StringReader end string_reader :foo def initialize @foo = 42 end end require "pp" my = MyClass.new pp my.foo #=> "42" (a string) # I would like to re-write the MyClass definition to: # # class MyClass # include StringReader # # string_reader :foo # # def initialize # @foo = 42 # end # end # # How do I refactor StringReader to get this code?
Refactorings
No refactoring yet !
Ryan Bates
June 3, 2008, June 03, 2008 14:08, permalink
You can use extend instead to turn the module methods into class methods.
1 2 3 4
class MyClass extend StringReader #... end
macournoyer
June 3, 2008, June 03, 2008 14:58, permalink
I think this makes the code easier to understand
1 2 3 4 5 6 7 8 9 10 11
module StringReader def string_reader(*params) params.each do |param| class_eval <<-EOS def #{param} @#{param}.to_s end EOS end end end
Rick DeNatale
June 4, 2008, June 04, 2008 12:12, permalink
Here's a pretty conventional approach to having a module provide class methods when included in another class or module
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
module StringReader module ClassMethods def string_reader(*params) params.each do |param| variable_name = "@" + param.to_s define_method(param) do self.instance_variable_get(variable_name).to_s end end end end def self.included(cls) cls.extend ClassMethods end end class MyClass include StringReader string_reader :foo def initialize @foo = 42 end end my = MyClass.new my.foo # => "42"
elliottcable
June 9, 2008, June 09, 2008 16:17, permalink
I like Rick's method, I use that a lot. #included is pretty awesome (-:
See the comment at the bottom of the code, but basically I'd like to move the "class << self" code into the StringReader module.