Featured image of post 第2回-設定ファイルを読み込もう — 設定ファイルマネージャーを作ってみよう

第2回-設定ファイルを読み込もう — 設定ファイルマネージャーを作ってみよう

Perl/Mooで外部の設定ファイル(INI形式)を読み込む方法を解説。load_configメソッドの実装と、設定値の取得方法を学びます。

@nqounetです。

前回は、ハードコードされた設定値をConfigクラスで管理する方法を学びました。

今回は、設定値を外部ファイルから読み込む機能を追加します。

今回のゴール

外部の設定ファイル(INI形式)を読み込んで、設定値を取得できるようにすることです。

ミキさんからの追加要望

ミキさんからこんな相談がありました。

「設定値を変えるたびにスクリプトを書き換えるのは面倒だな。設定ファイルを用意して、そこから読み込めるようにできない?」

確かに、設定ファイルを分離すれば、コードを変更せずに設定を変えられます。やってみましょう。

設定ファイルの形式

シンプルなINI風の形式を使います。=の左側がキー、右側が値です。

1
2
3
app_name = MyApp
version = 1.0.0
debug = 1

この形式なら、Perlの標準機能だけで簡単に読み込めます。

設定ファイルを読み込む処理

まずは、ファイルを読み込む処理を見てみましょう。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
sub load_config ($self, $file) {
    open my $fh, '<', $file or die "Cannot open $file: $!";
    while (my $line = <$fh>) {
        chomp $line;
        next if $line =~ /^\s*$/;     # 空行をスキップ
        next if $line =~ /^\s*#/;     # コメント行をスキップ

        if ($line =~ /^\s*(\w+)\s*=\s*(.+?)\s*$/) {
            my ($key, $value) = ($1, $2);
            $self->set($key, $value);
        }
    }
    close $fh;
}

ポイントを確認しましょう。

  • openでファイルを開く
  • 1行ずつ読み込んで、空行とコメント行(#で始まる行)をスキップ
  • 正規表現でkey = valueの形式を解析
  • setメソッドで値を保存

設定値を動的に保存する

設定ファイルから読み込んだ値を保存するには、ハッシュを使います。

1
2
3
4
5
6
7
8
9
has _settings => (is => 'ro', default => sub { {} });

sub set ($self, $key, $value) {
    $self->_settings->{$key} = $value;
}

sub get ($self, $key) {
    return $self->_settings->{$key};
}

_settingsというプライベートなハッシュに、キーと値のペアを保存します。

Configクラスの実装

それでは、ファイル読み込みに対応したConfigクラスを実装しましょう。

 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
40
use v5.36;
use Moo;

package Config {
    use Moo;

    has _settings => (is => 'ro', default => sub { {} });

    sub load_config ($self, $file) {
        open my $fh, '<', $file or die "Cannot open $file: $!";
        while (my $line = <$fh>) {
            chomp $line;
            next if $line =~ /^\s*$/;     # 空行をスキップ
            next if $line =~ /^\s*#/;     # コメント行をスキップ

            if ($line =~ /^\s*(\w+)\s*=\s*(.+?)\s*$/) {
                my ($key, $value) = ($1, $2);
                $self->set($key, $value);
            }
        }
        close $fh;
    }

    sub set ($self, $key, $value) {
        $self->_settings->{$key} = $value;
    }

    sub get ($self, $key) {
        return $self->_settings->{$key};
    }
};

package main;

my $config = Config->new();
$config->load_config('config.ini');

say "アプリ名: " . $config->get('app_name');
say "バージョン: " . $config->get('version');
say "デバッグモード: " . ($config->get('debug') ? 'ON' : 'OFF');

設定ファイルの用意

設定ファイルconfig.iniを用意します。

1
2
3
4
# アプリケーション設定
app_name = MyApp
version = 1.0.0
debug = 1

実行してみよう

スクリプトを実行すると、設定ファイルから値が読み込まれます。

1
2
3
アプリ名: MyApp
バージョン: 1.0.0
デバッグモード: ON

設定ファイルの値を変更してみましょう。

1
2
3
4
# アプリケーション設定
app_name = AwesomeApp
version = 2.0.0
debug = 0

再度実行すると、変更が反映されます。

1
2
3
アプリ名: AwesomeApp
バージョン: 2.0.0
デバッグモード: OFF

スクリプトを変更せずに、設定を切り替えられるようになりました!

第2回 完成コード

今回の完成コードは以下の通りです。

ファイル構成

1
2
3
.
├── app.pl
└── config.ini

app.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
40
use v5.36;
use Moo;

package Config {
    use Moo;

    has _settings => (is => 'ro', default => sub { {} });

    sub load_config ($self, $file) {
        open my $fh, '<', $file or die "Cannot open $file: $!";
        while (my $line = <$fh>) {
            chomp $line;
            next if $line =~ /^\s*$/;     # 空行をスキップ
            next if $line =~ /^\s*#/;     # コメント行をスキップ

            if ($line =~ /^\s*(\w+)\s*=\s*(.+?)\s*$/) {
                my ($key, $value) = ($1, $2);
                $self->set($key, $value);
            }
        }
        close $fh;
    }

    sub set ($self, $key, $value) {
        $self->_settings->{$key} = $value;
    }

    sub get ($self, $key) {
        return $self->_settings->{$key};
    }
};

package main;

my $config = Config->new();
$config->load_config('config.ini');

say "アプリ名: " . $config->get('app_name');
say "バージョン: " . $config->get('version');
say "デバッグモード: " . ($config->get('debug') ? 'ON' : 'OFF');

config.ini

1
2
3
4
# アプリケーション設定
app_name = MyApp
version = 1.0.0
debug = 1

まとめ

  • INI形式の設定ファイルを読み込むload_configメソッドを実装した
  • 設定値を動的に保存・取得するset/getメソッドを追加した
  • 設定ファイルを変更すれば、コードを変更せずに設定を切り替えられるようになった

次回予告

ミキさんのアプリが大きくなってきました。

「メインのスクリプト以外にも、別のモジュールから設定を使いたいんだけど…」

次回は、複数の場所から設定を使う方法を考えます。でも、ちょっとした問題が発生するかも…?

comments powered by Disqus
Hugo で構築されています。
テーマ StackJimmy によって設計されています。