activemodel 4.2.11.3 → 5.0.0.beta1
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of activemodel might be problematic. Click here for more details.
- checksums.yaml +5 -5
- data/CHANGELOG.md +84 -93
- data/MIT-LICENSE +1 -1
- data/README.rdoc +8 -16
- data/lib/active_model.rb +3 -2
- data/lib/active_model/attribute_assignment.rb +52 -0
- data/lib/active_model/attribute_methods.rb +16 -16
- data/lib/active_model/callbacks.rb +3 -3
- data/lib/active_model/conversion.rb +3 -3
- data/lib/active_model/dirty.rb +34 -35
- data/lib/active_model/errors.rb +117 -63
- data/lib/active_model/forbidden_attributes_protection.rb +3 -2
- data/lib/active_model/gem_version.rb +5 -5
- data/lib/active_model/lint.rb +32 -28
- data/lib/active_model/locale/en.yml +2 -1
- data/lib/active_model/model.rb +3 -4
- data/lib/active_model/naming.rb +5 -4
- data/lib/active_model/secure_password.rb +2 -9
- data/lib/active_model/serialization.rb +36 -9
- data/lib/active_model/serializers/json.rb +1 -1
- data/lib/active_model/type.rb +59 -0
- data/lib/active_model/type/big_integer.rb +13 -0
- data/lib/active_model/type/binary.rb +50 -0
- data/lib/active_model/type/boolean.rb +21 -0
- data/lib/active_model/type/date.rb +50 -0
- data/lib/active_model/type/date_time.rb +44 -0
- data/lib/active_model/type/decimal.rb +52 -0
- data/lib/active_model/type/decimal_without_scale.rb +11 -0
- data/lib/active_model/type/float.rb +25 -0
- data/lib/active_model/type/helpers.rb +4 -0
- data/lib/active_model/type/helpers/accepts_multiparameter_time.rb +35 -0
- data/lib/active_model/type/helpers/mutable.rb +18 -0
- data/lib/active_model/type/helpers/numeric.rb +34 -0
- data/lib/active_model/type/helpers/time_value.rb +77 -0
- data/lib/active_model/type/immutable_string.rb +29 -0
- data/lib/active_model/type/integer.rb +66 -0
- data/lib/active_model/type/registry.rb +64 -0
- data/lib/active_model/type/string.rb +19 -0
- data/lib/active_model/type/text.rb +11 -0
- data/lib/active_model/type/time.rb +46 -0
- data/lib/active_model/type/unsigned_integer.rb +15 -0
- data/lib/active_model/type/value.rb +112 -0
- data/lib/active_model/validations.rb +35 -3
- data/lib/active_model/validations/absence.rb +1 -1
- data/lib/active_model/validations/acceptance.rb +61 -9
- data/lib/active_model/validations/callbacks.rb +3 -3
- data/lib/active_model/validations/confirmation.rb +16 -4
- data/lib/active_model/validations/exclusion.rb +3 -1
- data/lib/active_model/validations/format.rb +1 -1
- data/lib/active_model/validations/helper_methods.rb +13 -0
- data/lib/active_model/validations/inclusion.rb +3 -3
- data/lib/active_model/validations/length.rb +48 -17
- data/lib/active_model/validations/numericality.rb +12 -13
- data/lib/active_model/validations/validates.rb +1 -1
- data/lib/active_model/validations/with.rb +0 -10
- data/lib/active_model/validator.rb +6 -2
- data/lib/active_model/version.rb +1 -1
- metadata +34 -9
- data/lib/active_model/serializers/xml.rb +0 -238
@@ -17,8 +17,9 @@ module ActiveModel
|
|
17
17
|
module ForbiddenAttributesProtection # :nodoc:
|
18
18
|
protected
|
19
19
|
def sanitize_for_mass_assignment(attributes)
|
20
|
-
if attributes.respond_to?(:permitted?)
|
21
|
-
raise ActiveModel::ForbiddenAttributesError
|
20
|
+
if attributes.respond_to?(:permitted?)
|
21
|
+
raise ActiveModel::ForbiddenAttributesError if !attributes.permitted?
|
22
|
+
attributes.to_h
|
22
23
|
else
|
23
24
|
attributes
|
24
25
|
end
|
@@ -1,14 +1,14 @@
|
|
1
1
|
module ActiveModel
|
2
|
-
# Returns the version of the currently loaded Active Model as a <tt>Gem::Version</tt>
|
2
|
+
# Returns the version of the currently loaded \Active \Model as a <tt>Gem::Version</tt>
|
3
3
|
def self.gem_version
|
4
4
|
Gem::Version.new VERSION::STRING
|
5
5
|
end
|
6
6
|
|
7
7
|
module VERSION
|
8
|
-
MAJOR =
|
9
|
-
MINOR =
|
10
|
-
TINY =
|
11
|
-
PRE = "
|
8
|
+
MAJOR = 5
|
9
|
+
MINOR = 0
|
10
|
+
TINY = 0
|
11
|
+
PRE = "beta1"
|
12
12
|
|
13
13
|
STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")
|
14
14
|
end
|
data/lib/active_model/lint.rb
CHANGED
@@ -21,28 +21,27 @@ module ActiveModel
|
|
21
21
|
# +self+.
|
22
22
|
module Tests
|
23
23
|
|
24
|
-
#
|
24
|
+
# Passes if the object's model responds to <tt>to_key</tt> and if calling
|
25
|
+
# this method returns +nil+ when the object is not persisted.
|
26
|
+
# Fails otherwise.
|
25
27
|
#
|
26
|
-
#
|
27
|
-
#
|
28
|
-
# <tt>dom_id</tt> to generate unique ids for the object.
|
28
|
+
# <tt>to_key</tt> returns an Enumerable of all (primary) key attributes
|
29
|
+
# of the model, and is used to a generate unique DOM id for the object.
|
29
30
|
def test_to_key
|
30
31
|
assert model.respond_to?(:to_key), "The model should respond to to_key"
|
31
32
|
def model.persisted?() false end
|
32
33
|
assert model.to_key.nil?, "to_key should return nil when `persisted?` returns false"
|
33
34
|
end
|
34
35
|
|
35
|
-
#
|
36
|
-
#
|
37
|
-
#
|
38
|
-
# or +nil+ if <tt>model.persisted?</tt> is +false+.
|
36
|
+
# Passes if the object's model responds to <tt>to_param</tt> and if
|
37
|
+
# calling this method returns +nil+ when the object is not persisted.
|
38
|
+
# Fails otherwise.
|
39
39
|
#
|
40
|
+
# <tt>to_param</tt> is used to represent the object's key in URLs.
|
40
41
|
# Implementers can decide to either raise an exception or provide a
|
41
42
|
# default in case the record uses a composite primary key. There are no
|
42
43
|
# tests for this behavior in lint because it doesn't make sense to force
|
43
44
|
# any of the possible implementation strategies on the implementer.
|
44
|
-
# However, if the resource is not persisted?, then <tt>to_param</tt>
|
45
|
-
# should always return +nil+.
|
46
45
|
def test_to_param
|
47
46
|
assert model.respond_to?(:to_param), "The model should respond to to_param"
|
48
47
|
def model.to_key() [1] end
|
@@ -50,32 +49,34 @@ module ActiveModel
|
|
50
49
|
assert model.to_param.nil?, "to_param should return nil when `persisted?` returns false"
|
51
50
|
end
|
52
51
|
|
53
|
-
#
|
52
|
+
# Passes if the object's model responds to <tt>to_partial_path</tt> and if
|
53
|
+
# calling this method returns a string. Fails otherwise.
|
54
54
|
#
|
55
|
-
#
|
56
|
-
#
|
55
|
+
# <tt>to_partial_path</tt> is used for looking up partials. For example,
|
56
|
+
# a BlogPost model might return "blog_posts/blog_post".
|
57
57
|
def test_to_partial_path
|
58
58
|
assert model.respond_to?(:to_partial_path), "The model should respond to to_partial_path"
|
59
59
|
assert_kind_of String, model.to_partial_path
|
60
60
|
end
|
61
61
|
|
62
|
-
#
|
62
|
+
# Passes if the object's model responds to <tt>persisted?</tt> and if
|
63
|
+
# calling this method returns either +true+ or +false+. Fails otherwise.
|
63
64
|
#
|
64
|
-
#
|
65
|
-
#
|
66
|
-
#
|
67
|
-
#
|
68
|
-
# to the update action.
|
65
|
+
# <tt>persisted?</tt> is used when calculating the URL for an object.
|
66
|
+
# If the object is not persisted, a form for that object, for instance,
|
67
|
+
# will route to the create action. If it is persisted, a form for the
|
68
|
+
# object will route to the update action.
|
69
69
|
def test_persisted?
|
70
70
|
assert model.respond_to?(:persisted?), "The model should respond to persisted?"
|
71
71
|
assert_boolean model.persisted?, "persisted?"
|
72
72
|
end
|
73
73
|
|
74
|
-
#
|
74
|
+
# Passes if the object's model responds to <tt>model_name</tt> both as
|
75
|
+
# an instance method and as a class method, and if calling this method
|
76
|
+
# returns a string with some convenience methods: <tt>:human</tt>,
|
77
|
+
# <tt>:singular</tt> and <tt>:plural</tt>.
|
75
78
|
#
|
76
|
-
#
|
77
|
-
# convenience methods: # <tt>:human</tt>, <tt>:singular</tt> and
|
78
|
-
# <tt>:plural</tt>. Check ActiveModel::Naming for more information.
|
79
|
+
# Check ActiveModel::Naming for more information.
|
79
80
|
def test_model_naming
|
80
81
|
assert model.class.respond_to?(:model_name), "The model class should respond to model_name"
|
81
82
|
model_name = model.class.model_name
|
@@ -88,12 +89,15 @@ module ActiveModel
|
|
88
89
|
assert_equal model.model_name, model.class.model_name
|
89
90
|
end
|
90
91
|
|
91
|
-
#
|
92
|
+
# Passes if the object's model responds to <tt>errors</tt> and if calling
|
93
|
+
# <tt>[](attribute)</tt> on the result of this method returns an array.
|
94
|
+
# Fails otherwise.
|
92
95
|
#
|
93
|
-
#
|
94
|
-
#
|
95
|
-
#
|
96
|
-
#
|
96
|
+
# <tt>errors[attribute]</tt> is used to retrieve the errors of a model
|
97
|
+
# for a given attribute. If errors are present, the method should return
|
98
|
+
# an array of strings that are the errors for the attribute in question.
|
99
|
+
# If localization is used, the strings should be localized for the current
|
100
|
+
# locale. If no error is present, the method should return an empty array.
|
97
101
|
def test_errors_aref
|
98
102
|
assert model.respond_to?(:errors), "The model should respond to errors"
|
99
103
|
assert model.errors[:hello].is_a?(Array), "errors#[] should return an Array"
|
@@ -6,6 +6,7 @@ en:
|
|
6
6
|
# The values :model, :attribute and :value are always available for interpolation
|
7
7
|
# The value :count is available when applicable. Can be used for pluralization.
|
8
8
|
messages:
|
9
|
+
model_invalid: "Validation failed: %{errors}"
|
9
10
|
inclusion: "is not included in the list"
|
10
11
|
exclusion: "is reserved"
|
11
12
|
invalid: "is invalid"
|
@@ -16,7 +17,7 @@ en:
|
|
16
17
|
present: "must be blank"
|
17
18
|
too_long:
|
18
19
|
one: "is too long (maximum is 1 character)"
|
19
|
-
other: "is too long (maximum is %{count} characters)"
|
20
|
+
other: "is too long (maximum is %{count} characters)"
|
20
21
|
too_short:
|
21
22
|
one: "is too short (minimum is 1 character)"
|
22
23
|
other: "is too short (minimum is %{count} characters)"
|
data/lib/active_model/model.rb
CHANGED
@@ -57,6 +57,7 @@ module ActiveModel
|
|
57
57
|
# (see below).
|
58
58
|
module Model
|
59
59
|
extend ActiveSupport::Concern
|
60
|
+
include ActiveModel::AttributeAssignment
|
60
61
|
include ActiveModel::Validations
|
61
62
|
include ActiveModel::Conversion
|
62
63
|
|
@@ -75,10 +76,8 @@ module ActiveModel
|
|
75
76
|
# person = Person.new(name: 'bob', age: '18')
|
76
77
|
# person.name # => "bob"
|
77
78
|
# person.age # => "18"
|
78
|
-
def initialize(
|
79
|
-
|
80
|
-
self.public_send("#{attr}=", value)
|
81
|
-
end if params
|
79
|
+
def initialize(attributes={})
|
80
|
+
assign_attributes(attributes) if attributes
|
82
81
|
|
83
82
|
super()
|
84
83
|
end
|
data/lib/active_model/naming.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'active_support/core_ext/hash/except'
|
2
2
|
require 'active_support/core_ext/module/introspection'
|
3
3
|
require 'active_support/core_ext/module/remove_method'
|
4
|
+
require 'active_support/core_ext/module/delegation'
|
4
5
|
|
5
6
|
module ActiveModel
|
6
7
|
class Name
|
@@ -163,7 +164,7 @@ module ActiveModel
|
|
163
164
|
@route_key << "_index" if @plural == @singular
|
164
165
|
end
|
165
166
|
|
166
|
-
# Transform the model name into a more
|
167
|
+
# Transform the model name into a more human format, using I18n. By default,
|
167
168
|
# it will underscore then humanize the class name.
|
168
169
|
#
|
169
170
|
# class BlogPost
|
@@ -190,8 +191,8 @@ module ActiveModel
|
|
190
191
|
|
191
192
|
private
|
192
193
|
|
193
|
-
def _singularize(string
|
194
|
-
ActiveSupport::Inflector.underscore(string).tr('/',
|
194
|
+
def _singularize(string)
|
195
|
+
ActiveSupport::Inflector.underscore(string).tr('/'.freeze, '_'.freeze)
|
195
196
|
end
|
196
197
|
end
|
197
198
|
|
@@ -212,7 +213,7 @@ module ActiveModel
|
|
212
213
|
# BookModule::BookCover.model_name.i18n_key # => :"book_module/book_cover"
|
213
214
|
#
|
214
215
|
# Providing the functionality that ActiveModel::Naming provides in your object
|
215
|
-
# is required to pass the Active Model Lint test. So either extending the
|
216
|
+
# is required to pass the \Active \Model Lint test. So either extending the
|
216
217
|
# provided method below, or rolling your own is required.
|
217
218
|
module Naming
|
218
219
|
def self.extended(base) #:nodoc:
|
@@ -26,7 +26,7 @@ module ActiveModel
|
|
26
26
|
# it). When this attribute has a +nil+ value, the validation will not be
|
27
27
|
# triggered.
|
28
28
|
#
|
29
|
-
# For further customizability, it is possible to
|
29
|
+
# For further customizability, it is possible to suppress the default
|
30
30
|
# validations by passing <tt>validations: false</tt> as an argument.
|
31
31
|
#
|
32
32
|
# Add bcrypt (~> 3.1.7) to Gemfile to use #has_secure_password:
|
@@ -77,13 +77,6 @@ module ActiveModel
|
|
77
77
|
validates_length_of :password, maximum: ActiveModel::SecurePassword::MAX_PASSWORD_LENGTH_ALLOWED
|
78
78
|
validates_confirmation_of :password, allow_blank: true
|
79
79
|
end
|
80
|
-
|
81
|
-
# This code is necessary as long as the protected_attributes gem is supported.
|
82
|
-
if respond_to?(:attributes_protected_by_default)
|
83
|
-
def self.attributes_protected_by_default #:nodoc:
|
84
|
-
super + ['password_digest']
|
85
|
-
end
|
86
|
-
end
|
87
80
|
end
|
88
81
|
end
|
89
82
|
|
@@ -99,7 +92,7 @@ module ActiveModel
|
|
99
92
|
# user.authenticate('notright') # => false
|
100
93
|
# user.authenticate('mUc3m00RsqyRe') # => user
|
101
94
|
def authenticate(unencrypted_password)
|
102
|
-
BCrypt::Password.new(password_digest)
|
95
|
+
BCrypt::Password.new(password_digest).is_password?(unencrypted_password) && self
|
103
96
|
end
|
104
97
|
|
105
98
|
attr_reader :password
|
@@ -31,16 +31,14 @@ module ActiveModel
|
|
31
31
|
# of the attributes hash's keys. In order to override this behavior, take a look
|
32
32
|
# at the private method +read_attribute_for_serialization+.
|
33
33
|
#
|
34
|
-
#
|
35
|
-
#
|
36
|
-
# <tt>ActiveModel::Serialization</tt
|
37
|
-
# explicitly include it.
|
34
|
+
# ActiveModel::Serializers::JSON module automatically includes
|
35
|
+
# the <tt>ActiveModel::Serialization</tt> module, so there is no need to
|
36
|
+
# explicitly include <tt>ActiveModel::Serialization</tt>.
|
38
37
|
#
|
39
|
-
# A minimal implementation including
|
38
|
+
# A minimal implementation including JSON would be:
|
40
39
|
#
|
41
40
|
# class Person
|
42
41
|
# include ActiveModel::Serializers::JSON
|
43
|
-
# include ActiveModel::Serializers::Xml
|
44
42
|
#
|
45
43
|
# attr_accessor :name
|
46
44
|
#
|
@@ -55,13 +53,11 @@ module ActiveModel
|
|
55
53
|
# person.serializable_hash # => {"name"=>nil}
|
56
54
|
# person.as_json # => {"name"=>nil}
|
57
55
|
# person.to_json # => "{\"name\":null}"
|
58
|
-
# person.to_xml # => "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<serial-person...
|
59
56
|
#
|
60
57
|
# person.name = "Bob"
|
61
58
|
# person.serializable_hash # => {"name"=>"Bob"}
|
62
59
|
# person.as_json # => {"name"=>"Bob"}
|
63
60
|
# person.to_json # => "{\"name\":\"Bob\"}"
|
64
|
-
# person.to_xml # => "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<serial-person...
|
65
61
|
#
|
66
62
|
# Valid options are <tt>:only</tt>, <tt>:except</tt>, <tt>:methods</tt> and
|
67
63
|
# <tt>:include</tt>. The following are all valid examples:
|
@@ -94,6 +90,37 @@ module ActiveModel
|
|
94
90
|
# person.serializable_hash(except: :name) # => {"age"=>22}
|
95
91
|
# person.serializable_hash(methods: :capitalized_name)
|
96
92
|
# # => {"name"=>"bob", "age"=>22, "capitalized_name"=>"Bob"}
|
93
|
+
#
|
94
|
+
# Example with <tt>:include</tt> option
|
95
|
+
#
|
96
|
+
# class User
|
97
|
+
# include ActiveModel::Serializers::JSON
|
98
|
+
# attr_accessor :name, :notes # Emulate has_many :notes
|
99
|
+
# def attributes
|
100
|
+
# {'name' => nil}
|
101
|
+
# end
|
102
|
+
# end
|
103
|
+
#
|
104
|
+
# class Note
|
105
|
+
# include ActiveModel::Serializers::JSON
|
106
|
+
# attr_accessor :title, :text
|
107
|
+
# def attributes
|
108
|
+
# {'title' => nil, 'text' => nil}
|
109
|
+
# end
|
110
|
+
# end
|
111
|
+
#
|
112
|
+
# note = Note.new
|
113
|
+
# note.title = 'Battle of Austerlitz'
|
114
|
+
# note.text = 'Some text here'
|
115
|
+
#
|
116
|
+
# user = User.new
|
117
|
+
# user.name = 'Napoleon'
|
118
|
+
# user.notes = [note]
|
119
|
+
#
|
120
|
+
# user.serializable_hash
|
121
|
+
# # => {"name" => "Napoleon"}
|
122
|
+
# user.serializable_hash(include: { notes: { only: 'title' }})
|
123
|
+
# # => {"name" => "Napoleon", "notes" => [{"title"=>"Battle of Austerlitz"}]}
|
97
124
|
def serializable_hash(options = nil)
|
98
125
|
options ||= {}
|
99
126
|
|
@@ -107,7 +134,7 @@ module ActiveModel
|
|
107
134
|
hash = {}
|
108
135
|
attribute_names.each { |n| hash[n] = read_attribute_for_serialization(n) }
|
109
136
|
|
110
|
-
Array(options[:methods]).each { |m| hash[m.to_s] = send(m)
|
137
|
+
Array(options[:methods]).each { |m| hash[m.to_s] = send(m) }
|
111
138
|
|
112
139
|
serializable_add_includes(options) do |association, records, opts|
|
113
140
|
hash[association.to_s] = if records.respond_to?(:to_ary)
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'active_model/type/helpers'
|
2
|
+
require 'active_model/type/value'
|
3
|
+
|
4
|
+
require 'active_model/type/big_integer'
|
5
|
+
require 'active_model/type/binary'
|
6
|
+
require 'active_model/type/boolean'
|
7
|
+
require 'active_model/type/date'
|
8
|
+
require 'active_model/type/date_time'
|
9
|
+
require 'active_model/type/decimal'
|
10
|
+
require 'active_model/type/decimal_without_scale'
|
11
|
+
require 'active_model/type/float'
|
12
|
+
require 'active_model/type/immutable_string'
|
13
|
+
require 'active_model/type/integer'
|
14
|
+
require 'active_model/type/string'
|
15
|
+
require 'active_model/type/text'
|
16
|
+
require 'active_model/type/time'
|
17
|
+
require 'active_model/type/unsigned_integer'
|
18
|
+
|
19
|
+
require 'active_model/type/registry'
|
20
|
+
|
21
|
+
module ActiveModel
|
22
|
+
module Type
|
23
|
+
@registry = Registry.new
|
24
|
+
|
25
|
+
class << self
|
26
|
+
attr_accessor :registry # :nodoc:
|
27
|
+
delegate :add_modifier, to: :registry
|
28
|
+
|
29
|
+
# Add a new type to the registry, allowing it to be referenced as a
|
30
|
+
# symbol by ActiveModel::Attributes::ClassMethods#attribute. If your
|
31
|
+
# type is only meant to be used with a specific database adapter, you can
|
32
|
+
# do so by passing +adapter: :postgresql+. If your type has the same
|
33
|
+
# name as a native type for the current adapter, an exception will be
|
34
|
+
# raised unless you specify an +:override+ option. +override: true+ will
|
35
|
+
# cause your type to be used instead of the native type. +override:
|
36
|
+
# false+ will cause the native type to be used over yours if one exists.
|
37
|
+
def register(type_name, klass = nil, **options, &block)
|
38
|
+
registry.register(type_name, klass, **options, &block)
|
39
|
+
end
|
40
|
+
|
41
|
+
def lookup(*args, **kwargs) # :nodoc:
|
42
|
+
registry.lookup(*args, **kwargs)
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
register(:big_integer, Type::BigInteger)
|
47
|
+
register(:binary, Type::Binary)
|
48
|
+
register(:boolean, Type::Boolean)
|
49
|
+
register(:date, Type::Date)
|
50
|
+
register(:date_time, Type::DateTime)
|
51
|
+
register(:decimal, Type::Decimal)
|
52
|
+
register(:float, Type::Float)
|
53
|
+
register(:immutable_string, Type::ImmutableString)
|
54
|
+
register(:integer, Type::Integer)
|
55
|
+
register(:string, Type::String)
|
56
|
+
register(:text, Type::Text)
|
57
|
+
register(:time, Type::Time)
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
module ActiveModel
|
2
|
+
module Type
|
3
|
+
class Binary < Value # :nodoc:
|
4
|
+
def type
|
5
|
+
:binary
|
6
|
+
end
|
7
|
+
|
8
|
+
def binary?
|
9
|
+
true
|
10
|
+
end
|
11
|
+
|
12
|
+
def cast(value)
|
13
|
+
if value.is_a?(Data)
|
14
|
+
value.to_s
|
15
|
+
else
|
16
|
+
super
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def serialize(value)
|
21
|
+
return if value.nil?
|
22
|
+
Data.new(super)
|
23
|
+
end
|
24
|
+
|
25
|
+
def changed_in_place?(raw_old_value, value)
|
26
|
+
old_value = deserialize(raw_old_value)
|
27
|
+
old_value != value
|
28
|
+
end
|
29
|
+
|
30
|
+
class Data # :nodoc:
|
31
|
+
def initialize(value)
|
32
|
+
@value = value.to_s
|
33
|
+
end
|
34
|
+
|
35
|
+
def to_s
|
36
|
+
@value
|
37
|
+
end
|
38
|
+
alias_method :to_str, :to_s
|
39
|
+
|
40
|
+
def hex
|
41
|
+
@value.unpack('H*')[0]
|
42
|
+
end
|
43
|
+
|
44
|
+
def ==(other)
|
45
|
+
other == to_s || super
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|