File Coverage

blib/lib/Email/MessageID.pm
Criterion Covered Total %
statement 30 34 88.2
branch 6 8 75.0
condition 5 8 62.5
subroutine 9 11 81.8
pod 4 8 50.0
total 54 69 78.2


line stmt bran cond sub pod time code
1 2     2   59539 use strict;
  2         5  
  2         72  
2 2     2   11 use warnings;
  2         18  
  2         139  
3             package Email::MessageID;
4             # ABSTRACT: Generate world unique message-ids.
5             $Email::MessageID::VERSION = '1.406';
6 2     2   3321 use overload '""' => 'as_string', fallback => 1;
  2         2575  
  2         18  
7              
8             #pod =head1 SYNOPSIS
9             #pod
10             #pod use Email::MessageID;
11             #pod
12             #pod my $mid = Email::MessageID->new->in_brackets;
13             #pod
14             #pod print "Message-ID: $mid\x0D\x0A";
15             #pod
16             #pod =head1 DESCRIPTION
17             #pod
18             #pod Message-ids are optional, but highly recommended, headers that identify a
19             #pod message uniquely. This software generates a unique message-id.
20             #pod
21             #pod =method new
22             #pod
23             #pod my $mid = Email::MessageID->new;
24             #pod
25             #pod my $new_mid = Email::MessageID->new( host => $myhost );
26             #pod
27             #pod This class method constructs an L<Email::Address|Email::Address> object
28             #pod containing a unique message-id. You may specify custom C<host> and C<user>
29             #pod parameters.
30             #pod
31             #pod By default, the C<host> is generated from C<Sys::Hostname::hostname>.
32             #pod
33             #pod By default, the C<user> is generated using C<Time::HiRes>'s C<gettimeofday>
34             #pod and the process ID.
35             #pod
36             #pod Using these values we have the ability to ensure world uniqueness down to
37             #pod a specific process running on a specific host, and the exact time down to
38             #pod six digits of microsecond precision.
39             #pod
40             #pod =cut
41              
42             sub new {
43 1003     1003 1 1975 my ($class, %args) = @_;
44              
45 1003   66     2002 $args{user} ||= $class->create_user;
46 1003   66     2142 $args{host} ||= $class->create_host;
47              
48 1003         3671 my $str = "$args{user}\@$args{host}";
49              
50 1003         1942 bless \$str => $class;
51             }
52              
53             #pod =method create_host
54             #pod
55             #pod my $domain_part = Email::MessageID->create_host;
56             #pod
57             #pod This method returns the domain part of the message-id.
58             #pod
59             #pod =cut
60              
61             my $_SYS_HOSTNAME_LONG;
62             sub create_host {
63 1001 100   1001 1 1292 unless (defined $_SYS_HOSTNAME_LONG) {
64 2   50     4 $_SYS_HOSTNAME_LONG = (eval { require Sys::Hostname::Long; 1 }) || 0;
65 2 50       1078 require Sys::Hostname unless $_SYS_HOSTNAME_LONG;
66             }
67              
68 1001 50       4236 return $_SYS_HOSTNAME_LONG ? Sys::Hostname::Long::hostname_long()
69             : Sys::Hostname::hostname();
70             }
71              
72             #pod =method create_user
73             #pod
74             #pod my $local_part = Email::MessageID->create_user;
75             #pod
76             #pod This method returns a unique local part for the message-id. It includes some
77             #pod random data and some predictable data.
78             #pod
79             #pod =cut
80              
81             my @CHARS = ('A'..'F','a'..'f',0..9);
82              
83             my %uniq;
84              
85             sub create_user {
86             my $noise = join '',
87 1001     1001 1 1558 map {; $CHARS[rand @CHARS] } (0 .. (3 + int rand 6));
  6435         7705  
88              
89 1001         1289 my $t = time;
90 1001 100       1491 my $u = exists $uniq{$t} ? ++$uniq{$t} : (%uniq = ($t => 0))[1];
91              
92 1001         1538 my $user = join '.', $t . $u, $noise, $$;
93 1001         2052 return $user;
94             }
95              
96             #pod =method in_brackets
97             #pod
98             #pod When using Email::MessageID directly to populate the C<Message-ID> field, be
99             #pod sure to use C<in_brackets> to get the string inside angle brackets:
100             #pod
101             #pod header => [
102             #pod ...
103             #pod 'Message-Id' => Email::MessageID->new->in_brackets,
104             #pod ],
105             #pod
106             #pod Don't make this common mistake:
107             #pod
108             #pod header => [
109             #pod ...
110             #pod 'Message-Id' => Email::MessageID->new->as_string, # WRONG!
111             #pod ],
112             #pod
113             #pod =for Pod::Coverage address as_string host user
114             #pod
115             #pod =cut
116              
117 2     2 0 1384 sub user { (split /@/, ${ $_[0] }, 2)[0] }
  2         50  
118 2     2 0 523 sub host { (split /@/, ${ $_[0] }, 2)[1] }
  2         17  
119              
120             sub in_brackets {
121 0     0 1 0 my ($self) = @_;
122 0         0 return "<$$self>";
123             }
124              
125             sub address {
126 1000     1000 0 798 my ($self) = @_;
127 1000         2742 return "$$self";
128             }
129              
130             sub as_string {
131 0     0 0   my ($self) = @_;
132 0           return "$$self";
133             }
134              
135             1;
136              
137             __END__
138              
139             =pod
140              
141             =encoding UTF-8
142              
143             =head1 NAME
144              
145             Email::MessageID - Generate world unique message-ids.
146              
147             =head1 VERSION
148              
149             version 1.406
150              
151             =head1 SYNOPSIS
152              
153             use Email::MessageID;
154              
155             my $mid = Email::MessageID->new->in_brackets;
156              
157             print "Message-ID: $mid\x0D\x0A";
158              
159             =head1 DESCRIPTION
160              
161             Message-ids are optional, but highly recommended, headers that identify a
162             message uniquely. This software generates a unique message-id.
163              
164             =head1 METHODS
165              
166             =head2 new
167              
168             my $mid = Email::MessageID->new;
169              
170             my $new_mid = Email::MessageID->new( host => $myhost );
171              
172             This class method constructs an L<Email::Address|Email::Address> object
173             containing a unique message-id. You may specify custom C<host> and C<user>
174             parameters.
175              
176             By default, the C<host> is generated from C<Sys::Hostname::hostname>.
177              
178             By default, the C<user> is generated using C<Time::HiRes>'s C<gettimeofday>
179             and the process ID.
180              
181             Using these values we have the ability to ensure world uniqueness down to
182             a specific process running on a specific host, and the exact time down to
183             six digits of microsecond precision.
184              
185             =head2 create_host
186              
187             my $domain_part = Email::MessageID->create_host;
188              
189             This method returns the domain part of the message-id.
190              
191             =head2 create_user
192              
193             my $local_part = Email::MessageID->create_user;
194              
195             This method returns a unique local part for the message-id. It includes some
196             random data and some predictable data.
197              
198             =head2 in_brackets
199              
200             When using Email::MessageID directly to populate the C<Message-ID> field, be
201             sure to use C<in_brackets> to get the string inside angle brackets:
202              
203             header => [
204             ...
205             'Message-Id' => Email::MessageID->new->in_brackets,
206             ],
207              
208             Don't make this common mistake:
209              
210             header => [
211             ...
212             'Message-Id' => Email::MessageID->new->as_string, # WRONG!
213             ],
214              
215             =for Pod::Coverage address as_string host user
216              
217             =head1 AUTHORS
218              
219             =over 4
220              
221             =item *
222              
223             Casey West <casey@geeknest.com>
224              
225             =item *
226              
227             Ricardo SIGNES <rjbs@cpan.org>
228              
229             =back
230              
231             =head1 CONTRIBUTOR
232              
233             =for stopwords Aaron Crane
234              
235             Aaron Crane <arc@cpan.org>
236              
237             =head1 COPYRIGHT AND LICENSE
238              
239             This software is copyright (c) 2004 by Casey West.
240              
241             This is free software; you can redistribute it and/or modify it under
242             the same terms as the Perl 5 programming language system itself.
243              
244             =cut