Module: FactoryModule

Included in:
Monkeyshines::Fetcher, Monkeyshines::RequestStream, Monkeyshines::Store
Defined in:
lib/monkeyshines/utils/factory_module.rb

Overview

Makes a module behave as a factory.

A module that extends FactoryModule gets a method #new(klass_name, *args): this finds the class corresponding to klass_name and creates it with *args as arguments.

if klass_name is a class, it’s used directly. Otherwise, it’s converted to a class, and can be in underscored form (mysql_doc_source) or namespace form (FileSources::WordDoc); the name is interpreted relative to the extending module’s namespace. (So, in the example below, :file_doc_source,

FileDocSource, DocSource

Example. Given:

module DocSource
  extend FactoryModule
end

# ... elsewhere ...
module DocSource
  # load docs from file
  class FileDocSource
    def initialize filename
      #...
    end
  end

  # load docs from web
  class MySqlDocSource
    def initialize host, port, user, password
      # ...
    end
  end
end

Then:

DocSource.new :file_doc_source, '/tmp/foo.doc'    # => returns DocSource::FileDocSource
DocSource.new :MySqlDocSource,  'localhost', 6666 # => returns DocSource::MySqlDocSource

Constant Summary collapse

FACTORY_CLASSES =
{}

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.extended(base) ⇒ Object



43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
# File 'lib/monkeyshines/utils/factory_module.rb', line 43

def self.extended base
  base.class_eval do

    def self.new klass_name, *args
      FactoryModule.get_class(self, klass_name).new(*args)
    end

    def self.from_hash plan
      return plan unless plan.is_a?(Hash)
      klass_name = (plan[:type] || plan['type']) or raise "Fat, drunk, and stupid is no way to go through life, son. You need a plan: #{plan.inspect}"
      FactoryModule.get_class(self, klass_name).from_hash(plan)
    end

    def self.create plan
      case
      # when plan.class.ancestors.include? self
      when plan.is_a?(Hash)
        klass_name = plan[:type] || plan['type']
        FactoryModule.get_class(self, klass_name).new(plan)
      when plan.is_a?(Symbol)
        klass_name = plan
        FactoryModule.get_class(self, klass_name).new()
      else plan
      end
    end

  end
end

.get_class(scope, klass_name) ⇒ Object



77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/monkeyshines/utils/factory_module.rb', line 77

def self.get_class scope, klass_name
  return FACTORY_CLASSES[ [scope, klass_name] ] if FACTORY_CLASSES[ [scope, klass_name] ]
  if klass_name.is_a? Class
    klass = klass_name
  else
    begin
      klass = scope.find_const(klass_name.to_s.camelize)
    rescue NameError => e
      raise "Can't find #{klass_name.inspect} in #{scope}"
    end
  end
  # find_const from wukong/extensions/module via extlib
  FACTORY_CLASSES[ [scope, klass_name] ] = klass
end

.list_of_classes(scope, klass_names, prefix = nil, suffix = nil) ⇒ Object

FactoryModule.list_of_classes(Wuclan::Twitter::Scrape, ‘followers_ids,friends_ids’, ‘request’)

# => [Wuclan::Twitter::Scrape::FollowersIdsRequest, Wuclan::Twitter::Scrape::FriendsIdsRequest]


98
99
100
101
102
103
104
# File 'lib/monkeyshines/utils/factory_module.rb', line 98

def self.list_of_classes scope, klass_names, prefix=nil, suffix=nil
  klass_names = klass_names.split(',') if klass_names.is_a?(String)
  klass_names.map do |klass_name|
    klass_name = [prefix, klass_name, suffix].compact.join('_') if klass_name.is_a?(String)
    self.get_class(scope, klass_name)
  end
end

Instance Method Details

#get_class(klass_name) ⇒ Object



72
73
74
# File 'lib/monkeyshines/utils/factory_module.rb', line 72

def get_class klass_name
  FactoryModule.get_class self, klass_name
end