Avatar

See the comment at the bottom of the code, but basically I'd like to move the "class << self" code into the StringReader 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
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 !

8dbf316d36ff66aad4869a4fc3cfbd37

Ryan Bates

June 3, 2008, June 03, 2008 14:08, permalink

1 rating. Login to rate!

You can use extend instead to turn the module methods into class methods.

1
2
3
4
class MyClass
  extend StringReader
  #...
end
Bfec5f7d1a4aaafc5a2451be8c42d26a

macournoyer

June 3, 2008, June 03, 2008 14:58, permalink

1 rating. Login to rate!

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
8f6f95c4bd64d5f10dfddfdcd03c19d6

Rick DeNatale

June 4, 2008, June 04, 2008 12:12, permalink

1 rating. Login to rate!

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"
F22c48808ddcb56564889bb39f755717

elliottcable

June 9, 2008, June 09, 2008 16:17, permalink

No rating. Login to rate!

I like Rick's method, I use that a lot. #included is pretty awesome (-:

Your refactoring





Format Copy from initial code

or Cancel