ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Types-Serialiser/Serialiser.pm
(Generate patch)

Comparing Types-Serialiser/Serialiser.pm (file contents):
Revision 1.7 by root, Tue Oct 29 18:33:11 2013 UTC vs.
Revision 1.10 by root, Tue Dec 1 01:47:20 2020 UTC

17 17
18package Types::Serialiser; 18package Types::Serialiser;
19 19
20use common::sense; # required to suppress annoying warnings 20use common::sense; # required to suppress annoying warnings
21 21
22our $VERSION = 0.03; 22our $VERSION = '1.01';
23 23
24=head1 SIMPLE SCALAR CONSTANTS 24=head1 SIMPLE SCALAR CONSTANTS
25 25
26Simple scalar constants are values that are overloaded to act like simple 26Simple scalar constants are values that are overloaded to act like simple
27Perl values, but have (class) type to differentiate them from normal Perl 27Perl values, but have (class) type to differentiate them from normal Perl
28scalars. This is necessary because these have different representations in 28scalars. This is necessary because these have different representations in
29the serialisation formats. 29the serialisation formats.
30 30
31In the following, functions with zero or one arguments have a prototype of
32C<()> and C<($)>, respectively, so act as constants and unary operators.
33
31=head2 BOOLEANS (Types::Serialiser::Boolean class) 34=head2 BOOLEANS (Types::Serialiser::Boolean class)
32 35
33This type has only two instances, true and false. A natural representation 36This type has only two instances, true and false. A natural representation
34for these in Perl is C<1> and C<0>, but serialisation formats need to be 37for these in Perl is C<1> and C<0>, but serialisation formats need to be
35able to differentiate between them and mere numbers. 38able to differentiate between them and mere numbers.
51the number C<0>. It is up to you whether you use the variable form 54the number C<0>. It is up to you whether you use the variable form
52(C<$Types::Serialiser::false>) or the constant form (C<Types::Serialiser::false>). 55(C<$Types::Serialiser::false>) or the constant form (C<Types::Serialiser::false>).
53 56
54The constant is represented as a reference to a scalar containing C<0> - 57The constant is represented as a reference to a scalar containing C<0> -
55implementations are allowed to directly test for this. 58implementations are allowed to directly test for this.
59
60=item Types::Serialiser::as_bool $value
61
62Converts a Perl scalar into a boolean, which is useful syntactic
63sugar. Strictly equivalent to:
64
65 $value ? $Types::Serialiser::true : $Types::Serialiser::false
56 66
57=item $is_bool = Types::Serialiser::is_bool $value 67=item $is_bool = Types::Serialiser::is_bool $value
58 68
59Returns true iff the C<$value> is either C<$Types::Serialiser::true> or 69Returns true iff the C<$value> is either C<$Types::Serialiser::true> or
60C<$Types::Serialiser::false>. 70C<$Types::Serialiser::false>.
127 137
128sub true () { $true } 138sub true () { $true }
129sub false () { $false } 139sub false () { $false }
130sub error () { $error } 140sub error () { $error }
131 141
142sub as_bool($) { $_[0] ? $true : $false }
143
132sub is_bool ($) { UNIVERSAL::isa $_[0], Types::Serialiser::Boolean:: } 144sub is_bool ($) { UNIVERSAL::isa $_[0], Types::Serialiser::Boolean:: }
133sub is_true ($) { $_[0] && UNIVERSAL::isa $_[0], Types::Serialiser::Boolean:: } 145sub is_true ($) { $_[0] && UNIVERSAL::isa $_[0], Types::Serialiser::Boolean:: }
134sub is_false ($) { !$_[0] && UNIVERSAL::isa $_[0], Types::Serialiser::Boolean:: } 146sub is_false ($) { !$_[0] && UNIVERSAL::isa $_[0], Types::Serialiser::Boolean:: }
135sub is_error ($) { UNIVERSAL::isa $_[0], Types::Serialiser::Error:: } 147sub is_error ($) { UNIVERSAL::isa $_[0], Types::Serialiser::Error:: }
136 148
157While it is possible to use an isa test, directly comparing stash pointers 169While it is possible to use an isa test, directly comparing stash pointers
158is faster and guaranteed to work. 170is faster and guaranteed to work.
159 171
160For historical reasons, the C<Types::Serialiser::Boolean> stash is 172For historical reasons, the C<Types::Serialiser::Boolean> stash is
161just an alias for C<JSON::PP::Boolean>. When printed, the classname 173just an alias for C<JSON::PP::Boolean>. When printed, the classname
162withh usually be C<JSON::PP::Boolean>, but isa tests and stash pointer 174with usually be C<JSON::PP::Boolean>, but isa tests and stash pointer
163comparison will normally work correctly (i.e. Types::Serialiser::true ISA 175comparison will normally work correctly (i.e. Types::Serialiser::true ISA
164JSON::PP::Boolean, but also ISA Types::Serialiser::Boolean). 176JSON::PP::Boolean, but also ISA Types::Serialiser::Boolean).
165 177
166=head1 A GENERIC OBJECT SERIALIATION PROTOCOL 178=head1 A GENERIC OBJECT SERIALIATION PROTOCOL
167 179
177When the encoder encounters an object that it cannot otherwise encode (for 189When the encoder encounters an object that it cannot otherwise encode (for
178example, L<CBOR::XS> can encode a few special types itself, and will first 190example, L<CBOR::XS> can encode a few special types itself, and will first
179attempt to use the special C<TO_CBOR> serialisation protocol), it will 191attempt to use the special C<TO_CBOR> serialisation protocol), it will
180look up the C<FREEZE> method on the object. 192look up the C<FREEZE> method on the object.
181 193
194Note that the C<FREEZE> method will normally be called I<during> encoding,
195and I<MUST NOT> change the data structure that is being encoded in any
196way, or it might cause memory corruption or worse.
197
182If it exists, it will call it with two arguments: the object to 198If it exists, it will call it with two arguments: the object to serialise,
183serialise, and a constant string that indicates the name of the 199and a constant string that indicates the name of the data model. For
184serialisationformat. For example L<CBOR::XS> uses C<CBOR>, and L<JSON> and 200example L<CBOR::XS> uses C<CBOR>, and the L<JSON> and L<JSON::XS> modules
185L<JSON::XS> (or any other JSON serialiser), would use C<JSON> as second 201(or any other JSON serialiser), would use C<JSON> as second argument.
186argument.
187 202
188The C<FREEZE> method can then return zero or more values to identify the 203The C<FREEZE> method can then return zero or more values to identify the
189object instance. The serialiser is then supposed to encode the class name 204object instance. The serialiser is then supposed to encode the class name
190and all of these return values (which must be encodable in the format) 205and all of these return values (which must be encodable in the format)
191using the relevant form for perl objects. In CBOR for example, there is a 206using the relevant form for Perl objects. In CBOR for example, there is a
192registered tag number for encoded perl objects. 207registered tag number for encoded perl objects.
193 208
194The values that C<FREEZE> returns must be serialisable with the serialiser 209The values that C<FREEZE> returns must be serialisable with the serialiser
195that calls it. Therefore, it is recommended to use simple types such as 210that calls it. Therefore, it is recommended to use simple types such as
196strings and numbers, and maybe array references and hashes (basically, the 211strings and numbers, and maybe array references and hashes (basically, the
197JSON data model). You can always use a more complex format for a specific 212JSON data model). You can always use a more complex format for a specific
198serialiser by checking the second argument. 213data model by checking the second argument, the data model.
214
215The "data model" is not the same as the "data format" - the data model
216indicates what types and kinds of return values can be returned from
217C<FREEZE>. For example, in C<CBOR> it is permissible to return tagged CBOR
218values, while JSON does not support these at all, so C<JSON> would be a
219valid (but too limited) data model name for C<CBOR::XS>. similarly, a
220serialising format that supports more or less the same data model as JSON
221could use C<JSON> as data model without losing anything.
199 222
200=head2 DECODING 223=head2 DECODING
201 224
202When the decoder then encounters such an encoded perl object, it should 225When the decoder then encounters such an encoded perl object, it should
203look up the C<THAW> method on the stored classname, and invoke it with the 226look up the C<THAW> method on the stored classname, and invoke it with the
204classname, the constant string to identify the format, and all the return 227classname, the constant string to identify the data model/data format, and
205values returned by C<FREEZE>. 228all the return values returned by C<FREEZE>.
206 229
207=head2 EXAMPLES 230=head2 EXAMPLES
208 231
209See the C<OBJECT SERIALISATION> section in the L<CBOR::XS> manpage for 232See the C<OBJECT SERIALISATION> section in the L<CBOR::XS> manpage for
210more details, an example implementation, and code examples. 233more details, an example implementation, and code examples.
211 234
212Here is an example C<FREEZE>/C<THAW> method pair: 235Here is an example C<FREEZE>/C<THAW> method pair:
213 236
214 sub My::Object::FREEZE { 237 sub My::Object::FREEZE {
215 my ($self, $serialiser) = @_; 238 my ($self, $model) = @_;
216 239
217 ($self->{type}, $self->{id}, $self->{variant}) 240 ($self->{type}, $self->{id}, $self->{variant})
218 } 241 }
219 242
220 sub My::Object::THAW { 243 sub My::Object::THAW {
221 my ($class, $serialiser, $type, $id, $variant) = @_; 244 my ($class, $model, $type, $id, $variant) = @_;
222 245
223 $class->new (type => $type, id => $id, variant => $variant) 246 $class->new (type => $type, id => $id, variant => $variant)
224 } 247 }
225 248
226=head1 BUGS 249=head1 BUGS

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines