classy 1.0.1 → 1.0.2
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/README.rdoc +23 -0
- data/VERSION +1 -1
- data/lib/classy/aliasable.rb +15 -12
- data/lib/classy/subclass_aware.rb +44 -4
- metadata +1 -1
data/README.rdoc
CHANGED
@@ -6,6 +6,29 @@ SubclassAware lets a class know about all of its subclasses (and
|
|
6
6
|
sub-subclasses, etc), and Aliasable lets you refer to classes via symbols
|
7
7
|
(useful for creating friendly DSLs).
|
8
8
|
|
9
|
+
== Examples
|
10
|
+
|
11
|
+
class Parent
|
12
|
+
extend Aliasable
|
13
|
+
extend SubclassAware
|
14
|
+
|
15
|
+
aka :pop
|
16
|
+
end
|
17
|
+
|
18
|
+
class ChildA
|
19
|
+
aka :kid1
|
20
|
+
end
|
21
|
+
|
22
|
+
class ChildB
|
23
|
+
aka :kid2
|
24
|
+
end
|
25
|
+
|
26
|
+
Parent.find(:kid1) # => ChildA
|
27
|
+
Parent.subclasses # => [ ChildA, ChildB ]
|
28
|
+
|
29
|
+
More extensive documentation and example code can be found in the RDoc for each
|
30
|
+
module, or in the spec files.
|
31
|
+
|
9
32
|
== Note on Patches/Pull Requests
|
10
33
|
|
11
34
|
* Fork the project.
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
1.0.
|
1
|
+
1.0.2
|
data/lib/classy/aliasable.rb
CHANGED
@@ -8,27 +8,28 @@
|
|
8
8
|
# @@classy_aliases, on the extending class. This could concievably lead to
|
9
9
|
# namespace conflicts and strange bugs in the unlikely event that this variable
|
10
10
|
# is used for anything else. Later versions may implement a hash of identity
|
11
|
-
# maps as a class variable on the
|
11
|
+
# maps as a class variable on the Aliasable module itself, but for reasons of
|
12
12
|
# complexity and performance, that has not been done at this time.
|
13
13
|
#
|
14
14
|
# Example:
|
15
15
|
#
|
16
|
-
# class
|
16
|
+
# class ParentClass
|
17
17
|
# extend Aliasable
|
18
18
|
# aka :pop
|
19
19
|
# end
|
20
20
|
#
|
21
|
-
# class
|
21
|
+
# class AliasedSubclass < ParentClass
|
22
22
|
# aka :kid
|
23
23
|
# end
|
24
24
|
#
|
25
|
-
# Parent.find(:pop) # =>
|
26
|
-
# Parent.find(:kid) # =>
|
25
|
+
# Parent.find(:pop) # => ParentClass
|
26
|
+
# Parent.find(:kid) # => AliasedSubclass
|
27
27
|
#
|
28
28
|
# More complex usage examples can be found in the aliasable_spec.rb file.
|
29
29
|
#
|
30
30
|
module Aliasable
|
31
|
-
|
31
|
+
|
32
|
+
def self.extended (klass) #:nodoc:
|
32
33
|
klass.class_exec do
|
33
34
|
class_variable_set(:@@classy_aliases, {})
|
34
35
|
end
|
@@ -37,25 +38,25 @@ module Aliasable
|
|
37
38
|
# When passed a class, just returns it. When passed a symbol that is an
|
38
39
|
# alias for a class, returns that class.
|
39
40
|
#
|
40
|
-
#
|
41
|
+
# ParentClass.find(AliasedSubclass) # => AliasedSubclass
|
42
|
+
# ParentClass.find(:kid) # => AliasedSubclass
|
41
43
|
#
|
42
44
|
def find (klass)
|
43
45
|
return klass if klass.kind_of? Class
|
44
46
|
class_variable_get(:@@classy_aliases)[klass] or raise ArgumentError, "Could not find alias #{klass}"
|
45
47
|
end
|
46
48
|
|
47
|
-
# Forget all known aliases.
|
49
|
+
# Forget all known aliases. Mainly useful for testing purposes.
|
48
50
|
#
|
49
51
|
def forget_aliases
|
50
52
|
class_variable_get(:@@classy_aliases).clear
|
51
53
|
end
|
52
54
|
|
53
55
|
# Specifies a symbol (or several) that a given framework might be known
|
54
|
-
# by.
|
55
|
-
# you might do this:
|
56
|
+
# by.
|
56
57
|
#
|
57
|
-
# class
|
58
|
-
# aka :
|
58
|
+
# class AnotherClass
|
59
|
+
# aka :kid2, :chunky_bacon
|
59
60
|
# ...
|
60
61
|
# end
|
61
62
|
#
|
@@ -68,6 +69,8 @@ module Aliasable
|
|
68
69
|
|
69
70
|
# Return a hash of known aliases to Class objects
|
70
71
|
#
|
72
|
+
# ParentClass.aliases # => { :pop => ParentClass, :kid => AliasedSubclass, :kid2 => AnotherClass, :chunky_bacon => AnotherClass }
|
73
|
+
#
|
71
74
|
def aliases
|
72
75
|
class_variable_get(:@@classy_aliases).dup
|
73
76
|
end
|
@@ -1,15 +1,55 @@
|
|
1
1
|
require 'set'
|
2
2
|
|
3
|
+
# SubclassAware allows a class to know about all of the subclasses that descend
|
4
|
+
# from it in the inheritance tree.
|
5
|
+
#
|
6
|
+
# Example:
|
7
|
+
#
|
8
|
+
# class Parent
|
9
|
+
# extend SubclassAware
|
10
|
+
# end
|
11
|
+
#
|
12
|
+
# class ChildA < Parent
|
13
|
+
# end
|
14
|
+
#
|
15
|
+
# class ChildB < Parent
|
16
|
+
# end
|
17
|
+
#
|
18
|
+
# Class ChildB1 < ChildB
|
19
|
+
# end
|
20
|
+
#
|
21
|
+
# Parent.subclasses # => [ ChildA, ChildB, ChildB1 ]
|
22
|
+
#
|
23
|
+
# Warning: This module defines an inherited() class method on the extending
|
24
|
+
# class to keep track of subclasses. Unfortunately, if this method is later
|
25
|
+
# re-defined, this inherited() method is lost and subclass tracking will break.
|
26
|
+
# In order to work around this, constructions like the following might be
|
27
|
+
# necessary:
|
28
|
+
#
|
29
|
+
# class ChildC < Parent
|
30
|
+
#
|
31
|
+
# class << self; alias :old_inherited :inherited end
|
32
|
+
# def self.inherited(sub)
|
33
|
+
# old_inherited(sub)
|
34
|
+
# # ...your inherited() code...
|
35
|
+
# end
|
36
|
+
#
|
37
|
+
# end
|
38
|
+
#
|
39
|
+
# This is not considered an acceptable long-term state of affairs - hopefully
|
40
|
+
# in future versions of this module, this work around will not be necessary.
|
41
|
+
#
|
3
42
|
module SubclassAware
|
4
43
|
|
5
|
-
def self.extended (klass)
|
44
|
+
def self.extended (klass) #:nodoc:
|
6
45
|
klass.class_exec { class_variable_set(:@@subclasses, Set.new) }
|
7
46
|
end
|
8
47
|
|
9
48
|
# TODO: Find a way for self.inherited on the extended class not to blow
|
10
49
|
# this away without requiring a bunch of alias chain hoops to be jumped
|
11
50
|
# through.
|
12
|
-
|
51
|
+
#
|
52
|
+
def inherited(sub) #:nodoc:
|
13
53
|
class_exec { class_variable_get(:@@subclasses).add sub }
|
14
54
|
end
|
15
55
|
|
@@ -20,8 +60,8 @@ module SubclassAware
|
|
20
60
|
class_exec { class_variable_get(:@@subclasses).to_a }
|
21
61
|
end
|
22
62
|
|
23
|
-
# Clear all info about known subclasses.
|
24
|
-
#
|
63
|
+
# Clear all info about known subclasses. This method is probably mainly
|
64
|
+
# useful for testing.
|
25
65
|
#
|
26
66
|
def forget_subclasses
|
27
67
|
class_exec { class_variable_get(:@@subclasses).clear }
|