nice_enum 0.1.3 → 0.1.4

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/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