1 |
NAME |
2 |
Types::Serialiser - simple data types for common serialisation formats |
3 |
|
4 |
SYNOPSIS |
5 |
DESCRIPTION |
6 |
This module provides some extra datatypes that are used by common |
7 |
serialisation formats such as JSON or CBOR. The idea is to have a |
8 |
repository of simple/small constants and containers that can be shared |
9 |
by different implementations so they become interoperable between each |
10 |
other. |
11 |
|
12 |
SIMPLE SCALAR CONSTANTS |
13 |
Simple scalar constants are values that are overloaded to act like |
14 |
simple Perl values, but have (class) type to differentiate them from |
15 |
normal Perl scalars. This is necessary because these have different |
16 |
representations in the serialisation formats. |
17 |
|
18 |
In the following, functions with zero or one arguments have a prototype |
19 |
of "()" and "($)", respectively, so act as constants and unary |
20 |
operators. |
21 |
|
22 |
BOOLEANS (Types::Serialiser::Boolean class) |
23 |
This type has only two instances, true and false. A natural |
24 |
representation for these in Perl is 1 and 0, but serialisation formats |
25 |
need to be able to differentiate between them and mere numbers. |
26 |
|
27 |
$Types::Serialiser::true, Types::Serialiser::true |
28 |
This value represents the "true" value. In most contexts is acts |
29 |
like the number 1. It is up to you whether you use the variable form |
30 |
($Types::Serialiser::true) or the constant form |
31 |
("Types::Serialiser::true"). |
32 |
|
33 |
The constant is represented as a reference to a scalar containing 1 |
34 |
- implementations are allowed to directly test for this. |
35 |
|
36 |
$Types::Serialiser::false, Types::Serialiser::false |
37 |
This value represents the "false" value. In most contexts is acts |
38 |
like the number 0. It is up to you whether you use the variable form |
39 |
($Types::Serialiser::false) or the constant form |
40 |
("Types::Serialiser::false"). |
41 |
|
42 |
The constant is represented as a reference to a scalar containing 0 |
43 |
- implementations are allowed to directly test for this. |
44 |
|
45 |
Types::Serialiser::as_bool $value |
46 |
Converts a Perl scalar into a boolean, which is useful syntactic |
47 |
sugar. Strictly equivalent to: |
48 |
|
49 |
$value ? $Types::Serialiser::true : $Types::Serialiser::false |
50 |
|
51 |
$is_bool = Types::Serialiser::is_bool $value |
52 |
Returns true iff the $value is either $Types::Serialiser::true or |
53 |
$Types::Serialiser::false. |
54 |
|
55 |
For example, you could differentiate between a perl true value and a |
56 |
"Types::Serialiser::true" by using this: |
57 |
|
58 |
$value && Types::Serialiser::is_bool $value |
59 |
|
60 |
$is_true = Types::Serialiser::is_true $value |
61 |
Returns true iff $value is $Types::Serialiser::true. |
62 |
|
63 |
$is_false = Types::Serialiser::is_false $value |
64 |
Returns false iff $value is $Types::Serialiser::false. |
65 |
|
66 |
ERROR (Types::Serialiser::Error class) |
67 |
This class has only a single instance, "error". It is used to signal an |
68 |
encoding or decoding error. In CBOR for example, and object that |
69 |
couldn't be encoded will be represented by a CBOR undefined value, which |
70 |
is represented by the error value in Perl. |
71 |
|
72 |
$Types::Serialiser::error, Types::Serialiser::error |
73 |
This value represents the "error" value. Accessing values of this |
74 |
type will throw an exception. |
75 |
|
76 |
The constant is represented as a reference to a scalar containing |
77 |
"undef" - implementations are allowed to directly test for this. |
78 |
|
79 |
$is_error = Types::Serialiser::is_error $value |
80 |
Returns false iff $value is $Types::Serialiser::error. |
81 |
|
82 |
NOTES FOR XS USERS |
83 |
The recommended way to detect whether a scalar is one of these objects |
84 |
is to check whether the stash is the "Types::Serialiser::Boolean" or |
85 |
"Types::Serialiser::Error" stash, and then follow the scalar reference |
86 |
to see if it's 1 (true), 0 (false) or "undef" (error). |
87 |
|
88 |
While it is possible to use an isa test, directly comparing stash |
89 |
pointers is faster and guaranteed to work. |
90 |
|
91 |
For historical reasons, the "Types::Serialiser::Boolean" stash is just |
92 |
an alias for "JSON::PP::Boolean". When printed, the classname with |
93 |
usually be "JSON::PP::Boolean", but isa tests and stash pointer |
94 |
comparison will normally work correctly (i.e. Types::Serialiser::true |
95 |
ISA JSON::PP::Boolean, but also ISA Types::Serialiser::Boolean). |
96 |
|
97 |
A GENERIC OBJECT SERIALIATION PROTOCOL |
98 |
This section explains the object serialisation protocol used by |
99 |
CBOR::XS. It is meant to be generic enough to support any kind of |
100 |
generic object serialiser. |
101 |
|
102 |
This protocol is called "the Types::Serialiser object serialisation |
103 |
protocol". |
104 |
|
105 |
ENCODING |
106 |
When the encoder encounters an object that it cannot otherwise encode |
107 |
(for example, CBOR::XS can encode a few special types itself, and will |
108 |
first attempt to use the special "TO_CBOR" serialisation protocol), it |
109 |
will look up the "FREEZE" method on the object. |
110 |
|
111 |
Note that the "FREEZE" method will normally be called *during* encoding, |
112 |
and *MUST NOT* change the data structure that is being encoded in any |
113 |
way, or it might cause memory corruption or worse. |
114 |
|
115 |
If it exists, it will call it with two arguments: the object to |
116 |
serialise, and a constant string that indicates the name of the data |
117 |
model. For example CBOR::XS uses "CBOR", and the JSON and JSON::XS |
118 |
modules (or any other JSON serialiser), would use "JSON" as second |
119 |
argument. |
120 |
|
121 |
The "FREEZE" method can then return zero or more values to identify the |
122 |
object instance. The serialiser is then supposed to encode the class |
123 |
name and all of these return values (which must be encodable in the |
124 |
format) using the relevant form for Perl objects. In CBOR for example, |
125 |
there is a registered tag number for encoded perl objects. |
126 |
|
127 |
The values that "FREEZE" returns must be serialisable with the |
128 |
serialiser that calls it. Therefore, it is recommended to use simple |
129 |
types such as strings and numbers, and maybe array references and hashes |
130 |
(basically, the JSON data model). You can always use a more complex |
131 |
format for a specific data model by checking the second argument, the |
132 |
data model. |
133 |
|
134 |
The "data model" is not the same as the "data format" - the data model |
135 |
indicates what types and kinds of return values can be returned from |
136 |
"FREEZE". For example, in "CBOR" it is permissible to return tagged CBOR |
137 |
values, while JSON does not support these at all, so "JSON" would be a |
138 |
valid (but too limited) data model name for "CBOR::XS". similarly, a |
139 |
serialising format that supports more or less the same data model as |
140 |
JSON could use "JSON" as data model without losing anything. |
141 |
|
142 |
DECODING |
143 |
When the decoder then encounters such an encoded perl object, it should |
144 |
look up the "THAW" method on the stored classname, and invoke it with |
145 |
the classname, the constant string to identify the data model/data |
146 |
format, and all the return values returned by "FREEZE". |
147 |
|
148 |
EXAMPLES |
149 |
See the "OBJECT SERIALISATION" section in the CBOR::XS manpage for more |
150 |
details, an example implementation, and code examples. |
151 |
|
152 |
Here is an example "FREEZE"/"THAW" method pair: |
153 |
|
154 |
sub My::Object::FREEZE { |
155 |
my ($self, $model) = @_; |
156 |
|
157 |
($self->{type}, $self->{id}, $self->{variant}) |
158 |
} |
159 |
|
160 |
sub My::Object::THAW { |
161 |
my ($class, $model, $type, $id, $variant) = @_; |
162 |
|
163 |
$class->new (type => $type, id => $id, variant => $variant) |
164 |
} |
165 |
|
166 |
BUGS |
167 |
The use of overload makes this module much heavier than it should be (on |
168 |
my system, this module: 4kB RSS, overload: 260kB RSS). |
169 |
|
170 |
SEE ALSO |
171 |
Currently, JSON::XS and CBOR::XS use these types. |
172 |
|
173 |
AUTHOR |
174 |
Marc Lehmann <schmorp@schmorp.de> |
175 |
http://home.schmorp.de/ |
176 |
|