| Filename | /Users/timbo/perl5/perlbrew/perls/perl-5.18.2/lib/site_perl/5.18.2/Email/Address.pm |
| Statements | Executed 64 statements in 4.38ms |
| Calls | P | F | Exclusive Time |
Inclusive Time |
Subroutine |
|---|---|---|---|---|---|
| 23 | 21 | 1 | 2.14ms | 2.14ms | Email::Address::CORE:regcomp (opcode) |
| 1 | 1 | 1 | 164µs | 164µs | Email::Address::BEGIN@230 |
| 27 | 25 | 1 | 30µs | 30µs | Email::Address::CORE:qr (opcode) |
| 1 | 1 | 1 | 20µs | 20µs | Email::Address::BEGIN@361 |
| 1 | 1 | 1 | 11µs | 22µs | Perl::Critic::Policy::ValuesAndExpressions::RequireInterpolationOfMetachars::BEGIN@1 |
| 1 | 1 | 1 | 9µs | 39µs | Email::Address::BEGIN@521 |
| 1 | 1 | 1 | 9µs | 21µs | Email::Address::BEGIN@403 |
| 1 | 1 | 1 | 8µs | 17µs | Email::Address::BEGIN@465 |
| 1 | 1 | 1 | 8µs | 19µs | Email::Address::BEGIN@370 |
| 1 | 1 | 1 | 7µs | 10µs | Perl::Critic::Policy::ValuesAndExpressions::RequireInterpolationOfMetachars::BEGIN@2 |
| 0 | 0 | 0 | 0s | 0s | Email::Address::__ANON__[:384] |
| 0 | 0 | 0 | 0s | 0s | Email::Address::__cache_parse |
| 0 | 0 | 0 | 0s | 0s | Email::Address::__dump |
| 0 | 0 | 0 | 0s | 0s | Email::Address::__get_cached_parse |
| 0 | 0 | 0 | 0s | 0s | Email::Address::_enquoted_phrase |
| 0 | 0 | 0 | 0s | 0s | Email::Address::_format |
| 0 | 0 | 0 | 0s | 0s | Email::Address::as_string |
| 0 | 0 | 0 | 0s | 0s | Email::Address::disable_cache |
| 0 | 0 | 0 | 0s | 0s | Email::Address::enable_cache |
| 0 | 0 | 0 | 0s | 0s | Email::Address::format |
| 0 | 0 | 0 | 0s | 0s | Email::Address::host |
| 0 | 0 | 0 | 0s | 0s | Email::Address::name |
| 0 | 0 | 0 | 0s | 0s | Email::Address::new |
| 0 | 0 | 0 | 0s | 0s | Email::Address::parse |
| 0 | 0 | 0 | 0s | 0s | Email::Address::purge_cache |
| 0 | 0 | 0 | 0s | 0s | Email::Address::user |
| Line | State ments |
Time on line |
Calls | Time in subs |
Code |
|---|---|---|---|---|---|
| 1 | 2 | 19µs | 2 | 34µs | # spent 22µs (11+11) within Perl::Critic::Policy::ValuesAndExpressions::RequireInterpolationOfMetachars::BEGIN@1 which was called:
# once (11µs+11µs) by Perl::Critic::Policy::ValuesAndExpressions::RequireInterpolationOfMetachars::BEGIN@16 at line 1 # spent 22µs making 1 call to Perl::Critic::Policy::ValuesAndExpressions::RequireInterpolationOfMetachars::BEGIN@1
# spent 11µs making 1 call to strict::import |
| 2 | 2 | 657µs | 2 | 14µs | # spent 10µs (7+3) within Perl::Critic::Policy::ValuesAndExpressions::RequireInterpolationOfMetachars::BEGIN@2 which was called:
# once (7µs+3µs) by Perl::Critic::Policy::ValuesAndExpressions::RequireInterpolationOfMetachars::BEGIN@16 at line 2 # spent 10µs making 1 call to Perl::Critic::Policy::ValuesAndExpressions::RequireInterpolationOfMetachars::BEGIN@2
# spent 3µs making 1 call to warnings::import |
| 3 | package Email::Address; | ||||
| 4 | # ABSTRACT: RFC 2822 Address Parsing and Creation | ||||
| 5 | 1 | 700ns | $Email::Address::VERSION = '1.905'; | ||
| 6 | 1 | 200ns | our $COMMENT_NEST_LEVEL ||= 2; | ||
| 7 | 1 | 200ns | our $STRINGIFY ||= 'format'; | ||
| 8 | 1 | 200ns | our $COLLAPSE_SPACES = 1 unless defined $COLLAPSE_SPACES; # I miss //= | ||
| 9 | |||||
| 10 | #pod =head1 SYNOPSIS | ||||
| 11 | #pod | ||||
| 12 | #pod use Email::Address; | ||||
| 13 | #pod | ||||
| 14 | #pod my @addresses = Email::Address->parse($line); | ||||
| 15 | #pod my $address = Email::Address->new(Casey => 'casey@localhost'); | ||||
| 16 | #pod | ||||
| 17 | #pod print $address->format; | ||||
| 18 | #pod | ||||
| 19 | #pod =head1 VERSION | ||||
| 20 | #pod | ||||
| 21 | #pod version 1.898 | ||||
| 22 | #pod | ||||
| 23 | #pod =head1 DESCRIPTION | ||||
| 24 | #pod | ||||
| 25 | #pod This class implements a regex-based RFC 2822 parser that locates email | ||||
| 26 | #pod addresses in strings and returns a list of C<Email::Address> objects found. | ||||
| 27 | #pod Alternatively you may construct objects manually. The goal of this software is | ||||
| 28 | #pod to be correct, and very very fast. | ||||
| 29 | #pod | ||||
| 30 | #pod =cut | ||||
| 31 | |||||
| 32 | 1 | 300ns | my $CTL = q{\x00-\x1F\x7F}; | ||
| 33 | 1 | 300ns | my $special = q{()<>\\[\\]:;@\\\\,."}; | ||
| 34 | |||||
| 35 | 1 | 9µs | 1 | 2µs | my $text = qr/[^\x0A\x0D]/; # spent 2µs making 1 call to Email::Address::CORE:qr |
| 36 | |||||
| 37 | 1 | 17µs | 2 | 10µs | my $quoted_pair = qr/\\$text/; # spent 9µs making 1 call to Email::Address::CORE:regcomp
# spent 1µs making 1 call to Email::Address::CORE:qr |
| 38 | |||||
| 39 | 1 | 4µs | 1 | 1µs | my $ctext = qr/(?>[^()\\]+)/; # spent 1µs making 1 call to Email::Address::CORE:qr |
| 40 | 1 | 1µs | my ($ccontent, $comment) = (q{})x2; | ||
| 41 | 1 | 1µs | for (1 .. $COMMENT_NEST_LEVEL) { | ||
| 42 | 2 | 52µs | 4 | 40µs | $ccontent = qr/$ctext|$quoted_pair|$comment/; # spent 38µs making 2 calls to Email::Address::CORE:regcomp, avg 19µs/call
# spent 2µs making 2 calls to Email::Address::CORE:qr, avg 1µs/call |
| 43 | 2 | 57µs | 4 | 43µs | $comment = qr/\s*\((?:\s*$ccontent)*\s*\)\s*/; # spent 41µs making 2 calls to Email::Address::CORE:regcomp, avg 21µs/call
# spent 2µs making 2 calls to Email::Address::CORE:qr, avg 1µs/call |
| 44 | } | ||||
| 45 | 1 | 27µs | 2 | 22µs | my $cfws = qr/$comment|\s+/; # spent 21µs making 1 call to Email::Address::CORE:regcomp
# spent 900ns making 1 call to Email::Address::CORE:qr |
| 46 | |||||
| 47 | 1 | 1µs | my $atext = qq/[^$CTL$special\\s]/; | ||
| 48 | 1 | 60µs | 2 | 54µs | my $atom = qr/$cfws*$atext+$cfws*/; # spent 53µs making 1 call to Email::Address::CORE:regcomp
# spent 1µs making 1 call to Email::Address::CORE:qr |
| 49 | 1 | 30µs | 2 | 25µs | my $dot_atom_text = qr/$atext+(?:\.$atext+)*/; # spent 24µs making 1 call to Email::Address::CORE:regcomp
# spent 1µs making 1 call to Email::Address::CORE:qr |
| 50 | 1 | 68µs | 2 | 61µs | my $dot_atom = qr/$cfws*$dot_atom_text$cfws*/; # spent 60µs making 1 call to Email::Address::CORE:regcomp
# spent 1µs making 1 call to Email::Address::CORE:qr |
| 51 | |||||
| 52 | 1 | 3µs | 1 | 800ns | my $qtext = qr/[^\\"]/; # spent 800ns making 1 call to Email::Address::CORE:qr |
| 53 | 1 | 14µs | 2 | 9µs | my $qcontent = qr/$qtext|$quoted_pair/; # spent 8µs making 1 call to Email::Address::CORE:regcomp
# spent 900ns making 1 call to Email::Address::CORE:qr |
| 54 | 1 | 53µs | 2 | 47µs | my $quoted_string = qr/$cfws*"$qcontent*"$cfws*/; # spent 46µs making 1 call to Email::Address::CORE:regcomp
# spent 1µs making 1 call to Email::Address::CORE:qr |
| 55 | |||||
| 56 | 1 | 95µs | 2 | 88µs | my $word = qr/$atom|$quoted_string/; # spent 87µs making 1 call to Email::Address::CORE:regcomp
# spent 1µs making 1 call to Email::Address::CORE:qr |
| 57 | |||||
| 58 | # XXX: This ($phrase) used to just be: my $phrase = qr/$word+/; It was changed | ||||
| 59 | # to resolve bug 22991, creating a significant slowdown. Given current speed | ||||
| 60 | # problems. Once 16320 is resolved, this section should be dealt with. | ||||
| 61 | # -- rjbs, 2006-11-11 | ||||
| 62 | #my $obs_phrase = qr/$word(?:$word|\.|$cfws)*/; | ||||
| 63 | |||||
| 64 | # XXX: ...and the above solution caused endless problems (never returned) when | ||||
| 65 | # examining this address, now in a test: | ||||
| 66 | # admin+=E6=96=B0=E5=8A=A0=E5=9D=A1_Weblog-- ATAT --test.socialtext.com | ||||
| 67 | # So we disallow the hateful CFWS in this context for now. Of modern mail | ||||
| 68 | # agents, only Apple Web Mail 2.0 is known to produce obs-phrase. | ||||
| 69 | # -- rjbs, 2006-11-19 | ||||
| 70 | 1 | 62µs | 2 | 56µs | my $simple_word = qr/$atom|\.|\s*"$qcontent+"\s*/; # spent 55µs making 1 call to Email::Address::CORE:regcomp
# spent 1µs making 1 call to Email::Address::CORE:qr |
| 71 | 1 | 63µs | 2 | 55µs | my $obs_phrase = qr/$simple_word+/; # spent 54µs making 1 call to Email::Address::CORE:regcomp
# spent 1µs making 1 call to Email::Address::CORE:qr |
| 72 | |||||
| 73 | 1 | 144µs | 2 | 135µs | my $phrase = qr/$obs_phrase|(?:$word+)/; # spent 134µs making 1 call to Email::Address::CORE:regcomp
# spent 1µs making 1 call to Email::Address::CORE:qr |
| 74 | |||||
| 75 | 1 | 102µs | 2 | 95µs | my $local_part = qr/$dot_atom|$quoted_string/; # spent 94µs making 1 call to Email::Address::CORE:regcomp
# spent 1µs making 1 call to Email::Address::CORE:qr |
| 76 | 1 | 4µs | 1 | 1µs | my $dtext = qr/[^\[\]\\]/; # spent 1µs making 1 call to Email::Address::CORE:qr |
| 77 | 1 | 16µs | 2 | 10µs | my $dcontent = qr/$dtext|$quoted_pair/; # spent 8µs making 1 call to Email::Address::CORE:regcomp
# spent 1µs making 1 call to Email::Address::CORE:qr |
| 78 | 1 | 52µs | 2 | 46µs | my $domain_literal = qr/$cfws*\[(?:\s*$dcontent)*\s*\]$cfws*/; # spent 45µs making 1 call to Email::Address::CORE:regcomp
# spent 1µs making 1 call to Email::Address::CORE:qr |
| 79 | 1 | 104µs | 2 | 96µs | my $domain = qr/$dot_atom|$domain_literal/; # spent 96µs making 1 call to Email::Address::CORE:regcomp
# spent 1µs making 1 call to Email::Address::CORE:qr |
| 80 | |||||
| 81 | 1 | 200ns | my $display_name = $phrase; | ||
| 82 | |||||
| 83 | #pod =head2 Package Variables | ||||
| 84 | #pod | ||||
| 85 | #pod B<ACHTUNG!> Email isn't easy (if even possible) to parse with a regex, I<at | ||||
| 86 | #pod least> if you're on a C<perl> prior to 5.10.0. Providing regular expressions | ||||
| 87 | #pod for use by other programs isn't a great idea, because it makes it hard to | ||||
| 88 | #pod improve the parser without breaking the "it's a regex" feature. Using these | ||||
| 89 | #pod regular expressions is not encouraged, and methods like C<< | ||||
| 90 | #pod Email::Address->is_addr_spec >> should be provided in the future. | ||||
| 91 | #pod | ||||
| 92 | #pod Several regular expressions used in this package are useful to others. | ||||
| 93 | #pod For convenience, these variables are declared as package variables that | ||||
| 94 | #pod you may access from your program. | ||||
| 95 | #pod | ||||
| 96 | #pod These regular expressions conform to the rules specified in RFC 2822. | ||||
| 97 | #pod | ||||
| 98 | #pod You can access these variables using the full namespace. If you want | ||||
| 99 | #pod short names, define them yourself. | ||||
| 100 | #pod | ||||
| 101 | #pod my $addr_spec = $Email::Address::addr_spec; | ||||
| 102 | #pod | ||||
| 103 | #pod =over 4 | ||||
| 104 | #pod | ||||
| 105 | #pod =item $Email::Address::addr_spec | ||||
| 106 | #pod | ||||
| 107 | #pod This regular expression defined what an email address is allowed to | ||||
| 108 | #pod look like. | ||||
| 109 | #pod | ||||
| 110 | #pod =item $Email::Address::angle_addr | ||||
| 111 | #pod | ||||
| 112 | #pod This regular expression defines an C<$addr_spec> wrapped in angle | ||||
| 113 | #pod brackets. | ||||
| 114 | #pod | ||||
| 115 | #pod =item $Email::Address::name_addr | ||||
| 116 | #pod | ||||
| 117 | #pod This regular expression defines what an email address can look like | ||||
| 118 | #pod with an optional preceding display name, also known as the C<phrase>. | ||||
| 119 | #pod | ||||
| 120 | #pod =item $Email::Address::mailbox | ||||
| 121 | #pod | ||||
| 122 | #pod This is the complete regular expression defining an RFC 2822 email | ||||
| 123 | #pod address with an optional preceding display name and optional | ||||
| 124 | #pod following comment. | ||||
| 125 | #pod | ||||
| 126 | #pod =back | ||||
| 127 | #pod | ||||
| 128 | #pod =cut | ||||
| 129 | |||||
| 130 | 1 | 194µs | 2 | 184µs | our $addr_spec = qr/$local_part\@$domain/; # spent 183µs making 1 call to Email::Address::CORE:regcomp
# spent 1µs making 1 call to Email::Address::CORE:qr |
| 131 | 1 | 222µs | 2 | 212µs | our $angle_addr = qr/$cfws*<$addr_spec>$cfws*/; # spent 211µs making 1 call to Email::Address::CORE:regcomp
# spent 1µs making 1 call to Email::Address::CORE:qr |
| 132 | 1 | 355µs | 2 | 343µs | our $name_addr = qr/(?>$display_name?)$angle_addr/; # spent 342µs making 1 call to Email::Address::CORE:regcomp
# spent 1µs making 1 call to Email::Address::CORE:qr |
| 133 | 1 | 544µs | 2 | 528µs | our $mailbox = qr/(?:$name_addr|$addr_spec)$comment*/; # spent 527µs making 1 call to Email::Address::CORE:regcomp
# spent 1µs making 1 call to Email::Address::CORE:qr |
| 134 | |||||
| 135 | sub _PHRASE () { 0 } | ||||
| 136 | sub _ADDRESS () { 1 } | ||||
| 137 | sub _COMMENT () { 2 } | ||||
| 138 | sub _ORIGINAL () { 3 } | ||||
| 139 | sub _IN_CACHE () { 4 } | ||||
| 140 | |||||
| 141 | sub __dump { | ||||
| 142 | return { | ||||
| 143 | phrase => $_[0][_PHRASE], | ||||
| 144 | address => $_[0][_ADDRESS], | ||||
| 145 | comment => $_[0][_COMMENT], | ||||
| 146 | original => $_[0][_ORIGINAL], | ||||
| 147 | } | ||||
| 148 | } | ||||
| 149 | |||||
| 150 | #pod =head2 Class Methods | ||||
| 151 | #pod | ||||
| 152 | #pod =over | ||||
| 153 | #pod | ||||
| 154 | #pod =item parse | ||||
| 155 | #pod | ||||
| 156 | #pod my @addrs = Email::Address->parse( | ||||
| 157 | #pod q[me@local, Casey <me@local>, "Casey" <me@local> (West)] | ||||
| 158 | #pod ); | ||||
| 159 | #pod | ||||
| 160 | #pod This method returns a list of C<Email::Address> objects it finds in the input | ||||
| 161 | #pod string. B<Please note> that it returns a list, and expects that it may find | ||||
| 162 | #pod multiple addresses. The behavior in scalar context is undefined. | ||||
| 163 | #pod | ||||
| 164 | #pod The specification for an email address allows for infinitely nestable comments. | ||||
| 165 | #pod That's nice in theory, but a little over done. By default this module allows | ||||
| 166 | #pod for two (C<2>) levels of nested comments. If you think you need more, modify | ||||
| 167 | #pod the C<$Email::Address::COMMENT_NEST_LEVEL> package variable to allow more. | ||||
| 168 | #pod | ||||
| 169 | #pod $Email::Address::COMMENT_NEST_LEVEL = 10; # I'm deep | ||||
| 170 | #pod | ||||
| 171 | #pod The reason for this hardly-limiting limitation is simple: efficiency. | ||||
| 172 | #pod | ||||
| 173 | #pod Long strings of whitespace can be problematic for this module to parse, a bug | ||||
| 174 | #pod which has not yet been adequately addressed. The default behavior is now to | ||||
| 175 | #pod collapse multiple spaces into a single space, which avoids this problem. To | ||||
| 176 | #pod prevent this behavior, set C<$Email::Address::COLLAPSE_SPACES> to zero. This | ||||
| 177 | #pod variable will go away when the bug is resolved properly. | ||||
| 178 | #pod | ||||
| 179 | #pod In accordance with RFC 822 and its descendants, this module demands that email | ||||
| 180 | #pod addresses be ASCII only. Any non-ASCII content in the parsed addresses will | ||||
| 181 | #pod cause the parser to return no results. | ||||
| 182 | #pod | ||||
| 183 | #pod =cut | ||||
| 184 | |||||
| 185 | 1 | 400ns | our (%PARSE_CACHE, %FORMAT_CACHE, %NAME_CACHE); | ||
| 186 | 1 | 100ns | my $NOCACHE; | ||
| 187 | |||||
| 188 | sub __get_cached_parse { | ||||
| 189 | return if $NOCACHE; | ||||
| 190 | |||||
| 191 | my ($class, $line) = @_; | ||||
| 192 | |||||
| 193 | return @{$PARSE_CACHE{$line}} if exists $PARSE_CACHE{$line}; | ||||
| 194 | return; | ||||
| 195 | } | ||||
| 196 | |||||
| 197 | sub __cache_parse { | ||||
| 198 | return if $NOCACHE; | ||||
| 199 | |||||
| 200 | my ($class, $line, $addrs) = @_; | ||||
| 201 | |||||
| 202 | $PARSE_CACHE{$line} = $addrs; | ||||
| 203 | } | ||||
| 204 | |||||
| 205 | sub parse { | ||||
| 206 | my ($class, $line) = @_; | ||||
| 207 | return unless $line; | ||||
| 208 | |||||
| 209 | $line =~ s/[ \t]+/ /g if $COLLAPSE_SPACES; | ||||
| 210 | |||||
| 211 | if (my @cached = $class->__get_cached_parse($line)) { | ||||
| 212 | return @cached; | ||||
| 213 | } | ||||
| 214 | |||||
| 215 | my (@mailboxes) = ($line =~ /$mailbox/go); | ||||
| 216 | my @addrs; | ||||
| 217 | foreach (@mailboxes) { | ||||
| 218 | my $original = $_; | ||||
| 219 | |||||
| 220 | my @comments = /($comment)/go; | ||||
| 221 | s/$comment//go if @comments; | ||||
| 222 | |||||
| 223 | my ($user, $host, $com); | ||||
| 224 | ($user, $host) = ($1, $2) if s/<($local_part)\@($domain)>\s*\z//o; | ||||
| 225 | if (! defined($user) || ! defined($host)) { | ||||
| 226 | s/($local_part)\@($domain)//o; | ||||
| 227 | ($user, $host) = ($1, $2); | ||||
| 228 | } | ||||
| 229 | |||||
| 230 | 2 | 208µs | 2 | 4.55ms | # spent 164µs within Email::Address::BEGIN@230 which was called:
# once (164µs+0s) by Perl::Critic::Policy::ValuesAndExpressions::RequireInterpolationOfMetachars::BEGIN@16 at line 230 # spent 4.38ms making 1 call to utf8::AUTOLOAD
# spent 164µs making 1 call to Email::Address::BEGIN@230 |
| 231 | 1 | 303µs | 1 | 39µs | next if $host =~ /\P{ASCII}/; # spent 39µs making 1 call to utf8::SWASHNEW |
| 232 | |||||
| 233 | my ($phrase) = /($display_name)/o; | ||||
| 234 | |||||
| 235 | for ( $phrase, $host, $user, @comments ) { | ||||
| 236 | next unless defined $_; | ||||
| 237 | s/^\s+//; | ||||
| 238 | s/\s+$//; | ||||
| 239 | $_ = undef unless length $_; | ||||
| 240 | } | ||||
| 241 | |||||
| 242 | my $new_comment = join q{ }, @comments; | ||||
| 243 | push @addrs, | ||||
| 244 | $class->new($phrase, "$user\@$host", $new_comment, $original); | ||||
| 245 | $addrs[-1]->[_IN_CACHE] = [ \$line, $#addrs ] | ||||
| 246 | } | ||||
| 247 | |||||
| 248 | $class->__cache_parse($line, \@addrs); | ||||
| 249 | return @addrs; | ||||
| 250 | } | ||||
| 251 | |||||
| 252 | #pod =item new | ||||
| 253 | #pod | ||||
| 254 | #pod my $address = Email::Address->new(undef, 'casey@local'); | ||||
| 255 | #pod my $address = Email::Address->new('Casey West', 'casey@local'); | ||||
| 256 | #pod my $address = Email::Address->new(undef, 'casey@local', '(Casey)'); | ||||
| 257 | #pod | ||||
| 258 | #pod Constructs and returns a new C<Email::Address> object. Takes four | ||||
| 259 | #pod positional arguments: phrase, email, and comment, and original string. | ||||
| 260 | #pod | ||||
| 261 | #pod The original string should only really be set using C<parse>. | ||||
| 262 | #pod | ||||
| 263 | #pod =cut | ||||
| 264 | |||||
| 265 | sub new { | ||||
| 266 | my ($class, $phrase, $email, $comment, $orig) = @_; | ||||
| 267 | $phrase =~ s/\A"(.+)"\z/$1/ if $phrase; | ||||
| 268 | |||||
| 269 | bless [ $phrase, $email, $comment, $orig ] => $class; | ||||
| 270 | } | ||||
| 271 | |||||
| 272 | #pod =item purge_cache | ||||
| 273 | #pod | ||||
| 274 | #pod Email::Address->purge_cache; | ||||
| 275 | #pod | ||||
| 276 | #pod One way this module stays fast is with internal caches. Caches live | ||||
| 277 | #pod in memory and there is the remote possibility that you will have a | ||||
| 278 | #pod memory problem. On the off chance that you think you're one of those | ||||
| 279 | #pod people, this class method will empty those caches. | ||||
| 280 | #pod | ||||
| 281 | #pod I've loaded over 12000 objects and not encountered a memory problem. | ||||
| 282 | #pod | ||||
| 283 | #pod =cut | ||||
| 284 | |||||
| 285 | sub purge_cache { | ||||
| 286 | %NAME_CACHE = (); | ||||
| 287 | %FORMAT_CACHE = (); | ||||
| 288 | %PARSE_CACHE = (); | ||||
| 289 | } | ||||
| 290 | |||||
| 291 | #pod =item disable_cache | ||||
| 292 | #pod | ||||
| 293 | #pod =item enable_cache | ||||
| 294 | #pod | ||||
| 295 | #pod Email::Address->disable_cache if memory_low(); | ||||
| 296 | #pod | ||||
| 297 | #pod If you'd rather not cache address parses at all, you can disable (and | ||||
| 298 | #pod re-enable) the Email::Address cache with these methods. The cache is enabled | ||||
| 299 | #pod by default. | ||||
| 300 | #pod | ||||
| 301 | #pod =cut | ||||
| 302 | |||||
| 303 | sub disable_cache { | ||||
| 304 | my ($class) = @_; | ||||
| 305 | $class->purge_cache; | ||||
| 306 | $NOCACHE = 1; | ||||
| 307 | } | ||||
| 308 | |||||
| 309 | sub enable_cache { | ||||
| 310 | $NOCACHE = undef; | ||||
| 311 | } | ||||
| 312 | |||||
| 313 | #pod =back | ||||
| 314 | #pod | ||||
| 315 | #pod =head2 Instance Methods | ||||
| 316 | #pod | ||||
| 317 | #pod =over 4 | ||||
| 318 | #pod | ||||
| 319 | #pod =item phrase | ||||
| 320 | #pod | ||||
| 321 | #pod my $phrase = $address->phrase; | ||||
| 322 | #pod $address->phrase( "Me oh my" ); | ||||
| 323 | #pod | ||||
| 324 | #pod Accessor and mutator for the phrase portion of an address. | ||||
| 325 | #pod | ||||
| 326 | #pod =item address | ||||
| 327 | #pod | ||||
| 328 | #pod my $addr = $address->address; | ||||
| 329 | #pod $addr->address( "me@PROTECTED.com" ); | ||||
| 330 | #pod | ||||
| 331 | #pod Accessor and mutator for the address portion of an address. | ||||
| 332 | #pod | ||||
| 333 | #pod =item comment | ||||
| 334 | #pod | ||||
| 335 | #pod my $comment = $address->comment; | ||||
| 336 | #pod $address->comment( "(Work address)" ); | ||||
| 337 | #pod | ||||
| 338 | #pod Accessor and mutator for the comment portion of an address. | ||||
| 339 | #pod | ||||
| 340 | #pod =item original | ||||
| 341 | #pod | ||||
| 342 | #pod my $orig = $address->original; | ||||
| 343 | #pod | ||||
| 344 | #pod Accessor for the original address found when parsing, or passed | ||||
| 345 | #pod to C<new>. | ||||
| 346 | #pod | ||||
| 347 | #pod =item host | ||||
| 348 | #pod | ||||
| 349 | #pod my $host = $address->host; | ||||
| 350 | #pod | ||||
| 351 | #pod Accessor for the host portion of an address's address. | ||||
| 352 | #pod | ||||
| 353 | #pod =item user | ||||
| 354 | #pod | ||||
| 355 | #pod my $user = $address->user; | ||||
| 356 | #pod | ||||
| 357 | #pod Accessor for the user portion of an address's address. | ||||
| 358 | #pod | ||||
| 359 | #pod =cut | ||||
| 360 | |||||
| 361 | # spent 20µs within Email::Address::BEGIN@361 which was called:
# once (20µs+0s) by Perl::Critic::Policy::ValuesAndExpressions::RequireInterpolationOfMetachars::BEGIN@16 at line 386 | ||||
| 362 | 1 | 2µs | my %_INDEX = ( | ||
| 363 | phrase => _PHRASE, | ||||
| 364 | address => _ADDRESS, | ||||
| 365 | comment => _COMMENT, | ||||
| 366 | original => _ORIGINAL, | ||||
| 367 | ); | ||||
| 368 | |||||
| 369 | 1 | 6µs | for my $method (keys %_INDEX) { | ||
| 370 | 2 | 101µs | 2 | 31µs | # spent 19µs (8+11) within Email::Address::BEGIN@370 which was called:
# once (8µs+11µs) by Perl::Critic::Policy::ValuesAndExpressions::RequireInterpolationOfMetachars::BEGIN@16 at line 370 # spent 19µs making 1 call to Email::Address::BEGIN@370
# spent 11µs making 1 call to strict::unimport |
| 371 | 4 | 700ns | my $index = $_INDEX{ $method }; | ||
| 372 | *$method = sub { | ||||
| 373 | if ($_[1]) { | ||||
| 374 | if ($_[0][_IN_CACHE]) { | ||||
| 375 | my $replicant = bless [ @{$_[0]} ] => ref $_[0]; | ||||
| 376 | $PARSE_CACHE{ ${ $_[0][_IN_CACHE][0] } }[ $_[0][_IN_CACHE][1] ] | ||||
| 377 | = $replicant; | ||||
| 378 | $_[0][_IN_CACHE] = undef; | ||||
| 379 | } | ||||
| 380 | $_[0]->[ $index ] = $_[1]; | ||||
| 381 | } else { | ||||
| 382 | $_[0]->[ $index ]; | ||||
| 383 | } | ||||
| 384 | 4 | 11µs | }; | ||
| 385 | } | ||||
| 386 | 1 | 73µs | 1 | 20µs | } # spent 20µs making 1 call to Email::Address::BEGIN@361 |
| 387 | |||||
| 388 | sub host { ($_[0]->[_ADDRESS] =~ /\@($domain)/o)[0] } | ||||
| 389 | sub user { ($_[0]->[_ADDRESS] =~ /($local_part)\@/o)[0] } | ||||
| 390 | |||||
| 391 | #pod =pod | ||||
| 392 | #pod | ||||
| 393 | #pod =item format | ||||
| 394 | #pod | ||||
| 395 | #pod my $printable = $address->format; | ||||
| 396 | #pod | ||||
| 397 | #pod Returns a properly formatted RFC 2822 address representing the | ||||
| 398 | #pod object. | ||||
| 399 | #pod | ||||
| 400 | #pod =cut | ||||
| 401 | |||||
| 402 | sub format { | ||||
| 403 | 2 | 257µs | 2 | 33µs | # spent 21µs (9+12) within Email::Address::BEGIN@403 which was called:
# once (9µs+12µs) by Perl::Critic::Policy::ValuesAndExpressions::RequireInterpolationOfMetachars::BEGIN@16 at line 403 # spent 21µs making 1 call to Email::Address::BEGIN@403
# spent 12µs making 1 call to warnings::unimport |
| 404 | return $FORMAT_CACHE{$cache_str} if exists $FORMAT_CACHE{$cache_str}; | ||||
| 405 | $FORMAT_CACHE{$cache_str} = $_[0]->_format; | ||||
| 406 | } | ||||
| 407 | |||||
| 408 | sub _format { | ||||
| 409 | my ($self) = @_; | ||||
| 410 | |||||
| 411 | unless ( | ||||
| 412 | defined $self->[_PHRASE] && length $self->[_PHRASE] | ||||
| 413 | || | ||||
| 414 | defined $self->[_COMMENT] && length $self->[_COMMENT] | ||||
| 415 | ) { | ||||
| 416 | return defined $self->[_ADDRESS] ? $self->[_ADDRESS] : ''; | ||||
| 417 | } | ||||
| 418 | |||||
| 419 | my $comment = defined $self->[_COMMENT] ? $self->[_COMMENT] : ''; | ||||
| 420 | $comment = "($comment)" if length $comment and $comment !~ /\A\(.*\)\z/; | ||||
| 421 | |||||
| 422 | my $format = sprintf q{%s <%s> %s}, | ||||
| 423 | $self->_enquoted_phrase, | ||||
| 424 | (defined $self->[_ADDRESS] ? $self->[_ADDRESS] : ''), | ||||
| 425 | $comment; | ||||
| 426 | |||||
| 427 | $format =~ s/^\s+//; | ||||
| 428 | $format =~ s/\s+$//; | ||||
| 429 | |||||
| 430 | return $format; | ||||
| 431 | } | ||||
| 432 | |||||
| 433 | sub _enquoted_phrase { | ||||
| 434 | my ($self) = @_; | ||||
| 435 | |||||
| 436 | my $phrase = $self->[_PHRASE]; | ||||
| 437 | |||||
| 438 | return '' unless defined $phrase and length $phrase; | ||||
| 439 | |||||
| 440 | # if it's encoded -- rjbs, 2007-02-28 | ||||
| 441 | return $phrase if $phrase =~ /\A=\?.+\?=\z/; | ||||
| 442 | |||||
| 443 | $phrase =~ s/\A"(.+)"\z/$1/; | ||||
| 444 | $phrase =~ s/([\\"])/\\$1/g; | ||||
| 445 | |||||
| 446 | return qq{"$phrase"}; | ||||
| 447 | } | ||||
| 448 | |||||
| 449 | #pod =item name | ||||
| 450 | #pod | ||||
| 451 | #pod my $name = $address->name; | ||||
| 452 | #pod | ||||
| 453 | #pod This method tries very hard to determine the name belonging to the address. | ||||
| 454 | #pod First the C<phrase> is checked. If that doesn't work out the C<comment> | ||||
| 455 | #pod is looked into. If that still doesn't work out, the C<user> portion of | ||||
| 456 | #pod the C<address> is returned. | ||||
| 457 | #pod | ||||
| 458 | #pod This method does B<not> try to massage any name it identifies and instead | ||||
| 459 | #pod leaves that up to someone else. Who is it to decide if someone wants their | ||||
| 460 | #pod name capitalized, or if they're Irish? | ||||
| 461 | #pod | ||||
| 462 | #pod =cut | ||||
| 463 | |||||
| 464 | sub name { | ||||
| 465 | 2 | 204µs | 2 | 25µs | # spent 17µs (8+8) within Email::Address::BEGIN@465 which was called:
# once (8µs+8µs) by Perl::Critic::Policy::ValuesAndExpressions::RequireInterpolationOfMetachars::BEGIN@16 at line 465 # spent 17µs making 1 call to Email::Address::BEGIN@465
# spent 8µs making 1 call to warnings::unimport |
| 466 | return $NAME_CACHE{$cache_str} if exists $NAME_CACHE{$cache_str}; | ||||
| 467 | |||||
| 468 | my ($self) = @_; | ||||
| 469 | my $name = q{}; | ||||
| 470 | if ( $name = $self->[_PHRASE] ) { | ||||
| 471 | $name =~ s/^"//; | ||||
| 472 | $name =~ s/"$//; | ||||
| 473 | $name =~ s/($quoted_pair)/substr $1, -1/goe; | ||||
| 474 | } elsif ( $name = $self->[_COMMENT] ) { | ||||
| 475 | $name =~ s/^\(//; | ||||
| 476 | $name =~ s/\)$//; | ||||
| 477 | $name =~ s/($quoted_pair)/substr $1, -1/goe; | ||||
| 478 | $name =~ s/$comment/ /go; | ||||
| 479 | } else { | ||||
| 480 | ($name) = $self->[_ADDRESS] =~ /($local_part)\@/o; | ||||
| 481 | } | ||||
| 482 | $NAME_CACHE{$cache_str} = $name; | ||||
| 483 | } | ||||
| 484 | |||||
| 485 | #pod =back | ||||
| 486 | #pod | ||||
| 487 | #pod =head2 Overloaded Operators | ||||
| 488 | #pod | ||||
| 489 | #pod =over 4 | ||||
| 490 | #pod | ||||
| 491 | #pod =item stringify | ||||
| 492 | #pod | ||||
| 493 | #pod print "I have your email address, $address."; | ||||
| 494 | #pod | ||||
| 495 | #pod Objects stringify to C<format> by default. It's possible that you don't | ||||
| 496 | #pod like that idea. Okay, then, you can change it by modifying | ||||
| 497 | #pod C<$Email:Address::STRINGIFY>. Please consider modifying this package | ||||
| 498 | #pod variable using C<local>. You might step on someone else's toes if you | ||||
| 499 | #pod don't. | ||||
| 500 | #pod | ||||
| 501 | #pod { | ||||
| 502 | #pod local $Email::Address::STRINGIFY = 'host'; | ||||
| 503 | #pod print "I have your address, $address."; | ||||
| 504 | #pod # geeknest.com | ||||
| 505 | #pod } | ||||
| 506 | #pod print "I have your address, $address."; | ||||
| 507 | #pod # "Casey West" <casey@geeknest.com> | ||||
| 508 | #pod | ||||
| 509 | #pod Modifying this package variable is now deprecated. Subclassing is now the | ||||
| 510 | #pod recommended approach. | ||||
| 511 | #pod | ||||
| 512 | #pod =cut | ||||
| 513 | |||||
| 514 | sub as_string { | ||||
| 515 | warn 'altering $Email::Address::STRINGIFY is deprecated; subclass instead' | ||||
| 516 | if $STRINGIFY ne 'format'; | ||||
| 517 | |||||
| 518 | $_[0]->can($STRINGIFY)->($_[0]); | ||||
| 519 | } | ||||
| 520 | |||||
| 521 | 2 | 112µs | 2 | 69µs | # spent 39µs (9+30) within Email::Address::BEGIN@521 which was called:
# once (9µs+30µs) by Perl::Critic::Policy::ValuesAndExpressions::RequireInterpolationOfMetachars::BEGIN@16 at line 521 # spent 39µs making 1 call to Email::Address::BEGIN@521
# spent 30µs making 1 call to overload::import |
| 522 | |||||
| 523 | #pod =pod | ||||
| 524 | #pod | ||||
| 525 | #pod =back | ||||
| 526 | #pod | ||||
| 527 | #pod =cut | ||||
| 528 | |||||
| 529 | 1 | 64µs | 1; | ||
| 530 | |||||
| 531 | =pod | ||||
| 532 | |||||
| 533 | =encoding UTF-8 | ||||
| 534 | |||||
| 535 | =head1 NAME | ||||
| 536 | |||||
| 537 | Email::Address - RFC 2822 Address Parsing and Creation | ||||
| 538 | |||||
| 539 | =head1 VERSION | ||||
| 540 | |||||
| 541 | version 1.905 | ||||
| 542 | |||||
| 543 | =head1 SYNOPSIS | ||||
| 544 | |||||
| 545 | use Email::Address; | ||||
| 546 | |||||
| 547 | my @addresses = Email::Address->parse($line); | ||||
| 548 | my $address = Email::Address->new(Casey => 'casey@localhost'); | ||||
| 549 | |||||
| 550 | print $address->format; | ||||
| 551 | |||||
| 552 | =head1 DESCRIPTION | ||||
| 553 | |||||
| 554 | This class implements a regex-based RFC 2822 parser that locates email | ||||
| 555 | addresses in strings and returns a list of C<Email::Address> objects found. | ||||
| 556 | Alternatively you may construct objects manually. The goal of this software is | ||||
| 557 | to be correct, and very very fast. | ||||
| 558 | |||||
| 559 | =head2 Package Variables | ||||
| 560 | |||||
| 561 | B<ACHTUNG!> Email isn't easy (if even possible) to parse with a regex, I<at | ||||
| 562 | least> if you're on a C<perl> prior to 5.10.0. Providing regular expressions | ||||
| 563 | for use by other programs isn't a great idea, because it makes it hard to | ||||
| 564 | improve the parser without breaking the "it's a regex" feature. Using these | ||||
| 565 | regular expressions is not encouraged, and methods like C<< | ||||
| 566 | Email::Address->is_addr_spec >> should be provided in the future. | ||||
| 567 | |||||
| 568 | Several regular expressions used in this package are useful to others. | ||||
| 569 | For convenience, these variables are declared as package variables that | ||||
| 570 | you may access from your program. | ||||
| 571 | |||||
| 572 | These regular expressions conform to the rules specified in RFC 2822. | ||||
| 573 | |||||
| 574 | You can access these variables using the full namespace. If you want | ||||
| 575 | short names, define them yourself. | ||||
| 576 | |||||
| 577 | my $addr_spec = $Email::Address::addr_spec; | ||||
| 578 | |||||
| 579 | =over 4 | ||||
| 580 | |||||
| 581 | =item $Email::Address::addr_spec | ||||
| 582 | |||||
| 583 | This regular expression defined what an email address is allowed to | ||||
| 584 | look like. | ||||
| 585 | |||||
| 586 | =item $Email::Address::angle_addr | ||||
| 587 | |||||
| 588 | This regular expression defines an C<$addr_spec> wrapped in angle | ||||
| 589 | brackets. | ||||
| 590 | |||||
| 591 | =item $Email::Address::name_addr | ||||
| 592 | |||||
| 593 | This regular expression defines what an email address can look like | ||||
| 594 | with an optional preceding display name, also known as the C<phrase>. | ||||
| 595 | |||||
| 596 | =item $Email::Address::mailbox | ||||
| 597 | |||||
| 598 | This is the complete regular expression defining an RFC 2822 email | ||||
| 599 | address with an optional preceding display name and optional | ||||
| 600 | following comment. | ||||
| 601 | |||||
| 602 | =back | ||||
| 603 | |||||
| 604 | =head2 Class Methods | ||||
| 605 | |||||
| 606 | =over | ||||
| 607 | |||||
| 608 | =item parse | ||||
| 609 | |||||
| 610 | my @addrs = Email::Address->parse( | ||||
| 611 | q[me@local, Casey <me@local>, "Casey" <me@local> (West)] | ||||
| 612 | ); | ||||
| 613 | |||||
| 614 | This method returns a list of C<Email::Address> objects it finds in the input | ||||
| 615 | string. B<Please note> that it returns a list, and expects that it may find | ||||
| 616 | multiple addresses. The behavior in scalar context is undefined. | ||||
| 617 | |||||
| 618 | The specification for an email address allows for infinitely nestable comments. | ||||
| 619 | That's nice in theory, but a little over done. By default this module allows | ||||
| 620 | for two (C<2>) levels of nested comments. If you think you need more, modify | ||||
| 621 | the C<$Email::Address::COMMENT_NEST_LEVEL> package variable to allow more. | ||||
| 622 | |||||
| 623 | $Email::Address::COMMENT_NEST_LEVEL = 10; # I'm deep | ||||
| 624 | |||||
| 625 | The reason for this hardly-limiting limitation is simple: efficiency. | ||||
| 626 | |||||
| 627 | Long strings of whitespace can be problematic for this module to parse, a bug | ||||
| 628 | which has not yet been adequately addressed. The default behavior is now to | ||||
| 629 | collapse multiple spaces into a single space, which avoids this problem. To | ||||
| 630 | prevent this behavior, set C<$Email::Address::COLLAPSE_SPACES> to zero. This | ||||
| 631 | variable will go away when the bug is resolved properly. | ||||
| 632 | |||||
| 633 | In accordance with RFC 822 and its descendants, this module demands that email | ||||
| 634 | addresses be ASCII only. Any non-ASCII content in the parsed addresses will | ||||
| 635 | cause the parser to return no results. | ||||
| 636 | |||||
| 637 | =item new | ||||
| 638 | |||||
| 639 | my $address = Email::Address->new(undef, 'casey@local'); | ||||
| 640 | my $address = Email::Address->new('Casey West', 'casey@local'); | ||||
| 641 | my $address = Email::Address->new(undef, 'casey@local', '(Casey)'); | ||||
| 642 | |||||
| 643 | Constructs and returns a new C<Email::Address> object. Takes four | ||||
| 644 | positional arguments: phrase, email, and comment, and original string. | ||||
| 645 | |||||
| 646 | The original string should only really be set using C<parse>. | ||||
| 647 | |||||
| 648 | =item purge_cache | ||||
| 649 | |||||
| 650 | Email::Address->purge_cache; | ||||
| 651 | |||||
| 652 | One way this module stays fast is with internal caches. Caches live | ||||
| 653 | in memory and there is the remote possibility that you will have a | ||||
| 654 | memory problem. On the off chance that you think you're one of those | ||||
| 655 | people, this class method will empty those caches. | ||||
| 656 | |||||
| 657 | I've loaded over 12000 objects and not encountered a memory problem. | ||||
| 658 | |||||
| 659 | =item disable_cache | ||||
| 660 | |||||
| 661 | =item enable_cache | ||||
| 662 | |||||
| 663 | Email::Address->disable_cache if memory_low(); | ||||
| 664 | |||||
| 665 | If you'd rather not cache address parses at all, you can disable (and | ||||
| 666 | re-enable) the Email::Address cache with these methods. The cache is enabled | ||||
| 667 | by default. | ||||
| 668 | |||||
| 669 | =back | ||||
| 670 | |||||
| 671 | =head2 Instance Methods | ||||
| 672 | |||||
| 673 | =over 4 | ||||
| 674 | |||||
| 675 | =item phrase | ||||
| 676 | |||||
| 677 | my $phrase = $address->phrase; | ||||
| 678 | $address->phrase( "Me oh my" ); | ||||
| 679 | |||||
| 680 | Accessor and mutator for the phrase portion of an address. | ||||
| 681 | |||||
| 682 | =item address | ||||
| 683 | |||||
| 684 | my $addr = $address->address; | ||||
| 685 | $addr->address( "me@PROTECTED.com" ); | ||||
| 686 | |||||
| 687 | Accessor and mutator for the address portion of an address. | ||||
| 688 | |||||
| 689 | =item comment | ||||
| 690 | |||||
| 691 | my $comment = $address->comment; | ||||
| 692 | $address->comment( "(Work address)" ); | ||||
| 693 | |||||
| 694 | Accessor and mutator for the comment portion of an address. | ||||
| 695 | |||||
| 696 | =item original | ||||
| 697 | |||||
| 698 | my $orig = $address->original; | ||||
| 699 | |||||
| 700 | Accessor for the original address found when parsing, or passed | ||||
| 701 | to C<new>. | ||||
| 702 | |||||
| 703 | =item host | ||||
| 704 | |||||
| 705 | my $host = $address->host; | ||||
| 706 | |||||
| 707 | Accessor for the host portion of an address's address. | ||||
| 708 | |||||
| 709 | =item user | ||||
| 710 | |||||
| 711 | my $user = $address->user; | ||||
| 712 | |||||
| 713 | Accessor for the user portion of an address's address. | ||||
| 714 | |||||
| 715 | =item format | ||||
| 716 | |||||
| 717 | my $printable = $address->format; | ||||
| 718 | |||||
| 719 | Returns a properly formatted RFC 2822 address representing the | ||||
| 720 | object. | ||||
| 721 | |||||
| 722 | =item name | ||||
| 723 | |||||
| 724 | my $name = $address->name; | ||||
| 725 | |||||
| 726 | This method tries very hard to determine the name belonging to the address. | ||||
| 727 | First the C<phrase> is checked. If that doesn't work out the C<comment> | ||||
| 728 | is looked into. If that still doesn't work out, the C<user> portion of | ||||
| 729 | the C<address> is returned. | ||||
| 730 | |||||
| 731 | This method does B<not> try to massage any name it identifies and instead | ||||
| 732 | leaves that up to someone else. Who is it to decide if someone wants their | ||||
| 733 | name capitalized, or if they're Irish? | ||||
| 734 | |||||
| 735 | =back | ||||
| 736 | |||||
| 737 | =head2 Overloaded Operators | ||||
| 738 | |||||
| 739 | =over 4 | ||||
| 740 | |||||
| 741 | =item stringify | ||||
| 742 | |||||
| 743 | print "I have your email address, $address."; | ||||
| 744 | |||||
| 745 | Objects stringify to C<format> by default. It's possible that you don't | ||||
| 746 | like that idea. Okay, then, you can change it by modifying | ||||
| 747 | C<$Email:Address::STRINGIFY>. Please consider modifying this package | ||||
| 748 | variable using C<local>. You might step on someone else's toes if you | ||||
| 749 | don't. | ||||
| 750 | |||||
| 751 | { | ||||
| 752 | local $Email::Address::STRINGIFY = 'host'; | ||||
| 753 | print "I have your address, $address."; | ||||
| 754 | # geeknest.com | ||||
| 755 | } | ||||
| 756 | print "I have your address, $address."; | ||||
| 757 | # "Casey West" <casey@geeknest.com> | ||||
| 758 | |||||
| 759 | Modifying this package variable is now deprecated. Subclassing is now the | ||||
| 760 | recommended approach. | ||||
| 761 | |||||
| 762 | =back | ||||
| 763 | |||||
| 764 | =head2 Did I Mention Fast? | ||||
| 765 | |||||
| 766 | On his 1.8GHz Apple MacBook, rjbs gets these results: | ||||
| 767 | |||||
| 768 | $ perl -Ilib bench/ea-vs-ma.pl bench/corpus.txt 5 | ||||
| 769 | Rate Mail::Address Email::Address | ||||
| 770 | Mail::Address 2.59/s -- -44% | ||||
| 771 | Email::Address 4.59/s 77% -- | ||||
| 772 | |||||
| 773 | $ perl -Ilib bench/ea-vs-ma.pl bench/corpus.txt 25 | ||||
| 774 | Rate Mail::Address Email::Address | ||||
| 775 | Mail::Address 2.58/s -- -67% | ||||
| 776 | Email::Address 7.84/s 204% -- | ||||
| 777 | |||||
| 778 | $ perl -Ilib bench/ea-vs-ma.pl bench/corpus.txt 50 | ||||
| 779 | Rate Mail::Address Email::Address | ||||
| 780 | Mail::Address 2.57/s -- -70% | ||||
| 781 | Email::Address 8.53/s 232% -- | ||||
| 782 | |||||
| 783 | ...unfortunately, a known bug causes a loss of speed the string to parse has | ||||
| 784 | certain known characteristics, and disabling cache will also degrade | ||||
| 785 | performance. | ||||
| 786 | |||||
| 787 | =head1 VERSION | ||||
| 788 | |||||
| 789 | version 1.898 | ||||
| 790 | |||||
| 791 | =head1 ACKNOWLEDGEMENTS | ||||
| 792 | |||||
| 793 | Thanks to Kevin Riggle and Tatsuhiko Miyagawa for tests for annoying | ||||
| 794 | phrase-quoting bugs! | ||||
| 795 | |||||
| 796 | =head1 AUTHORS | ||||
| 797 | |||||
| 798 | =over 4 | ||||
| 799 | |||||
| 800 | =item * | ||||
| 801 | |||||
| 802 | Casey West | ||||
| 803 | |||||
| 804 | =item * | ||||
| 805 | |||||
| 806 | Ricardo SIGNES <rjbs@cpan.org> | ||||
| 807 | |||||
| 808 | =back | ||||
| 809 | |||||
| 810 | =head1 COPYRIGHT AND LICENSE | ||||
| 811 | |||||
| 812 | This software is copyright (c) 2004 by Casey West. | ||||
| 813 | |||||
| 814 | This is free software; you can redistribute it and/or modify it under | ||||
| 815 | the same terms as the Perl 5 programming language system itself. | ||||
| 816 | |||||
| 817 | =cut | ||||
| 818 | |||||
| 819 | __END__ | ||||
# spent 30µs within Email::Address::CORE:qr which was called 27 times, avg 1µs/call:
# 2 times (2µs+0s) by Perl::Critic::Policy::ValuesAndExpressions::RequireInterpolationOfMetachars::BEGIN@16 at line 42, avg 1µs/call
# 2 times (2µs+0s) by Perl::Critic::Policy::ValuesAndExpressions::RequireInterpolationOfMetachars::BEGIN@16 at line 43, avg 1µs/call
# once (2µs+0s) by Perl::Critic::Policy::ValuesAndExpressions::RequireInterpolationOfMetachars::BEGIN@16 at line 35
# once (1µs+0s) by Perl::Critic::Policy::ValuesAndExpressions::RequireInterpolationOfMetachars::BEGIN@16 at line 39
# once (1µs+0s) by Perl::Critic::Policy::ValuesAndExpressions::RequireInterpolationOfMetachars::BEGIN@16 at line 132
# once (1µs+0s) by Perl::Critic::Policy::ValuesAndExpressions::RequireInterpolationOfMetachars::BEGIN@16 at line 70
# once (1µs+0s) by Perl::Critic::Policy::ValuesAndExpressions::RequireInterpolationOfMetachars::BEGIN@16 at line 54
# once (1µs+0s) by Perl::Critic::Policy::ValuesAndExpressions::RequireInterpolationOfMetachars::BEGIN@16 at line 75
# once (1µs+0s) by Perl::Critic::Policy::ValuesAndExpressions::RequireInterpolationOfMetachars::BEGIN@16 at line 133
# once (1µs+0s) by Perl::Critic::Policy::ValuesAndExpressions::RequireInterpolationOfMetachars::BEGIN@16 at line 48
# once (1µs+0s) by Perl::Critic::Policy::ValuesAndExpressions::RequireInterpolationOfMetachars::BEGIN@16 at line 130
# once (1µs+0s) by Perl::Critic::Policy::ValuesAndExpressions::RequireInterpolationOfMetachars::BEGIN@16 at line 56
# once (1µs+0s) by Perl::Critic::Policy::ValuesAndExpressions::RequireInterpolationOfMetachars::BEGIN@16 at line 131
# once (1µs+0s) by Perl::Critic::Policy::ValuesAndExpressions::RequireInterpolationOfMetachars::BEGIN@16 at line 73
# once (1µs+0s) by Perl::Critic::Policy::ValuesAndExpressions::RequireInterpolationOfMetachars::BEGIN@16 at line 50
# once (1µs+0s) by Perl::Critic::Policy::ValuesAndExpressions::RequireInterpolationOfMetachars::BEGIN@16 at line 76
# once (1µs+0s) by Perl::Critic::Policy::ValuesAndExpressions::RequireInterpolationOfMetachars::BEGIN@16 at line 49
# once (1µs+0s) by Perl::Critic::Policy::ValuesAndExpressions::RequireInterpolationOfMetachars::BEGIN@16 at line 77
# once (1µs+0s) by Perl::Critic::Policy::ValuesAndExpressions::RequireInterpolationOfMetachars::BEGIN@16 at line 78
# once (1µs+0s) by Perl::Critic::Policy::ValuesAndExpressions::RequireInterpolationOfMetachars::BEGIN@16 at line 37
# once (1µs+0s) by Perl::Critic::Policy::ValuesAndExpressions::RequireInterpolationOfMetachars::BEGIN@16 at line 71
# once (1µs+0s) by Perl::Critic::Policy::ValuesAndExpressions::RequireInterpolationOfMetachars::BEGIN@16 at line 79
# once (900ns+0s) by Perl::Critic::Policy::ValuesAndExpressions::RequireInterpolationOfMetachars::BEGIN@16 at line 45
# once (900ns+0s) by Perl::Critic::Policy::ValuesAndExpressions::RequireInterpolationOfMetachars::BEGIN@16 at line 53
# once (800ns+0s) by Perl::Critic::Policy::ValuesAndExpressions::RequireInterpolationOfMetachars::BEGIN@16 at line 52 | |||||
# spent 2.14ms within Email::Address::CORE:regcomp which was called 23 times, avg 93µs/call:
# 2 times (41µs+0s) by Perl::Critic::Policy::ValuesAndExpressions::RequireInterpolationOfMetachars::BEGIN@16 at line 43, avg 21µs/call
# 2 times (38µs+0s) by Perl::Critic::Policy::ValuesAndExpressions::RequireInterpolationOfMetachars::BEGIN@16 at line 42, avg 19µs/call
# once (527µs+0s) by Perl::Critic::Policy::ValuesAndExpressions::RequireInterpolationOfMetachars::BEGIN@16 at line 133
# once (342µs+0s) by Perl::Critic::Policy::ValuesAndExpressions::RequireInterpolationOfMetachars::BEGIN@16 at line 132
# once (211µs+0s) by Perl::Critic::Policy::ValuesAndExpressions::RequireInterpolationOfMetachars::BEGIN@16 at line 131
# once (183µs+0s) by Perl::Critic::Policy::ValuesAndExpressions::RequireInterpolationOfMetachars::BEGIN@16 at line 130
# once (134µs+0s) by Perl::Critic::Policy::ValuesAndExpressions::RequireInterpolationOfMetachars::BEGIN@16 at line 73
# once (96µs+0s) by Perl::Critic::Policy::ValuesAndExpressions::RequireInterpolationOfMetachars::BEGIN@16 at line 79
# once (94µs+0s) by Perl::Critic::Policy::ValuesAndExpressions::RequireInterpolationOfMetachars::BEGIN@16 at line 75
# once (87µs+0s) by Perl::Critic::Policy::ValuesAndExpressions::RequireInterpolationOfMetachars::BEGIN@16 at line 56
# once (60µs+0s) by Perl::Critic::Policy::ValuesAndExpressions::RequireInterpolationOfMetachars::BEGIN@16 at line 50
# once (55µs+0s) by Perl::Critic::Policy::ValuesAndExpressions::RequireInterpolationOfMetachars::BEGIN@16 at line 70
# once (54µs+0s) by Perl::Critic::Policy::ValuesAndExpressions::RequireInterpolationOfMetachars::BEGIN@16 at line 71
# once (53µs+0s) by Perl::Critic::Policy::ValuesAndExpressions::RequireInterpolationOfMetachars::BEGIN@16 at line 48
# once (46µs+0s) by Perl::Critic::Policy::ValuesAndExpressions::RequireInterpolationOfMetachars::BEGIN@16 at line 54
# once (45µs+0s) by Perl::Critic::Policy::ValuesAndExpressions::RequireInterpolationOfMetachars::BEGIN@16 at line 78
# once (24µs+0s) by Perl::Critic::Policy::ValuesAndExpressions::RequireInterpolationOfMetachars::BEGIN@16 at line 49
# once (21µs+0s) by Perl::Critic::Policy::ValuesAndExpressions::RequireInterpolationOfMetachars::BEGIN@16 at line 45
# once (9µs+0s) by Perl::Critic::Policy::ValuesAndExpressions::RequireInterpolationOfMetachars::BEGIN@16 at line 37
# once (8µs+0s) by Perl::Critic::Policy::ValuesAndExpressions::RequireInterpolationOfMetachars::BEGIN@16 at line 77
# once (8µs+0s) by Perl::Critic::Policy::ValuesAndExpressions::RequireInterpolationOfMetachars::BEGIN@16 at line 53 |