nice_enum 0.1.3 → 0.1.4

Sign up to get free protection for your applications and to get access to all the features.
data/lib/nice_enum.rb CHANGED
@@ -1,173 +1,173 @@
1
- #--
2
- # Copyright (c) 2010, Raphael Robatsch
3
- # All rights reserved.
4
- #
5
- # Redistribution and use in source and binary forms, with or without
6
- # modification, are permitted provided that the following conditions are met:
7
- # * Redistributions of source code must retain the above copyright
8
- # notice, this list of conditions and the following disclaimer.
9
- # * Redistributions in binary form must reproduce the above copyright
10
- # notice, this list of conditions and the following disclaimer in the
11
- # documentation and/or other materials provided with the distribution.
12
- # * The names of the developers or contributors must not be used to
13
- # endorse or promote products derived from this software without
14
- # specific prior written permission.
15
- #
16
- # THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS AND CONTRIBUTORS "AS IS" AND
17
- # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18
- # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19
- # DISCLAIMED. IN NO EVENT SHALL THE DEVELOPERS OR CONTRIBUTORS BE LIABLE FOR ANY
20
- # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21
- # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22
- # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23
- # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24
- # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25
- # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
- #++
27
-
28
- # Base class for all Enumerations. To create an Enumeration, subclass this
29
- # class and add enum calls in the class body.
30
- # There are many samples in README.rdoc and samples/ .
31
- class Enum
32
- include Comparable
33
-
34
- # Returns the name of the enumeration member. This is the first parameter
35
- # passed to +enum+, converted to a string.
36
- attr_reader :name
37
-
38
- # Returns the value of the enumeration member. This is the second parameter
39
- # passed to +enum+.
40
- attr_reader :value
41
-
42
- # Compares the value of +self+ with the value of +other+.
43
- def <=>(other)
44
- other = other.value if other.is_a? self.class
45
- return value <=> other
46
- end
47
-
48
- # Returns whether the value of +self+ and the value of +other+ are equal.
49
- def eql?(other)
50
- other = other.value if other.is_a? self.class
51
- return value.eql?(other)
52
- end
53
-
54
- # Returns the hashcode of +value+.
55
- def hash
56
- value.hash
57
- end
58
-
59
- # Returns the name of the enumeration member.
60
- def to_s
61
- @name
62
- end
63
-
64
- alias old_respond_to? respond_to? # :nodoc:
65
- def respond_to?(sym) # :nodoc:
66
- old_respond_to?(sym) || @value.respond_to?(sym)
67
- end
68
-
69
- def method_missing(sym, *args, &block) # :nodoc:
70
- @value.send(sym, *args, &block)
71
- end
72
-
73
- class << Enum
74
- include Enumerable
75
-
76
- # Returns the +Enum+ instance for the given value. If no enumeration
77
- # member has been created for this value, a new instance is created,
78
- # setting +name+ to +value.to_s+.
79
- def new(value)
80
- return @enumvalues[value] if @enumvalues.has_key? value
81
- _setup_enumvalue(value, value, allocate)
82
- end
83
-
84
- # Returns the default value for the attribute +attr+. If no default
85
- # value has been set, +nil+ is returned.
86
- def default_value(attr)
87
- @defaults ||= {}
88
- @defaults[attr.to_sym]
89
- end
90
-
91
- # Enumerates all known enumeration members.
92
- def each
93
- @enumvalues ||= {}
94
- @enumvalues.each_value { |enumvalue| yield enumvalue }
95
- end
96
-
97
- protected
98
- # Adds a new enumeration member to the current enumeration. The
99
- # generated member is accessible using the constant +name+. If
100
- # +value+ is +nil+, it is set to the highest integer value in
101
- # use \+ 1.
102
- def enum(name, value = nil, attributes = {})
103
- @enumvalues ||= {}
104
- value ||= (@enumvalues.values.max || -1) + 1
105
-
106
- enumvalue = allocate
107
- const_set(name, enumvalue)
108
- @enumvalues[value] = enumvalue
109
- _setup_enumvalue(name, value, enumvalue, attributes)
110
- end
111
-
112
- def _setup_enumvalue(name, value, enumvalue, attributes = {}) # :nodoc:
113
- enumvalue.instance_variable_set(:@name, name.to_s)
114
- enumvalue.instance_variable_set(:@value, value)
115
- attributes.each do |attribute, attr_value|
116
- _create_accessor(attribute)
117
- enumvalue.instance_variable_set("@#{attribute}", attr_value)
118
- end
119
- enumvalue
120
- end
121
-
122
- # Sets the default values for the attributes of the enumeration members.
123
- # There can be more than one call to +defaults+.
124
- def defaults(defs = {})
125
- @defaults ||= {}
126
- @defaults.merge!(defs)
127
- end
128
- alias default defaults
129
-
130
- def _create_accessor(attribute) # :nodoc:
131
- define_method(attribute) do
132
- instance_variable_get("@#{attribute}") || self.class.default_value(attribute)
133
- end
134
- end
135
- end
136
- end
137
-
138
- # Base class for enumerations in which members can be or'd together to create
139
- # combinations of them. For example, Unix file permissions can be represented
140
- # as a flag enumeration with the members <tt>Read = 4</tt>, <tt>Write = 2</tt>
141
- # and <tt>Execute = 1</tt>. There are many samples in README.rdoc and samples/.
142
- class Flags < Enum
143
- # Returns the individual enumeration members that are contained in +self+.
144
- # If the enumeration class contains a member with the value +0+, that
145
- # member is only included in the result if there aren't any other members
146
- # that are contained in +self+.
147
- def flags
148
- result = self.class.select { |flag| value & flag != 0 }.sort
149
- result = [self.class.new(0)] if result.empty?
150
- result
151
- end
152
-
153
- # Joins the result of +flags+ together.
154
- def join(seperator = " | ")
155
- flags.map { |flag| flag.name }.join(seperator)
156
- end
157
- alias to_s join
158
-
159
- # Returns the combination of +self+ and +other+.
160
- def |(other)
161
- self.class.new(value | other)
162
- end
163
-
164
- # Returns the intersection of +self+ and +other+.
165
- def &(other)
166
- self.class.new(value & other)
167
- end
168
-
169
- # Bitwise-XORs +self+ with +other+.
170
- def ^(other)
171
- self.class.new(value ^ other)
172
- end
173
- end
1
+ #--
2
+ # Copyright (c) 2010, Raphael Robatsch
3
+ # All rights reserved.
4
+ #
5
+ # Redistribution and use in source and binary forms, with or without
6
+ # modification, are permitted provided that the following conditions are met:
7
+ # * Redistributions of source code must retain the above copyright
8
+ # notice, this list of conditions and the following disclaimer.
9
+ # * Redistributions in binary form must reproduce the above copyright
10
+ # notice, this list of conditions and the following disclaimer in the
11
+ # documentation and/or other materials provided with the distribution.
12
+ # * The names of the developers or contributors must not be used to
13
+ # endorse or promote products derived from this software without
14
+ # specific prior written permission.
15
+ #
16
+ # THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS AND CONTRIBUTORS "AS IS" AND
17
+ # ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18
+ # WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
19
+ # DISCLAIMED. IN NO EVENT SHALL THE DEVELOPERS OR CONTRIBUTORS BE LIABLE FOR ANY
20
+ # DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21
+ # (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22
+ # LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23
+ # ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24
+ # (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25
+ # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
+ #++
27
+
28
+ # Base class for all Enumerations. To create an Enumeration, subclass this
29
+ # class and add enum calls in the class body.
30
+ # There are many samples in README.rdoc and samples/ .
31
+ class Enum
32
+ include Comparable
33
+
34
+ # Returns the name of the enumeration member. This is the first parameter
35
+ # passed to +enum+, converted to a string.
36
+ attr_reader :name
37
+
38
+ # Returns the value of the enumeration member. This is the second parameter
39
+ # passed to +enum+.
40
+ attr_reader :value
41
+
42
+ # Compares the value of +self+ with the value of +other+.
43
+ def <=>(other)
44
+ other = other.value if other.is_a? self.class
45
+ return value <=> other
46
+ end
47
+
48
+ # Returns whether the value of +self+ and the value of +other+ are equal.
49
+ def eql?(other)
50
+ other = other.value if other.is_a? self.class
51
+ return value.eql?(other)
52
+ end
53
+
54
+ # Returns the hashcode of +value+.
55
+ def hash
56
+ value.hash
57
+ end
58
+
59
+ # Returns the name of the enumeration member.
60
+ def to_s
61
+ @name
62
+ end
63
+
64
+ alias old_respond_to? respond_to? # :nodoc:
65
+ def respond_to?(sym) # :nodoc:
66
+ old_respond_to?(sym) || @value.respond_to?(sym)
67
+ end
68
+
69
+ def method_missing(sym, *args, &block) # :nodoc:
70
+ @value.send(sym, *args, &block)
71
+ end
72
+
73
+ class << Enum
74
+ include Enumerable
75
+
76
+ # Returns the +Enum+ instance for the given value. If no enumeration
77
+ # member has been created for this value, a new instance is created,
78
+ # setting +name+ to +value.to_s+.
79
+ def new(value)
80
+ return @enumvalues[value] if @enumvalues.has_key? value
81
+ _setup_enumvalue(value, value, allocate)
82
+ end
83
+
84
+ # Returns the default value for the attribute +attr+. If no default
85
+ # value has been set, +nil+ is returned.
86
+ def default_value(attr)
87
+ @defaults ||= {}
88
+ @defaults[attr.to_sym]
89
+ end
90
+
91
+ # Enumerates all known enumeration members.
92
+ def each
93
+ @enumvalues ||= {}
94
+ @enumvalues.each_value { |enumvalue| yield enumvalue }
95
+ end
96
+
97
+ protected
98
+ # Adds a new enumeration member to the current enumeration. The
99
+ # generated member is accessible using the constant +name+. If
100
+ # +value+ is +nil+, it is set to the highest integer value in
101
+ # use \+ 1.
102
+ def enum(name, value = nil, attributes = {})
103
+ @enumvalues ||= {}
104
+ value ||= (@enumvalues.values.max || -1) + 1
105
+
106
+ enumvalue = allocate
107
+ const_set(name, enumvalue)
108
+ @enumvalues[value] = enumvalue
109
+ _setup_enumvalue(name, value, enumvalue, attributes)
110
+ end
111
+
112
+ def _setup_enumvalue(name, value, enumvalue, attributes = {}) # :nodoc:
113
+ enumvalue.instance_variable_set(:@name, name.to_s)
114
+ enumvalue.instance_variable_set(:@value, value)
115
+ attributes.each do |attribute, attr_value|
116
+ _create_accessor(attribute)
117
+ enumvalue.instance_variable_set("@#{attribute}", attr_value)
118
+ end
119
+ enumvalue
120
+ end
121
+
122
+ # Sets the default values for the attributes of the enumeration members.
123
+ # There can be more than one call to +defaults+.
124
+ def defaults(defs = {})
125
+ @defaults ||= {}
126
+ @defaults.merge!(defs)
127
+ end
128
+ alias default defaults
129
+
130
+ def _create_accessor(attribute) # :nodoc:
131
+ define_method(attribute) do
132
+ instance_variable_get("@#{attribute}") || self.class.default_value(attribute)
133
+ end
134
+ end
135
+ end
136
+ end
137
+
138
+ # Base class for enumerations in which members can be or'd together to create
139
+ # combinations of them. For example, Unix file permissions can be represented
140
+ # as a flag enumeration with the members <tt>Read = 4</tt>, <tt>Write = 2</tt>
141
+ # and <tt>Execute = 1</tt>. There are many samples in README.rdoc and samples/.
142
+ class Flags < Enum
143
+ # Returns the individual enumeration members that are contained in +self+.
144
+ # If the enumeration class contains a member with the value +0+, that
145
+ # member is only included in the result if there aren't any other members
146
+ # that are contained in +self+.
147
+ def flags
148
+ result = self.class.select { |flag| value & flag != 0 }.sort
149
+ result = [self.class.new(0)] if result.empty?
150
+ result
151
+ end
152
+
153
+ # Joins the result of +flags+ together.
154
+ def join(seperator = " | ")
155
+ flags.map { |flag| flag.name }.join(seperator)
156
+ end
157
+ alias to_s join
158
+
159
+ # Returns the combination of +self+ and +other+.
160
+ def |(other)
161
+ self.class.new(value | other)
162
+ end
163
+
164
+ # Returns the intersection of +self+ and +other+.
165
+ def &(other)
166
+ self.class.new(value & other)
167
+ end
168
+
169
+ # Bitwise-XORs +self+ with +other+.
170
+ def ^(other)
171
+ self.class.new(value ^ other)
172
+ end
173
+ end
data/samples/deck.rb CHANGED
@@ -1,59 +1,59 @@
1
- require "../lib/nice_enum"
2
-
3
- module Cards
4
- class Suit < Enum
5
- enum :Spades
6
- enum :Hearts
7
- enum :Diamonds
8
- enum :Clubs
9
- end
10
-
11
- class Value < Enum
12
- enum :Ace, 1, :score => 11 # For the sake of simplicity
13
- enum :Two, 2, :score => 2
14
- enum :Three, 3, :score => 3
15
- enum :Four, nil, :score => 4
16
- enum :Five, nil, :score => 5
17
- enum :Six, nil, :score => 6
18
- enum :Jack, nil, :score => 10
19
- enum :Queen, nil, :score => 10
20
- enum :Knight, nil, :score => 10
21
- end
22
-
23
- class Card
24
- attr_accessor :suit
25
- attr_accessor :value
26
-
27
- def initialize(suit, value)
28
- @suit = suit
29
- @value = value
30
- end
31
-
32
- def to_s
33
- "#{value} of #{suit}"
34
- end
35
- end
36
-
37
- class Deck
38
- def initialize
39
- @cards = Suit.map do |suit|
40
- Value.map do |value|
41
- Card.new(suit, value)
42
- end
43
- end.flatten.shuffle
44
- end
45
-
46
- def draw(n)
47
- @cards.slice!(0, n)
48
- end
49
- end
50
- end
51
-
52
- deck = Cards::Deck.new
53
- hand = deck.draw(5)
54
-
55
- puts "Your hand:"
56
- hand.each do |card|
57
- puts " - #{card}"
58
- end
59
- puts "Blackjack score: #{hand.inject(0) { |score, card| score + card.value.score }}"
1
+ require "../lib/nice_enum"
2
+
3
+ module Cards
4
+ class Suit < Enum
5
+ enum :Spades
6
+ enum :Hearts
7
+ enum :Diamonds
8
+ enum :Clubs
9
+ end
10
+
11
+ class Value < Enum
12
+ enum :Ace, 1, :score => 11 # For the sake of simplicity
13
+ enum :Two, 2, :score => 2
14
+ enum :Three, 3, :score => 3
15
+ enum :Four, nil, :score => 4
16
+ enum :Five, nil, :score => 5
17
+ enum :Six, nil, :score => 6
18
+ enum :Jack, nil, :score => 10
19
+ enum :Queen, nil, :score => 10
20
+ enum :Knight, nil, :score => 10
21
+ end
22
+
23
+ class Card
24
+ attr_accessor :suit
25
+ attr_accessor :value
26
+
27
+ def initialize(suit, value)
28
+ @suit = suit
29
+ @value = value
30
+ end
31
+
32
+ def to_s
33
+ "#{value} of #{suit}"
34
+ end
35
+ end
36
+
37
+ class Deck
38
+ def initialize
39
+ @cards = Suit.map do |suit|
40
+ Value.map do |value|
41
+ Card.new(suit, value)
42
+ end
43
+ end.flatten.shuffle
44
+ end
45
+
46
+ def draw(n)
47
+ @cards.slice!(0, n)
48
+ end
49
+ end
50
+ end
51
+
52
+ deck = Cards::Deck.new
53
+ hand = deck.draw(5)
54
+
55
+ puts "Your hand:"
56
+ hand.each do |card|
57
+ puts " - #{card}"
58
+ end
59
+ puts "Blackjack score: #{hand.inject(0) { |score, card| score + card.value.score }}"
data/samples/filemodes.rb CHANGED
@@ -1,20 +1,20 @@
1
- require "../lib/nice_enum"
2
-
3
- class Permission < Flags
4
- enum :None, 0
5
- enum :Read, 4
6
- enum :Write, 2
7
- enum :Execute, 1
8
- end
9
-
10
- file = ARGV[0] || __FILE__
11
- puts "Permissions on #{file}:"
12
-
13
- mode = File.stat(file).mode
14
- user = Permission.new((mode & 448) >> 6)
15
- group = Permission.new((mode & 56) >> 3)
16
- world = Permission.new(mode & 7)
17
-
18
- puts "User: #{user}"
19
- puts "Group: #{group}"
20
- puts "World: #{world}"
1
+ require "../lib/nice_enum"
2
+
3
+ class Permission < Flags
4
+ enum :None, 0
5
+ enum :Read, 4
6
+ enum :Write, 2
7
+ enum :Execute, 1
8
+ end
9
+
10
+ file = ARGV[0] || __FILE__
11
+ puts "Permissions on #{file}:"
12
+
13
+ mode = File.stat(file).mode
14
+ user = Permission.new((mode & 448) >> 6)
15
+ group = Permission.new((mode & 56) >> 3)
16
+ world = Permission.new(mode & 7)
17
+
18
+ puts "User: #{user}"
19
+ puts "Group: #{group}"
20
+ puts "World: #{world}"
@@ -1,16 +1,16 @@
1
- require "../lib/nice_enum"
2
-
3
- class Number < Enum
4
- enum :Zero, 0
5
- enum :One, 1
6
- enum :Two, 2
7
-
8
- def square
9
- value ** 2
10
- end
11
- end
12
-
13
- numbers = Number.to_a
14
- numbers << Number.new(3)
15
-
16
- numbers.each { |number| puts "#{number} squared is #{number.square}." }
1
+ require "../lib/nice_enum"
2
+
3
+ class Number < Enum
4
+ enum :Zero, 0
5
+ enum :One, 1
6
+ enum :Two, 2
7
+
8
+ def square
9
+ value ** 2
10
+ end
11
+ end
12
+
13
+ numbers = Number.to_a
14
+ numbers << Number.new(3)
15
+
16
+ numbers.each { |number| puts "#{number} squared is #{number.square}." }
@@ -1,30 +1,30 @@
1
- require "nice_enum"
2
- require "test/unit"
3
-
4
- class AttributeTest < Test::Unit::TestCase
5
- class Number < Enum
6
- enum :Twenty, 20,
7
- :note => "Exact value of e^pi - pi"
8
-
9
- enum :Ninety, 90,
10
- :note => "Square Root of -1"
11
-
12
- enum :FourtyTwo, 42
13
- end
14
-
15
- def test_respond_to_known_attribute
16
- assert Number::Twenty.respond_to?(:note)
17
- end
18
-
19
- def test_get_attribute_from_known_value
20
- assert_equal "Exact value of e^pi - pi", Number::Twenty.note
21
- end
22
-
23
- def test_get_attribute_from_unknown_value
24
- assert_equal nil, Number.new(8).note
25
- end
26
-
27
- def test_respond_to_unknown_attribute
28
- assert !Number::Twenty.respond_to?(:color)
29
- end
30
- end
1
+ require "nice_enum"
2
+ require "test/unit"
3
+
4
+ class AttributeTest < Test::Unit::TestCase
5
+ class Number < Enum
6
+ enum :Twenty, 20,
7
+ :note => "Exact value of e^pi - pi"
8
+
9
+ enum :Ninety, 90,
10
+ :note => "Square Root of -1"
11
+
12
+ enum :FourtyTwo, 42
13
+ end
14
+
15
+ def test_respond_to_known_attribute
16
+ assert Number::Twenty.respond_to?(:note)
17
+ end
18
+
19
+ def test_get_attribute_from_known_value
20
+ assert_equal "Exact value of e^pi - pi", Number::Twenty.note
21
+ end
22
+
23
+ def test_get_attribute_from_unknown_value
24
+ assert_equal nil, Number.new(8).note
25
+ end
26
+
27
+ def test_respond_to_unknown_attribute
28
+ assert !Number::Twenty.respond_to?(:color)
29
+ end
30
+ end