はじめに
「Mooで覚えるオブジェクト指向プログラミング」シリーズを読了された皆さん、お待たせしました。今回から新シリーズ「天気情報ツールで覚えるPerl」を開始します。
このシリーズでは、天気情報を取得・表示するツールを題材に、複数のサービスを統一的に扱う設計手法を学んでいきます。前シリーズで習得した Moo の知識(has によるアトリビュート、メソッド定義、コンストラクタなど)を活用しながら、より実践的なプログラムを作成していきましょう。
対象読者
- Perl入学式を卒業したばかりの方
- 「Mooで覚えるオブジェクト指向プログラミング」シリーズを読了済みの方
- Perl v5.36以降の環境を使用できる方
このシリーズで学ぶこと
全5回を通じて、以下のスキルを身につけます。
- Mooを使った実用的なクラス設計
- 異なるインターフェースを持つサービスの統合方法
- 複数のサービスを統一的に扱う設計パターン
今回の目標
第1回となる今回は、シンプルな天気情報サービスクラス WeatherService を作成します。このクラスは、都市名を指定すると天気情報を返す基本的な機能を持ちます。
新しい概念: 基本クラス設計
今回学ぶ新しい概念は「基本クラス設計」です。前シリーズで学んだ Moo の基礎を復習しながら、実用的なクラスを設計していきます。
WeatherServiceクラスの設計
まず、天気情報サービスのクラスを設計しましょう。このクラスには以下の機能が必要です。
- 都市名を受け取り、その都市の天気を返す
get_weather メソッド - 天気情報を整形して表示する
show_weather メソッド
クラス定義のコード
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
| package WeatherService {
use v5.36;
use Moo;
sub get_weather ($self, $city) {
# 簡易的な天気データ(実際のAPIを想定したモック)
my %weather_data = (
'東京' => { condition => '晴れ', temperature => 25 },
'大阪' => { condition => '曇り', temperature => 23 },
'札幌' => { condition => '雨', temperature => 18 },
);
return $weather_data{$city} // { condition => '不明', temperature => 0 };
}
sub show_weather ($self, $city) {
my $weather = $self->get_weather($city);
say "$city の天気: $weather->{condition}(気温: $weather->{temperature}℃)";
}
}
|
このクラスの特徴を見ていきましょう。
use v5.36; で Perl v5.36 以降の機能(signatures など)を有効化use Moo; でオブジェクト指向の機能を導入get_weather メソッドは都市名を受け取り、ハッシュリファレンスで天気情報を返すshow_weather メソッドは天気情報を整形して表示する
signatures について
sub get_weather ($self, $city) という記法は Perl v5.36 で安定版となった「signatures(シグネチャ)」機能です。従来の my ($self, $city) = @_; という書き方より簡潔で、引数が明確になります。
天気情報を表示するスクリプト
次に、WeatherService クラスを使って天気情報を表示するスクリプトを作成しましょう。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
| #!/usr/bin/env perl
use v5.36;
# WeatherService クラスの定義(同一ファイル内)
package WeatherService {
use v5.36;
use Moo;
sub get_weather ($self, $city) {
my %weather_data = (
'東京' => { condition => '晴れ', temperature => 25 },
'大阪' => { condition => '曇り', temperature => 23 },
'札幌' => { condition => '雨', temperature => 18 },
);
return $weather_data{$city} // { condition => '不明', temperature => 0 };
}
sub show_weather ($self, $city) {
my $weather = $self->get_weather($city);
say "$city の天気: $weather->{condition}(気温: $weather->{temperature}℃)";
}
}
# メイン処理
package main {
use v5.36;
my $service = WeatherService->new;
# 各都市の天気を表示
$service->show_weather('東京');
$service->show_weather('大阪');
$service->show_weather('札幌');
$service->show_weather('福岡'); # 登録されていない都市
}
|
このスクリプトを実行すると、以下のような出力が得られます。
1
2
3
4
| 東京 の天気: 晴れ(気温: 25℃)
大阪 の天気: 曇り(気温: 23℃)
札幌 の天気: 雨(気温: 18℃)
福岡 の天気: 不明(気温: 0℃)
|
コードのポイント解説
インラインパッケージ
今回のコードでは、1つのファイル内に複数のパッケージを定義しています。package WeatherService { ... } というブロック形式を使うことで、パッケージのスコープを明確にしています。
戻り値の形式
get_weather メソッドは、天気の状態と気温をハッシュリファレンスで返しています。この形式にすることで、将来的に湿度や風速などの情報を追加しやすくなります。
デフォルト値の処理
登録されていない都市が指定された場合は、//(定義済み or 演算子)を使ってデフォルト値を返しています。これは Perl らしいイディオムの1つです。
今回の完成コード
今回作成した完成コードを以下に示します。weather_service.pl として保存し、実行してください。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
| #!/usr/bin/env perl
use v5.36;
# WeatherService クラス
# シンプルな天気情報サービスを提供する
package WeatherService {
use v5.36;
use Moo;
# 都市名を受け取り、天気情報をハッシュリファレンスで返す
sub get_weather ($self, $city) {
my %weather_data = (
'東京' => { condition => '晴れ', temperature => 25 },
'大阪' => { condition => '曇り', temperature => 23 },
'札幌' => { condition => '雨', temperature => 18 },
);
return $weather_data{$city} // { condition => '不明', temperature => 0 };
}
# 天気情報を整形して表示する
sub show_weather ($self, $city) {
my $weather = $self->get_weather($city);
say "$city の天気: $weather->{condition}(気温: $weather->{temperature}℃)";
}
}
# メイン処理
package main {
use v5.36;
my $service = WeatherService->new;
say "=== 天気情報ツール ===";
$service->show_weather('東京');
$service->show_weather('大阪');
$service->show_weather('札幌');
$service->show_weather('福岡');
}
|
実行方法:
1
2
| cpanm Moo # 未インストールの場合
perl weather_service.pl
|
まとめ
今回は、天気情報を返すシンプルな WeatherService クラスを作成しました。
- Moo を使った基本的なクラス設計を復習した
- Perl v5.36 の signatures 機能を活用した
- 天気情報をハッシュリファレンスで扱う設計にした
次回予告
次回は、別の天気情報サービス(異なるメソッド名や戻り値を持つ)を追加します。2つのサービスを同時に使おうとすると、どのような問題が発生するのでしょうか?お楽しみに!