RSSを読み込み、パースさせて、ファイルに保存する

サンプルを模倣。
read_rss.pl

#!/usr/bin/perl
use strict;
use warnings;

use LWP::Simple 'get';
use XML::RSS;

my $rss = new XML::RSS;
eval {
    $rss->parse(LWP::Simple::get('http://weather.livedoor.com/forecast/rss/index.xml'));
};

# $@ は eval のエラーメッセージ
exit if $@;

open(OUT, '> weather.txt');
foreach my $ref(@{$rss->{items}}) {
    print OUT "$ref->{'title'}: $ref->{'link'}\n";
}
close(OUT);

RSSの概要
実行をしてみる。

% chmod u+x read_rss.pl
% ./read_rss.pl
Wide character in print at ./read_rss.pl line 18.
Wide character in print at ./read_rss.pl line 18.
Wide character in print at ./read_rss.pl line 18.
Wide character in print at ./read_rss.pl line 18.
Wide character in print at ./read_rss.pl line 18.
Wide character in print at ./read_rss.pl line 18.
Wide character in print at ./read_rss.pl line 18.
Wide character in print at ./read_rss.pl line 18.
Wide character in print at ./read_rss.pl line 18.
Wide character in print at ./read_rss.pl line 18.
Wide character in print at ./read_rss.pl line 18.
Wide character in print at ./read_rss.pl line 18.
Wide character in print at ./read_rss.pl line 18.
Wide character in print at ./read_rss.pl line 18.
Wide character in print at ./read_rss.pl line 18.

% cat weather.txt
[ PR ] ブログで道央のお天気を簡単ゲット!: http://weather.livedoor.com/weather_hacks/plugin.html?pref=1b
[ 今日の天気 ] 札幌 - 曇り - 最高気温16- 529日(木): http://weather.livedoor.com/area/1b/4.html?r=rss
[ 今日の天気 ] 釧路 - 晴のち曇 - 最高気温12- 529日(木): http://weather.livedoor.com/area/1c/11.html?r=rss
[ 今日の天気 ] 秋田 - 雨のち晴 - 最高気温18- 529日(木): http://weather.livedoor.com/area/5/20.html?r=rss
[ 今日の天気 ] 仙台 - 雨時々曇 - 最高気温13- 529日(木): http://weather.livedoor.com/area/4/25.html?r=rss
[ 今日の天気 ] 新潟 - 雨のち晴 - 最高気温21- 529日(木): http://weather.livedoor.com/area/15/50.html?r=rss
[ 今日の天気 ] 東京 - 雨のち曇 - 最高気温17- 529日(木): http://weather.livedoor.com/area/13/63.html?r=rss
[ 今日の天気 ] 長野 - 曇り - 最高気温18- 529日(木): http://weather.livedoor.com/area/20/72.html?r=rss
[ 今日の天気 ] 名古屋 - 雨のち曇 - 最高気温23- 529日(木): http://weather.livedoor.com/area/23/38.html?r=rss
[ 今日の天気 ] 大阪 - 曇り - 最高気温22- 529日(木): http://weather.livedoor.com/area/27/81.html?r=rss
[ 今日の天気 ] 高知 - 晴時々曇 - 最高気温29- 529日(木): http://weather.livedoor.com/area/39/107.html?r=rss
[ 今日の天気 ] 広島 - 曇のち晴 - 最高気温27- 529日(木): http://weather.livedoor.com/area/34/90.html?r=rss
[ 今日の天気 ] 福岡 - 曇のち晴 - 最高気温23- 529日(木): http://weather.livedoor.com/area/40/110.html?r=rss
[ 今日の天気 ] 鹿児島 - 曇時々晴 - 最高気温28- 529日(木): http://weather.livedoor.com/area/46/132.html?r=rss
[ 今日の天気 ] 那覇 - 晴のち曇 - 最高気温29- 529日(木): http://weather.livedoor.com/area/47/136.html?r=rss

Wide character in print とは何か?

調べてみると、多くの検索結果が得られた。

詳しく調べているのは、下記を参照。

  1. Wide character in print at ...
  2. Perl 5.8.x Unicode関連

原因としては、

Wide character in print at というエラーは UTF-8 フラグが付いた文字列を print しようとしているからである。なので UTF-8 フラグを取り外してから print すればエラーがでなくなります。
Wide character in print at ...

Undefined subroutine &main::encode called at ./read_rss.pl line 20.

Wide character in print at ... に記載されている

print encode('utf-8', $string);

の通りに修正して実行をすると、下記のエラーが表示される。

% ./read_rss.pl
Undefined subroutine &main::encode called at ./read_rss.pl line 20.

Undefined subroutine &main::encode called」というエラーを調べてみたが、Google の検索結果では、わずか4件しか表示されなかった。
他に、「binmode(STDOUT, ":utf8");」を追加しても、「Wide character in print」という warning は表示されたままだった。
Perl 5.8.x Unicode関連 に目を通して、試しに

use Encode;

を追加してみたら、エラーも warning も表示されずに、実行結果を終えることができた。
最終的なコードは下記の通り。

#!/usr/bin/perl
use strict;
use warnings;

use LWP::Simple 'get';
use XML::RSS;
use Encode;

my $rss = new XML::RSS;
eval {
    $rss->parse(LWP::Simple::get('http://weather.livedoor.com/forecast/rss/index.xml'));
};

# $@ は eval のエラーメッセージ
exit if $@;

open(OUT, '> weather.txt');
foreach my $ref(@{$rss->{items}}) {
    print OUT encode('utf-8', "$ref->{'title'}: $ref->{'link'}\n");
}
close(OUT);

Perl文字コードまわりの処理はおそらく初心者だと投げ出してしまうように思う。
UTF-8 のフラグがついているから、UTF-8 フラグを除け」と言われても、初心者には理解できないだろう。
実際、PHPRuby で処理をするならば、ここまでややこしくはない。