Mail::M...ge::Body(3)
π NAME π
Mail::Message::Body β the data of a body in a message π
This one's Mail::M...ge::Body(3), from the User Contributed Perl Documentation, and bestie it's a long one, so we're doing it in parts. This is part 1. Let's get into it π«Ά
π INHERITANCE π
okay so the whole family tree, exactly how the docs lay it out, no edits, no cap:
Mail::Message::Body has extra code in
Mail::Message::Body::Construct
Mail::Message::Body::Encode
Mail::Message::Body
is a Mail::Reporter
Mail::Message::Body
is a Mail::Reporter
Mail::Message::Body is extended by
Mail::Message::Body::File
Mail::Message::Body::Lines
Mail::Message::Body::Multipart
Mail::Message::Body::Nested
Mail::Message::Body::String
Mail::Message::Body is realized by
Mail::Message::Body::Delayed
π¦ SYNOPSIS π¦
the vibe check, in code:
my Mail::Message $msg = ...;
my $body = $msg->body;
my @text = $body->lines;
my $text = $body->string;
my $file = $body->file; # IO::File
$body->print(\*FILE);
my $content_type = $body->type;
my $transfer_encoding = $body->transferEncoding;
my $encoded = $body->encode(mime_type => 'text/html',
charset => 'us-ascii', transfer_encoding => 'none');\n";
my $decoded = $body->decoded;
πΈ DESCRIPTION πΈ
okay so here's the tea β: the encoding + decoding glow-up for a Mail::Message::Body is implemented in the Mail::Message::Body::Encode package. That package gets auto-loaded the moment encoding and decoding of messages needs to happen. And the methods that just build and process body objects? Those are living in Mail::Message::Body::Construct. β¨
The body of a message (that's a Mail::Message object) gets stored in one of the many body types. Every body type has equivalent functionality β same energy, same job, periodt β but the performance differs. Each body type has its own documentation with all the deets about its implementation. π
Extends "DESCRIPTION" in Mail::Reporter.
Extends "DESCRIPTION" in Mail::Reporter.
π OVERLOADED π
the magic tricks, bestie β the things that let a body cosplay as a string, a number, an array, and an always-truthy babe πͺ
overload: '""'stringification β hands you back the body as a string, which β heads up β will trigger completion. Unless it's being called to produce a string forCarp. That last bit is there to avoid deep recursions. π
Β» example: stringification of body
print $msg->body; # implicit by print
my $body = $msg->body;
my $x = "$body"; # explicit by interpolation
overload: '=='numerical comparison β compares whether two references point to the same message. This only produces correct results if both arguments are message references within the same folder. β οΈ
Β» example: use of numeric comparison on a body
my $skip = $folder->message(3);
foreach my $msg (@$folder)
{ next if $msg == $skip;
$msg->send;
}
overload: '@{}'addressed as array β when a body object gets used like an array reference, you get the lines of the body back. Same thing as usinglines(). π«
Β» example: using a body as array
print $body->lines->[1]; # second line
print $body->[1]; # same
my @lines = $body->lines;
my @lines = @$body; # same
overload: booltrue/false β always returns atruevalue. That's needed so overloaded objects can be used likeif($body). Otherwise you'd have to writeif(defined $body)to avoid a runtime error. π₯
π₯ METHODS π₯
Extends "METHODS" in Mail::Reporter.
Extends "METHODS" in Mail::Reporter.
π Constructors π
Extends "Constructors" in Mail::Reporter.
Extends "Constructors" in Mail::Reporter.
$obj->clone()β gives you back a copy of this body, usually so it can ride along inside a cloned message. For a whole entire message, useMail::Message::clone(). π«Ά$class->new(%options)β BE WARNED that whatever you put in here are encodings and such that are already in place. These options will not trigger conversions. When you need conversions, first create a body with options that tell what you've got, and then callencode()for what you need. Improves base, see "Constructors" in Mail::Reporter. π
-Option --Default
based_on undef
charset 'PERL'
checked false
content_id undef
data undef
description undef
disposition undef
eol 'NATIVE'
file undef
filename undef
language undef
message undef
mime_type 'text/plain'
modified false
transfer_encoding 'none'
based_on => $bodyβ the info about encodings must be taken from the given$body, unless you specified something differently. πΈcharset => $charset|'PERL'|<undef>β sets the character-set that's used in the data. Only useful when paired with amime_typethat refers totextin any shape, and that doesn't already contain an explicit charset. This field is case-insensitive.
When a known CHARSET is provided and the mime-type says text, then the data is expected to be raw octets in that particular encoding (see Encode). When 'PERL' is given, then the data is in Perl's internal encoding β either cp1252 or utf8. More details in "Character encoding PERL". π§
checked => BOOLEANβ whether the added information has been checked not to contain illegal octets with respect to the transfer encoding and mime type. If it hasn't been checked, and it then gets set as body for a message, it will be. βcontent_id => STRINGβ inmultipart/relatedMIME content, thecontent_idis required so the related content can be accessed through acid:<...>descriptor of an inline disposition.
A Content-ID is supposed to be globally unique. Because of that, it's common to append @computer.domain to the end of some unique string. And since other content in the multipart/related container also needs to know what this Content-ID is, that should be left to the imagination of the person making the content (for now). π
As a MIME header field, the Content-ID string is expected to sit inside angle brackets. π
data => \@lines|$textβ the content of the body. The only way to set a body's content is during the creation of the body. So if you wanna modify the content of a message, you need to create a new body with the new content and add that to the body. Why tho? Because correct encodings and body information must be guaranteed. It also saves you the hassle of calculating the number of lines in the body and checking whether bad characters are enclosed in the text. π
Give @lines each terminated by a newline, or one $text which may contain multiple lines, separated and terminated by a newline. π
description => STRING|$fieldβ informal info about the body content. This data relates to theContent-Descriptionfield. Give a STRING which will become the field content, or a real$fieldobject. π¬disposition => STRING|$fieldβ how this message can be decomposed. This data relates to theContent-Dispositionfield. Give a STRING which will become the field content, or a real$field. π·
The content of this field is specified in RFC 1806. The body of the field can be inline, to indicate that the body is intended to be displayed automatically upon display of the message. Use attachment to indicate that it's separate from the main body of the mail message, and that its display should not be automatic, but contingent upon some further action of the user. πΌοΈ
The filename attribute specifies a name to which is suggested to the reader of the message when it is extracted. π
[3.017] RFC9078 adds type reaction. This part content is restricted to a single line of emoji's. For this kind, you need to pass the FIELD here, as well as mime-type text/plain. π
eol => 'CR'|'LF'|'CRLF'|'NATIVE'β convert the message into having the specified string as line terminator for all lines in the body.NATIVEis used to represent the\non the current platform and will be translated in the applicable one.
BE WARNED that folders with a non-native encoding may appear on your platform, for instance in Windows folders handled from a UNIX system. The eol encoding has effect on the size of the body! β οΈ
file => $file|$handle|$ioβ read the data from the specified$filename, file$handle, or object of typeIO::Handle. πfilename => $fileβ [3.001] overrule/set$filename for content-disposition. π·οΈlanguage => STRING|\@lang|$fieldβ [3.017] RFC3282Content-Languagefield, containing a comma separated list of language codes. πmessage => $messageβ the$messagewhere this body belongs to. πmime_type => STRING|$field|$mimeβ the type of data which is added. You may specify a content of a header line as STRING, or a$fieldobject. You may also specify aMIME::Typeobject. In any case, it will be kept internally as a real field (aMail::Message::Fieldobject). This relates to theContent-Typeheader field. π
A mime-type specification consists of two parts: a general class (text, image, application, etc) and a specific sub-class. Examples for specific classes with text are plain, html, and xml. This field is case-insensitive but case preserving. The default mime-type is text/plain. π
modified => BOOLEANβ whether the body is flagged modified, directly from its creation. π©transfer_encoding => STRING|$fieldβ the encoding that the data has. If the data is to be encoded, then you will have to callencode()after the body is created. That will return a new encoded body. This$fieldis case-insensitive and relates to theContent-Transfer-Encodingfield in the header. π
Β» example:
my $body = Mail::Message::Body::String->new(file => \*IN,
mime_type => 'text/html; charset="ISO-8859-1"');
my $body = Mail::Message::Body::Lines->new(data => ["first\n", $second],
charset => 'ISO-10646', transfer_encoding => 'none');
my $body = Mail::Message::Body::Lines->new(data => \@lines,
transfer_encoding => 'base64');
my $body = Mail::Message::Body::Lines->new(file => 'picture.gif',
mime_type => 'image/gif', content_id => '<12345@example.com>',
disposition => 'inline');
π Attributes π
Extends "Attributes" in Mail::Reporter.
Extends "Attributes" in Mail::Reporter.
$obj->charsetDetectAlgorithm( [CODE|undef|METHOD] )β inherited, bestie, go peep Attributes over inMail::Message::Body::Encodeπ«Ά
β¨ Constructing a body β¨
$obj->attach(@messages, %options)β inherited, so slide over to Constructing a body inMail::Message::Body::Constructπ$obj->charsetDetect(%options)β inherited, same deal: Constructing a body inMail::Message::Body::Encodeβ¨$obj->check()β inherited, Constructing a body inMail::Message::Body::Encode, go go go πΈ$obj->concatenate(@components)β inherited, Constructing a body inMail::Message::Body::Constructπ$obj->decoded(%options)β okay this one is lowkey important so listen up π it hands you back a body, like an object that's a (sub-)class ofMail::Message::Body, and that body holds a simplified, chill representation of the textual data. Now β plot twist β the object you get back might literally be the same object you called it on, or it might be a brand new body of literally any type. No promises, she's mysterious.
So this:
my $dec = $body->decoded;
is equivalent to this whole thing:
my $dec = $body->encode(
mime_type => 'text/plain',
transfer_encoding => 'none',
charset => 'PERL',
);
The $dec you get back is a body, periodt. Wanna know what got produced? Ask the mimeType() method, she'll tell you. And heads up: this $dec body is not related to any header. She's independent, she's free π
Options, bestie:
-Optionβ--Defaultresult_typeβ<same as current>
result_type => CLASS
$obj->encode(%options)β inherited, Constructing a body inMail::Message::Body::Encodeπ¦$obj->encoded(%options)β inherited, Constructing a body inMail::Message::Body::Encodeβ$obj->eol( ['CR'|'LF'|'CRLF'|'NATIVE'] )β inherited, Constructing a body inMail::Message::Body::Encodeπ$obj->foreachLine(CODE)β inherited, Constructing a body inMail::Message::Body::Constructπ$obj->stripSignature(%options)β inherited, Constructing a body inMail::Message::Body::Constructπ§$obj->unify($body)β inherited, Constructing a body inMail::Message::Body::Encodeβ¨
π The body π
$obj->isDelayed()β gives you back atrueorfalse, depending on whether this body has actually been read from file yet. Fun fact: this can only ever befalsefor aMail::Message::Body::Delayed. Iconic behaviour honestly.$obj->isMultipart()β tells you whether this message-body has parts inside it that are messages all on their own π$obj->isNested()β only evertruefor a body that contains exactly one sub-message, aka theMail::Message::Body::Nestedbody type πΈ$obj->message( [$message] )β returns the message (or message part) this body belongs to. You can optionally hand it a new$messagefirst and it'll switch to that one. And if you passundef? The body gets fully disconnected from the message, it's giving β¨independent eraβ¨$obj->partNumberOf($part)β returns a string for multiparts and nested bodies, and otherwise it's an error, sorry bestie π It's whatMail::Message::partNumber()uses under the hood.
π«Ά About the payload π«Ά
$obj->charset()β returns the character set used in the text body, as a string. This is part of whatever thetypemethod hands back π$obj->checked( [BOOLEAN] )β tells you whether the body encoding has been checked or not. Pass a value and you can set that flag to a new one while you're at it π$obj->contentId( [STRING|$field] )β returns (or, if you pass something, sets) the id β that's the unique reference β of a message part. The header field it's chillin' with isContent-ID. You get back aMail::Message::Fieldobject (which stringifies into the field content, cute). If no disposition was specified, the field content will benone. The argument you pass can be aSTRING(which gets converted into a field) or a fully prepared header$fieldπ$obj->description( [STRING|$field] )β returns (or sets) the informal description of the body content. Its header field bestie isContent-Description. You get back aMail::Message::Fieldobject (stringifies into the field content). Field content isnoneif no disposition was specified. Argument can be aSTRING(converted into a field) or a fully prepared header field π$obj->disposition( [STRING|$field] )β returns (or sets) how the message can be disposed of (aka unpacked). The related header field isContent-Disposition. Back comes aMail::Message::Fieldobject (stringifying into the field content). The field content will benoneif no disposition was specified. Argument: aSTRING(converted into a field) or a fully prepared header field β¨
[3.017] heads up: RFC9078 adds the type reaction. That part's content is restricted to a single line of emoji's. Yes really. The manpage said emoji's and I'm not about to edit her π
$obj->dispositionFilename( [$directory] )β inherited, see About the payload inMail::Message::Body::Encodeπ¦$obj->isBinary()β inherited, About the payload inMail::Message::Body::Encodeπ$obj->isText()β inherited, About the payload inMail::Message::Body::Encodeβ$obj->language( [@langs|\@langs|$langs|$field] )β [3.017] returns (or sets) theContent-Languageheader, exactly as specified in RFC3282. You get the field back with a comma separated list of languages as its body π$obj->mimeType()β returns aMIME::Typeobject that's related to this body's type. This is different from thetypemethod, which gives you aMail::Message::Fieldinstead. Know the difference, bestie π
Β» example:
if($body->mimeType eq 'text/html') {...}
print $body->mimeType->simplified;
$obj->nrLines()β returns the number of lines in the message body. For multi-part messages, this counts the header lines and the boundaries of all the parts too πΈ$obj->size()β the total number of bytes in the message body. And here's the thing: the size is computed in whatever shape the body is currently in. So like, if this is a base64 encoded message, you get the size of the encoded data back. You probably wanna callMail::Message::decoded()first π$obj->transferEncoding( [STRING|$field] )β returns the transfer-encoding of the data inside this body as aMail::Message::Field(which stringifies to its content). If it needs changing, call theencode()orencoded()method instead. When there's no encoding present, the field contains the textnone. The optionalSTRINGor$fieldforces a new encoding to be set β without doing the actual required translations, so watch out π«Ά
Β» example:
my $transfer = $msg->decoded->transferEncoding;
$transfer->print; # --> Content-Encoding: base64
print $transfer; # --> base64
if($msg->body->transferEncoding eq 'none') {...}
$obj->type( [STRING|$field] )β returns the type of information the body contains, as aMail::Message::Fieldobject. The type is taken from theContent-Typeheader field. And if the header didn't have that field at all? You get a default field containingtext/plain, she's got your back π
ngl though, you can usually do better with mimeType(), because that one returns a clever object with actual type information in it. Just saying.
Β» example:
my $msg = $folder->message(6);
$msg->get('Content-Type')->print;
# --> Content-Type: text/plain; charset="us-ascii"
my $content = $msg->decoded;
my $type = $content->type;
print "This is a $type message\n";
# --> This is a text/plain; charset="us-ascii" message
print "This is a ", $type->body, "message\n";
# --> This is a text/plain message
print "Comment: ", $type->comment, "\n";
# --> Comment: charset="us-ascii"
π Access to the payload π
$obj->endsOnNewline()β tells you whether the last line of the body is terminated by a new-line (in transport it'll become a CRLF). And an empty body returnstrueas well, because the newline comes from the line before it. Iconic loophole β¨$obj->file()β returns the content of the body as a file handle. That stream might be a real file, or a simulated file in any form Perl supports. You might not be able to write to the file handle, but you can absolutely read from it π
WARNING: even if the file handle does support writing, do NOT write to the file handle. If you do, some of the internal values of the Mail::Message::Body may not get updated. And then everything is cursed. Don't do it bestie π
$obj->lines()β returns the content of the body as a list of lines (in LIST context) or as a reference to an array of lines (in SCALAR context). And in scalar context, that array of lines gets cached so you avoid needless copying, which means wayyy faster access for large messages π₯
If you just want the number of lines, use the nrLines() method instead β it's usually much more efficient π
BE WARNED: for some types of bodies, that reference will point at the original data. You must NOT change the referenced data! If you do, some of the essential internal variables of the Mail::Message::Body may not be updated. Respect the reference, she's sensitive π
Β» example:
my @lines = $body->lines; # copies lines
my $line3 = ($body->lines)[3] # only one copy
print $lines[0];
my $linesref = $body->lines; # reference to originals
my $line3 = $body->lines->[3] # only one copy (faster)
print $linesref->[0];
print $body->[0]; # by overloading
$obj->print( [$fh] )β prints the body to the specified$fh(defaults to whatever handle is currently selected). AnIO::Fileobject works, or... honestly any object with aprint()method will do. Nothing useful comes back, she's not about the returns π¦$obj->printEscapedFrom($fh)β prints the body to the specified$fh, BUT every line that starts with'From '(optionally already preceded by>'s) will habe an>added in front. Yes, "habe". That's what the page says, character for character, I'm not touching it π Nothing useful is returned.$obj->string()β returns the content of the body as a scalar (a single string). And heads up: this is a copy of the internally kept information π«Ά
Β» example:
my $text = $body->string;
print "Body: $body\n"; # by overloading
$obj->stripTrailingNewline()β removes the newline from the last line. Or, if that last line contains nothing other than a newline, it removes the whole line πΈ$obj->write(%options)β writes the content of the body to a file. But be warned, bestie: you may want to decode the body before writing it! π-Optionβ--Defaultfilenameβ<required>
filename => FILENAME
Β» example: write the data to a file
use File::Temp;
my $fn = tempfile;
$message->decoded->write(filename => $fn);
Β» example: using the content-disposition information to write
use File::Temp;
my $dir = tempdir; mkdir $dir or die;
my $fn = $message->body->dispositionFilename($dir);
$message->decoded->write(filename => $fn);
Internals πΈ
$any->addTransferEncHandler( $name, <$class|$object> )β inherited bestie, go peek at "Internals" inMail::Message::Body::Encodefor the full tea π$obj->contentInfoFrom($head)β moves all the body-related info out of the header and into this body. Like, transferring the vibe over π«Ά$obj->contentInfoTo($head)β copies the content information (aka theContent-*fields) into the$headyou point at. Use this when the body got built out of raw data and is missing the info it needs, so you gotta add it. Also checkcontentInfoFrom(), they're a little duo β¨$obj->fileLocation( [$begin, $end] )β where the body lives inside the file. Hands you back a list withbeginandend. Thebeginis the offset of the first byte of the folder used for this body, andendis the offset of the first byte of the next message. π$obj->getTransferEncHandler($type)β inherited, see "Internals" inMail::Message::Body::Encodeπ$obj->isModified()β tells you whether the body has changed at all. Simple as that, queen π$obj->load()β makes sure the body is actually loaded, and returns the loaded body. No more lazy vibes β¨$obj->modified( [BOOLEAN] )β flips the body's modification flag. Doing this forces a re-write of the body into the folder file when it gets closed. And ngl, changing the body is pretty dangerous: the very same body might be shared between multiple messages inside your program, so you're messing with more than you think π
Especially be warned: you have to change the message-id when you change the body of the message, because no two messages should ever have the same id. Periodt. π
Call it with no value and you get the current setting back β though honestly you're better off just using isModified().
$obj->moveLocation( [$distance] )β moves the registration of the message over$distanceto a new location. This gets called when the message is written out to a new version of the same folder-file. π¦$obj->read( $parser, $head, $bodytype, [$chars, [$lines]] )β reads the body out of the file using$parser. Heads up: the actual implementation of this method is different for every type of body. The$bodytypeargument is either a class name or a code reference to a routine that can produce a class name, and multipart bodies use it to figure out the type of body for each individual part. π
The $chars argument is the estimated number of bytes in the body, or undef when nobody knows. Sometimes you can derive that from the header (the Content-Length line) or from the file-size.
The second argument is the estimated number of $lines in the body. It's less useful than $chars, but it can help you decide whether the message separator is trustworthy. You might find this value in the Lines field of the header. π
Error handling π
Extends "Error handling" in Mail::Reporter.
Extends "Error handling" in Mail::Reporter.
(yes bestie, it really does say it twice, I'm not playing π)
$obj->AUTOLOAD()β when an unknown method gets called on a message body object, it's not automatically a problem. For performance reasons, some methods live in separate files and only get demand-loaded. But if that delayed compilation of the extra modules doesn't save the day, then an error gets produced. Improves base, see "Error handling" inMail::Reporterβ¨$obj->notImplemented()β inherited, see "Error handling" inMail::Reporterπ$obj->notImplemented()β inherited, see "Error handling" inMail::Reporterπ
Cleanup π§
Extends "Cleanup" in Mail::Reporter.
Extends "Cleanup" in Mail::Reporter.
$obj->DESTROY()β inherited, see "Cleanup" inMail::Reporterπ$obj->DESTROY()β inherited, see "Cleanup" inMail::Reporterπ
β¨ DETAILS β¨
Access to the body π¦
A body can be chilling inside a message, but it can also live completely on its own. Either way it's storing data, and either way you can ask the same questions: what type of data is it, how many bytes and lines does it have, what encoding is being used? Any body can be encoded and decoded, and both of those hand you back a new body object. But here's the thing β bodies that are part of a message will always be in a shape where they can be written to a file or sent somewhere: they'll be encoded if that's what's needed. No cap. π
Β» Example
my $body = Mail::Message::Body::String->new(mime_type => 'image/gif');
$body->print(\*OUT); # this is binary image data...
my $encoded = $message->body($body);
$encoded->print(\*OUT); # ascii data, encoded image
So now encoded refers to the body of the $message, which is the content of $body in a shape that it can actually be transmitted in. Usually base64 encoding is what's going on here. β¨
Body class implementation π
The body of a message can be stored in so many ways. Roughly speaking, the implementations split into two groups: the data collectors and the complex bodies. The former give you various ways to access data, and they're fully compatible with each other β they only differ in performance and memory footprint under different circumstances. The latter were created to handle complex multiparts and lazy extraction. πΈ
Data collector bodies π
Mail::Message::Body::Stringβ the whole message body is stored in one single scalar. Small messages can live like this with zero performance penalties. iconic πMail::Message::Body::Linesβ every line of the message body is stored as its own single scalar. Super useful when you want a detailed look into the message body, which is usually organized line by line. πMail::Message::Body::Fileβ the message body is stored in an external temporary file. This storage type is especially useful when the body is large, the whole folder is large, or memory is limited. ποΈMail::Message::Body::InFolderβ NOT IMPLEMENTED YET. The message is kept in the folder, and is only taken out when the content changes. πMail::Message::Body::Externalβ NOT IMPLEMENTED YET. The message is kept in a separate file, usually because the message body is large. The difference from the::Externalobject is that this external storage stays that way between closing and opening of a folder. The::Externalobject only uses a file while the folder is open. π
Complex bodies π
Mail::Message::Body::Delayedβ the message-body hasn't been read yet, but the exact location of the body is known, so it can be read whenever it's needed. This is part of the lazy extraction mechanism. Once it gets extracted, the object can become any simple or complex body. π΄Mail::Message::Body::Multipartβ the message body contains a set of sub-messages (which can themselves contain multipart bodies, it goes deep). Each sub-message is an instance ofMail::Message::Part, which is an extension ofMail::Message. π§©Mail::Message::Body::Nestedβ nested messages, likemessage/rfc822: they contain a message inside the body. For most code they just behave like multiparts. πͺ
Character encoding PERL π
A body object can be part of a message, or stand-alone. When it's part of a message, the "transport encoding" and the content have to be in a shape where the data can be transported via SMTP.
But when you want to process the body data in plain Perl (or when you build body data out of normal Perl strings), you need to be aware of Perl's internal representation of strings. That can either be cp1252 (extended latin1) or utf8 (not real UTF-8, but something similar β go read the perlunicode manual page for the details, iykyk). So before you start using data from an incoming message, do this:
my $body = $msg->decoded;
my @lines = $body->lines;
Now the body has character-set 'PERL' (when it's text, obviously).
When you create a new body that contains text content (which is the default), it gets created with character-set 'PERL' unless you explicitly specify a character-set.
my $body = Mail::Box::Body::Lines->new(data => \@lines);
# now mime=text/plain, charset=PERL
my $msg = Mail::Message->buildFromBody($body);
$msg->body($body);
$msg->attach($body); # etc
# these all will convert the charset=PERL into real utf-8,
# cp1252 or us-ascii, which depends on the characters found.
Autodetection of character-set π
This Body object represents data as part of an existing message, or as something about to become part of a message. The body can be in two states:
- ready to be processed textually, using Perl's string operations
- raw bytes read or to be written
In the first case, the body content has no transfer encoding on it (none), and the character-set is PERL. In the second version, the body may have transfer encoding, and it has an (IANA listed) charset on it, which defaults to us-ascii.
Using encode() (maybe via decoded()), you can convert bodies from one state into a different one. And in one single go, you can change the transfer-encoding, the character-set, or whether it's in PERL string format or raw (in bytes). Slay. β¨
[3.013] A serious problem pops up when a conversion is needed, while the input or output character-set is not explicitly known. The email RFCs state that the default is us-ascii. However β plot twist β in the real world it can be literally anything. So in those situations, autodetection kicks in. π
- When a Body is read (using
Mail::Message::read()and friends), the character-set may stay undefined until transfer-decoding has been applied. At that moment, (configurable auto-detection) is applied. π - When a Body is created within the program, without a specific character-set, it will use
'PERL'. π¦ - When a Body is written, the requested character-set is not specified, and the current character-set is
PERL, then auto-detection is used. This may result inus-ascii,cp1252andutf-8. π - In all other cases, the character-set is known, so it's "easy". π
π¨ DIAGNOSTICS π¨
okay bestie, this is the part where the module yells at you. every single one of these is a real message it can throw, so read them like they're texts from a friend who's mildly stressed π
Warning: Content-Transfer-Encoding '$te' requires explicit charset, defaulted to utf-8.Cast byencode()Error: cannot concatenate element $whichCast byconcatenate()Fault: cannot open $file to write body: $!Cast bywrite()Warning: charset '$name' is not known.So like, the encoding or decoding of a message body ran into a character set that Perl'sEncodemodule simply does not understand. rip. Cast byencode()Error: class $package does not implement method $method.Fatal error: the specific$package(or one of its superclasses) does not implement this method where it should. This message means that some other related classes do implement this method however the class at hand does not. Probably you should investigate this and probably inform the author of the package. Cast bynotImplemented()Error: class $package does not implement method $method.Fatal error: the specific$package(or one of its superclasses) does not implement this method where it should. This message means that some other related classes do implement this method however the class at hand does not. Probably you should investigate this and probably inform the author of the package. Cast bynotImplemented()
no fr, that one is listed twice in the original and we are keeping it twice. the manpage said it twice, so we say it twice. consistency is the vibe β¨
Fault: error closing $file after write body: $!Cast bywrite()Error: message body: illegal datatype '$type' for data option.Cast bynew()Error: message body: illegal datatype '$type' for file option.Cast bynew()Warning: no decoder defined for transfer encoding '$encoding'.The data (message body) is encoded in a way which is not currently understood, therefore no decoding (or recoding) can take place. Cast byencode()Warning: no encoder defined for transfer encoding '$encoding'.The data (message body) has been decoded, but the required encoding is unknown. The decoded data is returned. Cast byencode()Error: no filename parameter for write() body.Cast bywrite()Error: part number needs multi-part or nested.Cast bypartNumberOf()Error: unknown line terminator '$eol'.Cast byeol()
π SEE ALSO π
This module is part of Mail-Message version 4.04, built on February 04, 2026. Website: http://perl.overmeer.net/CPAN/
π LICENSE π
For contributors see file ChangeLog.
This software is copyright (c) 2001-2026 by Mark Overmeer.
This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.
and that's a wrap on the whole page, bestie!! π the source you just read is Mail-Message version 4.04, built February 04, 2026, and this particular rendering came off perl v5.42.0 dated 2026-02-05 β that footer's the whole receipts section, so consider yourself receipted π
go forth and encode responsibly, mwah π«Άπ
π¦ where this page comes from
- fedora 44: perl-Mail-Message 4.04-1.fc44 Β· GPL-1.0-or-later OR Artistic-1.0-Perl
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms