rap_enum 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README +45 -0
- data/lib/rap_enum.rb +84 -0
- metadata +47 -0
data/README
ADDED
@@ -0,0 +1,45 @@
|
|
1
|
+
# The RapEnum module adds functionality to facilitate the creation of
|
2
|
+
# enumeration classes.
|
3
|
+
#
|
4
|
+
# Usage:
|
5
|
+
# class Klass
|
6
|
+
# include RapEnum
|
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 RapEnum
|
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
|
data/lib/rap_enum.rb
ADDED
@@ -0,0 +1,84 @@
|
|
1
|
+
module RapEnum
|
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_enum
|
5
|
+
version: !ruby/object:Gem::Version
|
6
|
+
version: 0.0.1
|
7
|
+
date: 2007-10-10 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_enum
|
16
|
+
default_executable:
|
17
|
+
bindir: bin
|
18
|
+
has_rdoc: true
|
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_enum.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
|
+
|