power_enum 0.3.0 → 0.3.1

Sign up to get free protection for your applications and to get access to all the features.
data/LICENSE CHANGED
@@ -1,4 +1,7 @@
1
- Copyright (c) 2005 Trevor Squires
1
+ Initial Version Copyright (c) 2005 Trevor Squires
2
+ Rails 3 Updates Copyright (c) 2010 Pivotal Labs
3
+ Initial Test Suite Copyright (c) 2011 Sergey Potapov
4
+ Subsequent Updates Copyright (c) 2011 Arthur Shagall
2
5
 
3
6
  Permission is hereby granted, free of charge, to any person obtaining
4
7
  a copy of this software and associated documentation files (the
data/README.md CHANGED
@@ -9,8 +9,8 @@ It allows you to cleanly solve many of the problems that the traditional Rails a
9
9
  It is particularly suitable for scenarios where your Rails application is not the only user of the database, such as
10
10
  when it's used for analytics or reporting.
11
11
 
12
- Power Enum is built on top of the Rails 3 modernization made by the fine folks at Protocool https://github.com/protocool/enumerations_mixin
13
- to the original plugin by Trevor Squires located at https://github.com/protocool/enumerations_mixin. While many of the core ideas remain,
12
+ Power Enum is built on top of the Rails 3 modernization made by the fine folks at Protocool https://github.com/protocool/enumerations\_mixin
13
+ to the original plugin by Trevor Squires located at https://github.com/protocool/enumerations\_mixin. While many of the core ideas remain,
14
14
  it has been reworked and a full test suite written to facilitate further development.
15
15
 
16
16
  At it's most basic level, it allows you to say things along the lines of:
@@ -39,17 +39,18 @@ then run
39
39
 
40
40
  This package adds two mixins and a helper to Rails' ActiveRecord, as well as methods to migrations to simplify the creation of backing tables.
41
41
 
42
- <code>acts_as_enumerated</code> provides capabilities to treat your model and its records as an enumeration.
43
- At a minimum, the database table for an acts_as_enumerated must contain an 'id' column and a 'name' column.
44
- It is strongly recommended that there be a NOT NULL constraint on the 'name' column.
45
- All instances for the acts_as_enumerated model are cached in memory. If the table has an 'active' column, the
46
- value of that attribute will be used to determine which enum instances are active. Otherwise, all values are considered
47
- active.
42
+ `acts_as_enumerated` provides capabilities to treat your model and its records as an enumeration.
43
+ At a minimum, the database table for an acts\_as\_enumerated must contain an 'id' column and a column
44
+ to hold the value of the enum ('name' by default). It is strongly recommended that there be
45
+ a NOT NULL constraint on the 'name' column. All instances for the `acts_as_enumerated` model
46
+ are cached in memory. If the table has an 'active' column, the value of that attribute
47
+ will be used to determine which enum instances are active.
48
+ Otherwise, all values are considered active.
48
49
 
49
- <code>has_enumerated</code> adds methods to your ActiveRecord model for setting and retrieving enumerated values using an associated acts_as_enumerated model.
50
+ `has_enumerated` adds methods to your ActiveRecord model for setting and retrieving enumerated values using an associated acts\_as\_enumerated model.
50
51
 
51
- There is also an <code>ActiveRecord::VirtualEnumerations</code> helper module to create 'virtual' acts_as_enumerated models which helps to avoid
52
- cluttering up your models directory with acts_as_enumerated classes.
52
+ There is also an `ActiveRecord::VirtualEnumerations` helper module to create 'virtual' acts\_as\_enumerated models which helps to avoid
53
+ cluttering up your models directory with acts\_as\_enumerated classes.
53
54
 
54
55
  ## How to use it
55
56
 
@@ -61,8 +62,6 @@ In the following example, we'll look at a Booking that can have several types of
61
62
  # The above is equivalent to saying
62
63
  # create_table :booking_statuses do |t|
63
64
  # t.string :name, :limit => 50, :null => false
64
-
65
- # t.timestamps
66
65
  # end
67
66
 
68
67
  create_table :bookings do |t|
@@ -76,23 +75,35 @@ In the following example, we'll look at a Booking that can have several types of
76
75
 
77
76
  There are two methods added to Rails migrations:
78
77
 
79
- ##### create_enum(enum_name, options = {})
78
+ ##### `create_enum(enum_name, options = {})`
80
79
 
81
- Creates a new enum table. <code>enum_name</code> will be automatically pluralized. The following options are supported:
80
+ Creates a new enum table. `enum_name` will be automatically pluralized. The following options are supported:
82
81
 
83
82
  - [:name_column] Specify the column name for name of the enum. By default it's :name. This can be a String or a Symbol
84
- - [:description] Set this to <code>true</code> to have a 'description' column generated.
83
+ - [:description] Set this to `true` to have a 'description' column generated.
85
84
  - [:name_limit] Set this define the limit of the name column.
86
85
  - [:desc_limit] Set this to define the limit of the description column
87
- - [:active] Set this to <code>true</code> to have a boolean 'active' column generated. The 'active' column will have the options of NOT NULL and DEFAULT TRUE.
86
+ - [:active] Set this to `true` to have a boolean 'active' column generated. The 'active' column will have the options of NOT NULL and DEFAULT TRUE.
87
+ - [:timestamps] Set this to `true` to have the timestamp columns (created\_at and updated\_at) generated
88
88
 
89
89
  Example:
90
90
 
91
+ create_enum :booking_status
92
+
93
+ is the equivalent of
94
+
95
+ create_table :booking_statuses do |t|
96
+ t.string :name, :null => false
97
+ end
98
+
99
+ In a more complex case:
100
+
91
101
  create_enum :booking_status, :name_column => :booking_name,
92
102
  :name_limit => 50,
93
103
  :description => true,
94
104
  :desc_limit => 100,
95
- :active => true
105
+ :active => true,
106
+ :timestamps => true
96
107
 
97
108
  is the equivalent of
98
109
 
@@ -103,9 +114,9 @@ is the equivalent of
103
114
  t.timestamps
104
115
  end
105
116
 
106
- ##### remove_enum(enum_name)
117
+ ##### `remove_enum(enum_name)`
107
118
 
108
- Drops the enum table. <code>enum_name</code> will be automatically pluralized.
119
+ Drops the enum table. `enum_name` will be automatically pluralized.
109
120
 
110
121
  Example:
111
122
 
@@ -115,77 +126,85 @@ is the equivalent of
115
126
 
116
127
  drop_table :booking_statuses
117
128
 
118
- ### acts_as_enumerated
129
+ ### acts\_as\_enumerated
119
130
 
120
131
  class BookingStatus < ActiveRecord::Base
121
- acts_as_enumerated :conditions => 'optional_sql_conditions',
122
- :order => 'optional_sql_orderby',
123
- :on_lookup_failure => :optional_class_method,
124
- :name_column => 'optional_name_column' #If required, may override the default name column
132
+ acts_as_enumerated :conditions => 'optional_sql_conditions',
133
+ :order => 'optional_sql_orderby',
134
+ :on_lookup_failure => :optional_class_method,
135
+ :name_column => 'optional_name_column' #If required, may override the default name column
125
136
  end
126
137
 
127
138
  With that, your BookingStatus class will have the following methods defined:
128
139
 
129
140
  #### Class Methods
130
141
 
131
- ##### [](arg)
142
+ ##### `[](arg)`
132
143
 
133
- <code>BookingStatus[arg]</code> performs a lookup the BookingStatus instance for arg. The arg value can be a 'string' or a :symbol, in which case the lookup will be against the BookingStatus.name field. Alternatively arg can be a Fixnum, in which case the lookup will be against the BookingStatus.id field.
144
+ `BookingStatus[arg]` performs a lookup for the BookingStatus instance for the given arg. The arg value can be a 'string' or a :symbol,
145
+ in which case the lookup will be against the BookingStatus.name field. Alternatively arg can be a Fixnum,
146
+ in which case the lookup will be against the BookingStatus.id field.
134
147
 
135
- The <code>:on_lookup_failure</code> option specifies the name of a class method to invoke when the [] method is unable to locate a BookingStatus record for arg. The default is the built-in :enforce_none which returns nil. There are also built-ins for :enforce_strict (raise and exception regardless of the type for arg), :enforce_strict_literals (raises an exception if the arg is a Fixnum or Symbol), :enforce_strict_ids (raises and exception if the arg is a Fixnum) and :enforce_strict_symbols (raises an exception if the arg is a Symbol).
148
+ The `:on_lookup_failure` option specifies the name of a *class* method to invoke when the `[]` method is unable to locate a BookingStatus record for arg.
149
+ The default is the built-in `:enforce_none` which returns nil. There are also built-ins for `:enforce_strict` (raise and exception regardless of the type for arg),
150
+ `:enforce_strict_literals` (raises an exception if the arg is a Fixnum or Symbol), `:enforce_strict_ids` (raises and exception if the arg is a Fixnum)
151
+ and `:enforce_strict_symbols` (raises an exception if the arg is a Symbol).
136
152
 
137
- The purpose of the :on_lookup_failure option is that a) under some circumstances a lookup failure is a Bad Thing and action should be taken, therefore b) a fallback action should be easily configurable.
153
+ The purpose of the `:on_lookup_failure` option is that a) under some circumstances a lookup failure is a Bad Thing and action should be taken,
154
+ therefore b) a fallback action should be easily configurable.
138
155
 
139
- ##### all
156
+ ##### `all`
140
157
 
141
- <code>BookingStatus.all</code> returns an array of all BookingStatus records that match the :conditions specified in acts_as_enumerated, in the order specified by :order.
158
+ `BookingStatus.all` returns an array of all BookingStatus records that match the `:conditions` specified in `acts_as_enumerated`, in the order specified by `:order`.
142
159
 
143
- ##### active
160
+ ##### `active`
144
161
 
145
- <code>BookingStatus.active</code> returns an array of all BookingStatus records that are marked active. See the <code>active?</code> instance method.
162
+ `BookingStatus.active` returns an array of all BookingStatus records that are marked active. See the `active?` instance method.
146
163
 
147
- ##### inactive
164
+ ##### `inactive`
148
165
 
149
- <code>BookingStatus.inactive</code> returns an array of all BookingStatus records that are inactive. See the <code>inactive?</code> instance method.
166
+ `BookingStatus.inactive` returns an array of all BookingStatus records that are inactive. See the `inactive?` instance method.
150
167
 
151
168
  #### Instance Methods
152
169
 
153
170
  Each enumeration model gets the following instance methods.
154
171
 
155
- ##### ===(arg)
172
+ ##### `===(arg)`
156
173
 
157
- <code>BookingStatus[:foo] === arg</code> returns true if <code>BookingStatus[:foo] === BookingStatus[arg]</code> returns true if arg is Fixnum, String, or Symbol. If arg is an Array, will compare every element of the array and return true if any element return true for ===.
174
+ `BookingStatus[:foo] === arg` returns true if `BookingStatus[:foo] === BookingStatus[arg]` returns true if arg is Fixnum, String,
175
+ or Symbol. If arg is an Array, will compare every element of the array and return true if any element return true for `===`.
158
176
 
159
- You should note that defining an :on_lookup_failure method that raises an exception will cause <code>===</code> to also raise an exception for any lookup failure of <code>BookingStatus</arg>.
177
+ You should note that defining an `:on_lookup_failure` method that raises an exception will cause `===` to also raise an exception for any lookup failure of `BookingStatus[arg]`.
160
178
 
161
- <code>like?</code> is aliased to <code>===<code>
179
+ `like?` is aliased to `===`
162
180
 
163
- ##### in?(*list)
181
+ ##### `in?(*list)`
164
182
 
165
- Returns true if any element in the list returns true for <code>===(arg)</code>, false otherwise.
183
+ Returns true if any element in the list returns true for `===(arg)`, false otherwise.
166
184
 
167
- ##### name
185
+ ##### `name`
168
186
 
169
- Returns the 'name' of the enum, i.e. the value in the <code>:name_column</code> attribute of the enumeration model.
187
+ Returns the 'name' of the enum, i.e. the value in the `:name_column` attribute of the enumeration model.
170
188
 
171
- ##### name_sym
189
+ ##### `name_sym`
172
190
 
173
- Returns the symbol representation of the name of the enum. <code>BookingStatus[:foo].name_sym</code> returns :foo.
191
+ Returns the symbol representation of the name of the enum. `BookingStatus[:foo].name_sym` returns :foo.
174
192
 
175
- ##### active?
193
+ ##### `active?`
176
194
 
177
195
  Returns true if the instance is active, false otherwise. If it has an attribute 'active',
178
- returns the attribute cast to a boolean, otherwise returns true. This method is used by the 'active'
196
+ returns the attribute cast to a boolean, otherwise returns true. This method is used by the `active`
179
197
  class method to select active enums.
180
198
 
181
- ##### inactive?
199
+ ##### `inactive?`
182
200
 
183
- Returns true if the instance is inactive, false otherwise. Default implementations returns !active?
184
- This method is used by the 'inactive' class method to select inactive enums.
201
+ Returns true if the instance is inactive, false otherwise. Default implementations returns `!active?`
202
+ This method is used by the `inactive` class method to select inactive enums.
185
203
 
186
204
  #### Notes
187
205
 
188
- acts_as_enumerated records are considered immutable. By default you cannot create/alter/destroy instances because they are cached in memory. Because of Rails' process-based model it is not safe to allow updating acts_as_enumerated records as the caches will get out of sync.
206
+ `acts_as_enumerated` records are considered immutable. By default you cannot create/alter/destroy instances because they are cached in memory.
207
+ Because of Rails' process-based model it is not safe to allow updating acts\_as\_enumerated records as the caches will get out of sync.
189
208
 
190
209
  However, one instance where updating the models *should* be allowed is if you are using seeds.rb to seed initial values into the database.
191
210
 
@@ -196,64 +215,76 @@ Using the above example you would do the following:
196
215
  BookingStatus.create( :name => status_name )
197
216
  end
198
217
 
199
- A <code>:presence</code> and <code>:uniqueness</code> validation is automatically defined on each model.
218
+ Note that a `:presence` and `:uniqueness` validation is automatically defined on each model for the name column.
200
219
 
201
- ### has_enumerated
220
+ ### has\_enumerated
202
221
 
203
- First of all, note that you *could* specify the relationship to an acts_as_enumerated class using the belongs_to association. However, has_enumerated is preferable because you aren't really associated to the enumerated value, you are *aggregating* it. As such, the has_enumerated macro behaves more like an aggregation than an association.
222
+ First of all, note that you *could* specify the relationship to an `acts_as_enumerated` class using the belongs_to association.
223
+ However, `has_enumerated` is preferable because you aren't really associated to the enumerated value, you are *aggregating* it. As such,
224
+ the `has_enumerated` macro behaves more like an aggregation than an association.
204
225
 
205
226
  class Booking < ActiveRecord::Base
206
- has_enumerated :status, :class_name => 'BookingStatus',
207
- :foreign_key => 'status_id',
208
- :on_lookup_failure => :optional_instance_method
227
+ has_enumerated :status, :class_name => 'BookingStatus',
228
+ :foreign_key => 'status_id',
229
+ :on_lookup_failure => :optional_instance_method
209
230
  end
210
231
 
211
- By default, the foreign key is interpreted to be the name of your has_enumerated field (in this case 'status') plus '_id'. Additionally, the default value for :class_name is the camel-ized version of the name for your has_enumerated field. :on_lookup_failure is explained below.
232
+ By default, the foreign key is interpreted to be the name of your has\_enumerated field (in this case 'status') plus '\_id'. Additionally,
233
+ the default value for `:class_name` is the camel-ized version of the name for your has\_enumerated field. `:on_lookup_failure` is explained below.
212
234
 
213
235
  With that, your Booking class will have the following methods defined:
214
236
 
215
- #### status
237
+ #### `status`
216
238
 
217
239
  Returns the BookingStatus with an id that matches the value in the Booking.status_id.
218
240
 
219
- #### status=(arg)
241
+ #### `status=(arg)`
220
242
 
221
- Sets the value for Booking.status_id using the id of the BookingStatus instance passed as an argument. As a short-hand, you can also pass it the 'name' of a BookingStatus instance, either as a 'string' or :symbol, or pass in the id directly.
243
+ Sets the value for Booking.status_id using the id of the BookingStatus instance passed as an argument. As a
244
+ short-hand, you can also pass it the 'name' of a BookingStatus instance, either as a 'string' or :symbol, or pass in the id directly.
222
245
 
223
246
  example:
224
247
 
225
248
  mybooking.status = :confirmed
226
249
 
227
- this also works:
250
+ this is equivalent to:
228
251
 
229
252
  mybooking.status = 'confirmed'
230
253
 
231
- The <code>:on_lookup_failure</code> option in has_enumerated is there because you may want to create an error handler for situations where the argument passed to status= is invalid. By default, an invalid value will cause an ArgumentError to be raised.
254
+ or:
255
+
256
+ mybooking.status = BookingStatus[:confirmed]
257
+
258
+ The `:on_lookup_failure` option in has_enumerated is there because you may want to create an error handler for situations
259
+ where the argument passed to `status=(arg)` is invalid. By default, an invalid value will cause an ArgumentError to be raised.
232
260
 
233
261
  Of course, this may not be optimal in your situation. In this case you can specify an *instance* method to be called in the case of a lookup failure. The method signature is as follows:
234
262
 
235
263
  your_lookup_handler(operation, name, name_foreign_key, acts_enumerated_class_name, lookup_value)
236
264
 
237
- The 'operation' arg will be either :read or :write. In the case of :read you are expected to return something or raise an exception, while in the case of a :write you don't have to return anything.
265
+ The 'operation' arg will be either `:read` or `:write`. In the case of `:read` you are expected to return something or raise an exception,
266
+ while in the case of a `:write` you don't have to return anything.
238
267
 
239
- Note that there's enough information in the method signature that you can specify one method to handle all lookup failures for all has_enumerated fields if you happen to have more than one defined in your model.
268
+ Note that there's enough information in the method signature that you can specify one method to handle all lookup failures
269
+ for all has\_enumerated fields if you happen to have more than one defined in your model.
240
270
 
241
- NOTE: A nil is always considered to be a valid value for status= since it's assumed you're trying to null out the foreign key, therefore the <code>:on_lookup_failure</code> will be bypassed.
271
+ NOTE: A `nil` is always considered to be a valid value for `status=(arg)` since it's assumed you're trying to null out the foreign key.
272
+ The `:on_lookup_failure` will be bypassed.
242
273
 
243
274
  ### ActiveRecord::VirtualEnumerations
244
275
 
245
- For the most part, your acts_as_enumerated classes will do nothing more than just act as enumerated.
276
+ In many instances, your `acts_as_enumerated` classes will do nothing more than just act as enumerated.
246
277
 
247
278
  In that case there isn't much point cluttering up your models directory with those class files. You can use ActiveRecord::VirtualEnumerations to reduce that clutter.
248
279
 
249
- Copy virtual_enumerations_sample.rb to Rails.root/config/initializers/virtual_enumerations.rb and configure it accordingly.
280
+ Copy virtual\_enumerations\_sample.rb to Rails.root/config/initializers/virtual\_enumerations.rb and configure it accordingly.
250
281
 
251
- See virtual_enumerations_sample.rb in the examples directory of this gem for a full description.
282
+ See virtual\_enumerations\_sample.rb in the examples directory of this gem for a full description.
252
283
 
253
284
 
254
285
  ## How to run tests
255
286
 
256
- Go to dummy project:
287
+ Go to the 'dummy' project:
257
288
 
258
289
  cd ./spec/dummy
259
290
 
@@ -277,7 +308,7 @@ And finally run tests:
277
308
 
278
309
  * Initial Version Copyright (c) 2005 Trevor Squires
279
310
  * Rails 3 Updates Copyright (c) 2010 Pivotal Labs
280
- * Initial test suite Copyright (c) 2011 Sergey Potapov
281
- * Additional Updates Copyright (c) 2011 Arthur Shagall
311
+ * Initial Test Suite Copyright (c) 2011 Sergey Potapov
312
+ * Subsequent Updates Copyright (c) 2011 Arthur Shagall
282
313
 
283
314
  Released under the MIT License. See the LICENSE file for more details.
@@ -25,6 +25,8 @@ module PowerEnum::Schema
25
25
  # Set this to define the limit of the description column.
26
26
  # [:active]
27
27
  # Set this to <tt>true</tt> to have a boolean 'active' column generated. The 'active' column will have the options of NOT NULL and DEFAULT TRUE.
28
+ # [:timestamps]
29
+ # Set this to <tt>true</tt> to have timestamp columns (created_at and updated_at) generated.
28
30
  #
29
31
  # ===== Examples
30
32
  # ====== Basic Enum
@@ -32,11 +34,15 @@ module PowerEnum::Schema
32
34
  # is the equivalent of
33
35
  # create_table :connector_types do |t|
34
36
  # t.string :name, :null => false
35
- # t.timestamps
36
37
  # end
37
38
  #
38
39
  # ====== Advanced Enum
39
- # create_enum :connector_type, :name_column => :connector, :name_limit => 50, :description => true, :desc_limit => 100, :active => true
40
+ # create_enum :connector_type, :name_column => :connector,
41
+ # :name_limit => 50,
42
+ # :description => true,
43
+ # :desc_limit => 100,
44
+ # :active => true,
45
+ # :timestamps => true
40
46
  # is the equivalent of
41
47
  # create_table :connector_types do |t|
42
48
  # t.string :connector, :limit => 50, :null => false
@@ -50,6 +56,7 @@ module PowerEnum::Schema
50
56
  name_column = options[:name_column] || :name
51
57
  generate_description = !!options[:description]
52
58
  generate_active = !!options[:active]
59
+ generate_timestamps = !!options[:timestamps]
53
60
  name_limit = options[:name_limit]
54
61
  desc_limit = options[:desc_limit]
55
62
 
@@ -61,8 +68,9 @@ module PowerEnum::Schema
61
68
  if generate_active
62
69
  t.boolean :active, :null => false, :default => true
63
70
  end
64
-
65
- t.timestamps
71
+ if generate_timestamps
72
+ t.timestamps
73
+ end
66
74
  end
67
75
 
68
76
  add_index enum_table_name, [name_column], :unique => true
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: power_enum
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.3.1
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -12,11 +12,11 @@ authors:
12
12
  autorequire:
13
13
  bindir: bin
14
14
  cert_chain: []
15
- date: 2011-09-23 00:00:00.000000000Z
15
+ date: 2011-09-25 00:00:00.000000000Z
16
16
  dependencies:
17
17
  - !ruby/object:Gem::Dependency
18
18
  name: rails
19
- requirement: &18214180 !ruby/object:Gem::Requirement
19
+ requirement: &28153380 !ruby/object:Gem::Requirement
20
20
  none: false
21
21
  requirements:
22
22
  - - ! '>='
@@ -24,10 +24,10 @@ dependencies:
24
24
  version: 3.0.0
25
25
  type: :runtime
26
26
  prerelease: false
27
- version_requirements: *18214180
27
+ version_requirements: *28153380
28
28
  - !ruby/object:Gem::Dependency
29
29
  name: jeweler
30
- requirement: &18213580 !ruby/object:Gem::Requirement
30
+ requirement: &28152380 !ruby/object:Gem::Requirement
31
31
  none: false
32
32
  requirements:
33
33
  - - ! '>='
@@ -35,10 +35,10 @@ dependencies:
35
35
  version: '0'
36
36
  type: :development
37
37
  prerelease: false
38
- version_requirements: *18213580
38
+ version_requirements: *28152380
39
39
  - !ruby/object:Gem::Dependency
40
40
  name: rspec
41
- requirement: &18189680 !ruby/object:Gem::Requirement
41
+ requirement: &28151860 !ruby/object:Gem::Requirement
42
42
  none: false
43
43
  requirements:
44
44
  - - ! '>='
@@ -46,10 +46,10 @@ dependencies:
46
46
  version: '0'
47
47
  type: :development
48
48
  prerelease: false
49
- version_requirements: *18189680
49
+ version_requirements: *28151860
50
50
  - !ruby/object:Gem::Dependency
51
51
  name: sqlite3
52
- requirement: &18188860 !ruby/object:Gem::Requirement
52
+ requirement: &28151280 !ruby/object:Gem::Requirement
53
53
  none: false
54
54
  requirements:
55
55
  - - ! '>='
@@ -57,7 +57,7 @@ dependencies:
57
57
  version: '0'
58
58
  type: :development
59
59
  prerelease: false
60
- version_requirements: *18188860
60
+ version_requirements: *28151280
61
61
  description: ! 'Power Enum allows you to treat instances of your ActiveRecord models
62
62
  as though they were an enumeration of values.
63
63