typecollection 0.0.10 → 0.0.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/Rakefile CHANGED
@@ -35,12 +35,3 @@ end
35
35
 
36
36
  task :default => :test
37
37
 
38
- require 'rake/rdoctask'
39
- Rake::RDocTask.new do |rdoc|
40
- version = File.exist?('VERSION') ? File.read('VERSION') : ""
41
-
42
- rdoc.rdoc_dir = 'rdoc'
43
- rdoc.title = "typecollection #{version}"
44
- rdoc.rdoc_files.include('README*')
45
- rdoc.rdoc_files.include('lib/**/*.rb')
46
- end
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.0.10
1
+ 0.0.11
@@ -1,6 +1,8 @@
1
1
  module TypeCollection
2
+ NAME_DECOMPOSER = /(^|(?<namespace>.*):{2})(?<constant>[^:]+)$/
3
+ class << self; attr_accessor :create_unknown_types; end
4
+
2
5
  module Base
3
-
4
6
  module BaseClassMethods
5
7
  # Returns all of the known subclass names for this collection
6
8
  def all_type_names(); return __tc_members().keys(); end
@@ -13,19 +15,48 @@ module TypeCollection
13
15
  raise TypeCollection::UnknownChildType.new("Unregistered type: #{type}") unless (mems.has_key?(type))
14
16
  return mems[type]
15
17
  end
16
- # Get similar type based on the object passed in which can be a String,
18
+ # Creates the type associated with the provided value (Class or Otherwise)
19
+ def generate_type(type)
20
+ type = type.inferred_type() if (type.kind_of?(Class))
21
+ root = __tc_collection_root()
22
+
23
+ name = TypeCollection::NAME_DECOMPOSER.match(root.name)
24
+
25
+ new_type = Class.new(root)
26
+ new_type_name = type + name[:constant]
27
+
28
+ # Back away. Just BACK. AWAY.
29
+ #
30
+ # We need to take this new class we've just created here
31
+ # and assign it to a constant in the same namespace as its
32
+ # collection root. That may be the global namespace.
33
+ # This mess accomplishes that.
34
+ ::Kernel.instance_exec(new_type, &eval("->(klass){ #{name[:namespace]}::#{new_type_name} = klass }"))
35
+
36
+ root.__tc_register_member(new_type)
37
+ new_type
38
+ end
39
+ # Get similar type based on the object passed in which can be a String,
17
40
  # Object (using the inferred type), or Class
18
- def get_associated_type(associate)
41
+ def get_associated_type(associate, create_if_unknown=TypeCollection.create_unknown_types)
19
42
  if (!associate.kind_of?(String))
20
43
  if (!associate.kind_of?(Class))
21
44
  associate = associate.class
22
45
  end
23
46
  associate = associate.inferred_type()
24
47
  end
25
- return self.get_type(associate)
48
+ begin
49
+ self.get_type(associate)
50
+ rescue TypeCollection::UnknownChildType => uct
51
+ if create_if_unknown
52
+ self.generate_type(associate)
53
+ else
54
+ raise
55
+ end
56
+ end
26
57
  end
27
58
  end
28
-
59
+
29
60
  def self.included(base)
30
61
  base.extend(TypeCollection::ClassMethods)
31
62
  base.extend(TypeCollection::Base::BaseClassMethods)
@@ -1,14 +1,15 @@
1
1
  class Class
2
- def inferred_type()
3
- klass_name = self.name.split("::").last
4
- parent_klass = self.superclass
5
- while(parent_klass != nil)
6
- check = /#{parent_klass.name.split("::").last}$/
7
- if (klass_name.match(check))
8
- return klass_name.gsub(check, '')
9
- end
10
- parent_klass = parent_klass.superclass
2
+ def __tc_collection_root()
3
+ root = self
4
+ while root.superclass && root.superclass.include?(TypeCollection::Base)
5
+ root = root.superclass
11
6
  end
12
- return nil
7
+ root
8
+ end
9
+
10
+ def inferred_type()
11
+ klass_name = self.name.split("::").last
12
+ root_name = __tc_collection_root.name.split("::").last
13
+ klass_name.gsub(root_name, "")
13
14
  end
14
- end
15
+ end
@@ -3,30 +3,37 @@ module TypeCollection
3
3
  # fails to comply with the correct naming convention for TypeCollection
4
4
  # to function properly
5
5
  class InvalidChildType < StandardError; end
6
-
6
+
7
7
  # Indicates that a request has been made to retrieve a child type that
8
8
  # is not currently registered with the type collection
9
9
  class UnknownChildType < StandardError; end
10
-
10
+
11
11
  # Extended by TypeCollections to provide class level functionality (almost
12
12
  # all functionality is class level as of the current design)
13
13
  module ClassMethods
14
14
  # Contains the Members mapped by type
15
15
  def __tc_members(); @_members ||= { }; end
16
-
17
- # Overrides the default behavior when being extended by a child class.
18
- # It ensures the child is mapped for future retrieval and checks the
19
- # subclass name to ensure it is a valid one
20
- def inherited(child)
21
- super if (defined?(super))
16
+
17
+ # Registers a member
18
+ def __tc_register_member(child)
22
19
  type = child.inferred_type()
23
20
  if (type.nil?)
24
21
  cname = child.name.split("::").last
25
22
  pname = self.name.split("::").last
26
- error = "Invalid Name: #{ cname }! Child class names must end with \"#{ pname }\"."
23
+ error = "Invalid name: '#{cname}'! Child class names must end with '#{pname}'."
27
24
  raise TypeCollection::InvalidChildType.new(error)
28
25
  end
29
26
  __tc_members()[type] = child
30
27
  end
28
+
29
+ # Overrides the default behavior when being extended by a child class.
30
+ # It ensures the child is mapped for future retrieval and checks the
31
+ # subclass name to ensure it is a valid one
32
+ def inherited(child)
33
+ super if (defined?(super))
34
+ unless child.name.nil?
35
+ __tc_collection_root.__tc_register_member(child)
36
+ end
37
+ end
31
38
  end
32
- end
39
+ end
@@ -5,11 +5,11 @@
5
5
 
6
6
  Gem::Specification.new do |s|
7
7
  s.name = "typecollection"
8
- s.version = "0.0.10"
8
+ s.version = "0.0.11"
9
9
 
10
10
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
11
  s.authors = ["James Petty"]
12
- s.date = "2012-08-13"
12
+ s.date = "2013-04-04"
13
13
  s.description = "Easily map subtypes into their parent type for later retrieval"
14
14
  s.email = "jp@jibe.com"
15
15
  s.extra_rdoc_files = [
@@ -36,7 +36,7 @@ Gem::Specification.new do |s|
36
36
  s.homepage = "http://github.com/pettyjamesm/TypeCollection"
37
37
  s.licenses = ["MIT"]
38
38
  s.require_paths = ["lib"]
39
- s.rubygems_version = "1.8.24"
39
+ s.rubygems_version = "1.8.25"
40
40
  s.summary = "TypeCollection maintains a record of sub-types for a given class based on a common suffix."
41
41
 
42
42
  if s.respond_to? :specification_version then
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: typecollection
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.10
4
+ version: 0.0.11
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-08-13 00:00:00.000000000 Z
12
+ date: 2013-04-04 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: shoulda
@@ -97,7 +97,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
97
97
  version: '0'
98
98
  segments:
99
99
  - 0
100
- hash: 110654369381516186
100
+ hash: 160659592697084515
101
101
  required_rubygems_version: !ruby/object:Gem::Requirement
102
102
  none: false
103
103
  requirements:
@@ -106,7 +106,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
106
106
  version: '0'
107
107
  requirements: []
108
108
  rubyforge_project:
109
- rubygems_version: 1.8.24
109
+ rubygems_version: 1.8.25
110
110
  signing_key:
111
111
  specification_version: 3
112
112
  summary: TypeCollection maintains a record of sub-types for a given class based on