ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/Types-Serialiser/Serialiser.pm
Revision: 1.1
Committed: Sun Oct 27 19:49:33 2013 UTC (10 years, 8 months ago) by root
Branch: MAIN
Log Message:
*** empty log message ***

File Contents

# Content
1 =head1 NAME
2
3 Types::Serialiser - simple data types for common serialisation formats
4
5 =encoding utf-8
6
7 =head1 SYNOPSIS
8
9 =head1 DESCRIPTION
10
11 This module provides some extra datatypes that are used by common
12 serialisation formats such as JSON or CBOR. The idea is to have a
13 repository of simple/small constants and containers that can be shared by
14 different implementations so they become interoperable between each other.
15
16 =cut
17
18 package Types::Serialiser;
19
20 use common::sense;
21
22 our $VERSION = 0.01;
23
24 =head1 SIMPLE SCALAR CONSTANTS
25
26 Simple scalar constants are values that are overloaded to act like simple
27 Perl values, but have (class) type to differentiate them from normal Perl
28 scalars. This is necessary because these have different representations in
29 the serialisation formats.
30
31 =head2 BOOLEANS (Types::Serialiser::Boolean class)
32
33 This type has only two instances, true and false. A natural representation
34 for these in Perl is C<1> and C<0>, but serialisation formats need to be
35 able to differentiate between them and mere numbers.
36
37 =over 4
38
39 =item $Types::Serialiser::true, Types::Serialiser::true
40
41 This value represents the "true" value. In most contexts is acts like
42 the number C<1>. It is up to you whether you use the variable form
43 (C<$Types::Serialiser::true>) or the constant form (C<Types::Serialiser::true>).
44
45 The constant is represented as a reference to a scalar containing C<1> -
46 implementations are allowed to directly test for this.
47
48 =item $Types::Serialiser::false, Types::Serialiser::false
49
50 This value represents the "false" value. In most contexts is acts like
51 the 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>).
53
54 The constant is represented as a reference to a scalar containing C<0> -
55 implementations are allowed to directly test for this.
56
57 =item $is_bool = Types::Serialiser::is_bool $value
58
59 Returns true iff the C<$value> is either C<$Types::Serialiser::true> or
60 C<$Types::Serialiser::false>.
61
62 For example, you could differentiate between a perl true value and a
63 C<Types::Serialiser::true> by using this:
64
65 $value && Types::Serialiser::is_bool $value
66
67 =item $is_true = Types::Serialiser::is_true $value
68
69 Returns true iff C<$value> is C<$Types::Serialiser::true>.
70
71 =item $is_false = Types::Serialiser::is_false $value
72
73 Returns false iff C<$value> is C<$Types::Serialiser::false>.
74
75 =back
76
77 =head2 ERROR (Types::Serialiser::Error class)
78
79 This class has only a single instance, C<error>. It is used to signal
80 an encoding or decoding error. In CBOR for example, and object that
81 couldn't be encoded will be represented by a CBOR undefined value, which
82 is represented by the error value in Perl.
83
84 =over 4
85
86 =item $Types::Serialiser::error, Types::Serialiser::error
87
88 This value represents the "error" value. Accessing values of this type
89 will throw an exception.
90
91 The constant is represented as a reference to a scalar containing C<undef>
92 - implementations are allowed to directly test for this.
93
94 =item $is_error = Types::Serialiser::is_error $value
95
96 Returns false iff C<$value> is C<$Types::Serialiser::error>.
97
98 =back
99
100 =cut
101
102 our $true = do { bless \(my $dummy = 1), Types::Serialiser::Boolean:: };
103 our $false = do { bless \(my $dummy = 0), Types::Serialiser::Boolean:: };
104 our $error = do { bless \(my $dummy ), Types::Serialiser::Error:: };
105
106 sub true () { $true }
107 sub false () { $false }
108 sub error () { $error }
109
110 sub is_bool ($) { UNIVERSAL::isa $_[0], Types::Serialiser::Boolean:: }
111 sub is_true ($) { $_[0] && UNIVERSAL::isa $_[0], Types::Serialiser::Boolean:: }
112 sub is_false ($) { !$_[0] && UNIVERSAL::isa $_[0], Types::Serialiser::Boolean:: }
113 sub is_error ($) { UNIVERSAL::isa $_[0], Types::Serialiser::Error:: }
114
115 package Types::Serialiser::Boolean;
116
117 use overload
118 "0+" => sub { ${$_[0]} },
119 "++" => sub { $_[0] = ${$_[0]} + 1 },
120 "--" => sub { $_[0] = ${$_[0]} - 1 },
121 fallback => 1;
122
123 package Types::Serialiser::Error;
124
125 sub error {
126 require Carp;
127 Carp::croak ("caught attempt to use Types::Serialiser::error value");
128 };
129
130 use overload
131 "0+" => \&error,
132 "++" => \&error,
133 "--" => \&error,
134 fallback => 1;
135
136 =head1 BUGS
137
138 The use of L<overload> makes this module much heavier than it should be
139 (on my system, this module: 4kB RSS, overload: 260kB RSS).
140
141 =head1 SEE ALSO
142
143 Currently, L<JSON::XS> and L<CBOR::XS> use these types.
144
145 =head1 AUTHOR
146
147 Marc Lehmann <schmorp@schmorp.de>
148 http://home.schmorp.de/
149
150 =cut
151
152 1
153