utf8 flag must be off when using XML::Atom

使用XML::Atom可以很方便地为Perl脚本增加生成Atom Feed的功能。例如生成一个entry的代码如下:

use XML::Atom::Entry;

$entry = XML::Atom::Entry;
$entry->title('我的标题');
$entry->updated('2007-01-16T08:00:00+08:00');
$entry->id('my unique id for this entry');
$entry->summary('oops');

$link = XML::Atom::Link->new;
$link->type('text/html');
$link->rel('alternate');
$link->href('http://example.com/entry.html');

$entry->add_link($link);

print $entry->as_xml_utf8;

到目前为止,一切都很好。

在实际的代码中,我们不可能把内容静态地写在代码里,而是从其它地方获得的,这时,就有可能发生编码问题。比如,标题是从某个网页上提取出来的:

use LWP::UserAgent;

$ua = LWP::UserAgent->new;
$response = $ua->get($url);
$content = $response->decoded_content;
($year, $month, $day) = extract_date_from_web_page($content);
$entry->title("$year年$month月$day日");

这时打印出来的标题是乱码。

原因是经过decode后,变量$year、$month和$day的utf8 flag被打开了,应先将其关掉:

use Encode;
Encode::_utf8_off($year);
Encode::_utf8_off($month);
Encode::_utf8_off($day);
$entry->title("$year年$month月$day日");

这样,编码就正确了。

Implicit Type Conversion in Perl

下面的程序把类型为Person的对象隐式转换为字符串和整数。

#!/usr/bin/perl

package Person;
use overload '0+' => &age, # convert type to integer
   '""' => &name,           # convert type to string
   fallback => 1;            # make ($p - $a) possible

sub new {
   my ($this, $name, $age) = @_;
   my $class = ref($this) || $this;
   my $self = { name => $name, age => $age };
   bless $self, $class;
   return $self;
}

sub name {
   my $self = shift;
   return $self->{name};
}

sub age {
   my $self = shift;
   return $self->{age};
}

package main;

$p = Person->new("Old Brother", 20);
print $p->name, " is ", $p->age, " years old.n";
$a = Person->new("Young Sister", 8);
print $a->name, " is ", $a->age, " years old.n";
print $p, " is ", $p - $a, " year older than ", $a, ".n";

overload的详细信息参见perldoc overload