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   113826 use strict;
  2         23  
  2         50  
2 2     2   10 use warnings;
  2         2  
  2         110  
3             package Email::MessageID 1.408;
4             # ABSTRACT: Generate world unique message-ids.
5              
6 2     2   1946 use overload '""' => 'as_string', fallback => 1;
  2         1669  
  2         9  
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 Email::MessageID object
28             #pod containing a unique message-id. You may specify custom C and C
29             #pod parameters.
30             #pod
31             #pod By default, the C is generated from C.
32             #pod
33             #pod By default, the C is generated using C's C
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 2443 my ($class, %args) = @_;
44              
45 1003   66     2219 $args{user} ||= $class->create_user;
46 1003   66     2496 $args{host} ||= $class->create_host;
47              
48 1003         3801 my $str = "$args{user}\@$args{host}";
49              
50 1003         1979 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 1377 unless (defined $_SYS_HOSTNAME_LONG) {
64 2   50     4 $_SYS_HOSTNAME_LONG = (eval { require Sys::Hostname::Long; 1 }) || 0;
65 2 50       696 require Sys::Hostname unless $_SYS_HOSTNAME_LONG;
66             }
67              
68 1001 50       3325 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 1790 map {; $CHARS[rand @CHARS] } (0 .. (3 + int rand 6));
  6435         10640  
88              
89 1001         1645 my $t = time;
90 1001 100       1580 my $u = exists $uniq{$t} ? ++$uniq{$t} : (%uniq = ($t => 0))[1];
91              
92 1001         1927 my $user = join '.', $t . $u, $noise, $$;
93 1001         2195 return $user;
94             }
95              
96             #pod =method in_brackets
97             #pod
98             #pod When using Email::MessageID directly to populate the C field, be
99             #pod sure to use C 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 777 sub user { (split /@/, ${ $_[0] }, 2)[0] }
  2         33  
118 2     2 0 314 sub host { (split /@/, ${ $_[0] }, 2)[1] }
  2         12  
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 1283 my ($self) = @_;
127 1000         2956 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__