rap_enumerable 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. data/README +45 -0
  2. data/lib/rap_enumerable.rb +84 -0
  3. metadata +47 -0
data/README ADDED
@@ -0,0 +1,45 @@
1
+ # The RapEnumerable module adds functionality to facilitate the creation of
2
+ # enumeration classes.
3
+ #
4
+ # Usage:
5
+ # class Klass
6
+ # include RapEnumerable
7
+ #
8
+ # create(:id => 1, :aliases => ['hello', 'there'])
9
+ # create(:id => 2, :aliases => ['foo', 'bar'])
10
+ # # ...
11
+ # end
12
+ #
13
+ # * This ensures that instances of Klass can only be created from within Klass
14
+ # by calling new_instance(attributes), where attributes is a hash used to set initial
15
+ # values of instance variables, using the key as a method name and sending in the value.
16
+ #
17
+ # * Instances of Klass will get methods id() and aliases() to retrieve these values.
18
+ #
19
+ # * Instances of Klass can be retrieved by calling Klass.find(key) where key is
20
+ # an instance id or any of its aliases.
21
+ #
22
+ # * Instances of Klass can be checked to see whether they are a particular instance by calling
23
+ # <name>? for any of its indexed values. In the example above, you can take k, an instance
24
+ # of Klass, and call k.hello?
25
+ #
26
+ # * By default, the find method uses an index keyed by the id and aliases of the
27
+ # Klass instances. You can add attributes to be used as finders by calling find_by as shown below. This
28
+ # will also generate accessor methods for the given attribute names. Note that you must call
29
+ # find_by before creating your enumeration instances.
30
+ #
31
+ # For example, this will let you call Klass.find(1) or Klass.find('hello') and get back the
32
+ # instance:
33
+ # class Klass
34
+ # include RapEnumerable
35
+ #
36
+ # find_by :name
37
+ #
38
+ # create(:id => 1, :name => 'hello')
39
+ # create(:id => 2, :name => 'world')
40
+ #
41
+ # end
42
+ #
43
+ # * An array of all Klass instances can be retrieved with Klass.all
44
+ #
45
+ # Jeremy Lizt (jeremy@rapleaf.com) - 4/2007
@@ -0,0 +1,84 @@
1
+ module RapEnumerable
2
+
3
+ attr_reader :id, :aliases
4
+
5
+ def initialize(attributes = {})
6
+ @id = attributes.delete(:id)
7
+ @aliases = attributes.delete(:aliases).to_a
8
+ attributes.each {|k,v| send(k.to_s + "=", v)}
9
+ end
10
+
11
+ # Return an array of aliases plus
12
+ def _keys
13
+ self.class.finder_attrs.map {|attr| send(attr) if respond_to?(attr)}.flatten.compact
14
+ end
15
+
16
+ # Check if any indexed keys match the query. Only handle if the query matches an indexed key.
17
+ def method_missing(method_id, *arguments)
18
+ if match = /^(\w*)\?$/.match(method_id.to_s)
19
+ inst = self.class.find(match[1])
20
+ if(inst.nil?) then super
21
+ else self == inst
22
+ end
23
+ else
24
+ super
25
+ end
26
+ end
27
+
28
+ end
29
+
30
+
31
+ class << RapEnumerable
32
+
33
+ def included(klass)
34
+ super
35
+ klass.extend(RapEnumerableClassMethods)
36
+ klass.private_class_method :new, :allocate, :create
37
+ klass.instance_eval do
38
+ @finder_attrs = [:id, :aliases] # Attribute names to use to find keys for the find index.
39
+ @instances = []
40
+ @instances_by_key = {}
41
+ end
42
+ end
43
+
44
+ module RapEnumerableClassMethods
45
+
46
+ attr_reader :finder_attrs
47
+
48
+ # Add one or more attribute names to use for indexing the finder. Also, generate accessor methods for these attributes.
49
+ def find_by(*attribute_names)
50
+ attr_accessor(*attribute_names)
51
+ @finder_attrs.concat(attribute_names).uniq!
52
+ end
53
+
54
+ def create(attributes = nil)
55
+ inst = new(attributes)
56
+
57
+ # Check for key & alias uniqueness
58
+ if(dup_key = inst._keys.find {|key| @instances_by_key[key]})
59
+ raise "Duplicate key error: #{dup_key}"
60
+ end
61
+
62
+ # Add instance and index
63
+ @instances << inst
64
+ inst._keys.each {|key| @instances_by_key[key.to_s.strip.downcase] = inst}
65
+ inst
66
+ end
67
+
68
+ def find(key)
69
+ @instances_by_key[key.to_s.strip.downcase] unless key.nil?
70
+ end
71
+
72
+ def all
73
+ @instances
74
+ end
75
+
76
+ def each
77
+ @instances.each {|instance| yield instance}
78
+ end
79
+
80
+ end
81
+
82
+ end
83
+
84
+
metadata ADDED
@@ -0,0 +1,47 @@
1
+ --- !ruby/object:Gem::Specification
2
+ rubygems_version: 0.9.4
3
+ specification_version: 1
4
+ name: rap_enumerable
5
+ version: !ruby/object:Gem::Version
6
+ version: 0.0.1
7
+ date: 2007-10-05 00:00:00 -07:00
8
+ summary: Module to facilitate the creation of enumeration classes.
9
+ require_paths:
10
+ - lib
11
+ email: jeremy@rapleaf.com
12
+ homepage: http://blog.rapleaf.com/dev
13
+ rubyforge_project:
14
+ description:
15
+ autorequire: rap_enumerable
16
+ default_executable:
17
+ bindir: bin
18
+ has_rdoc: false
19
+ required_ruby_version: !ruby/object:Gem::Version::Requirement
20
+ requirements:
21
+ - - ">"
22
+ - !ruby/object:Gem::Version
23
+ version: 0.0.0
24
+ version:
25
+ platform: ruby
26
+ signing_key:
27
+ cert_chain:
28
+ post_install_message:
29
+ authors:
30
+ - Jeremy Lizt
31
+ files:
32
+ - lib/rap_enumerable.rb
33
+ - README
34
+ test_files: []
35
+
36
+ rdoc_options: []
37
+
38
+ extra_rdoc_files:
39
+ - README
40
+ executables: []
41
+
42
+ extensions: []
43
+
44
+ requirements: []
45
+
46
+ dependencies: []
47
+