如何更好地处理配置文件?

时间:2019-05-26 21:42:09

标签: config perl6 raku

在我正在编写的程序包中,我有一个配置模块,如下所示:

use v6.d;
use JSON::Fast;
use PSBot::Tools;

sub EXPORT(--> Hash) {
    my Str $path = do if %*ENV<TESTING> {
        $*REPO.Str.IO.child('META6.json').e
            ?? $*REPO.Str.IO.child('t/config.json').Str         # For when testing using zef
            !! $*REPO.Str.IO.parent.child('t/config.json').Str; # For when testing using prove
    } elsif $*DISTRO.is-win {
        "%*ENV<LOCALAPPDATA>\\PSBot\\config.json"
    } else {
        "$*HOME/.config/PSBot/config.json"
    };

    unless $path.IO.e {
        note "PSBot config at $path does not exist!";
        note "Copy psbot.json.example there and read the README for instructions on how to set up the config file.";
        exit 1;
    }

    with from-json slurp $path -> %config {
        %(
            USERNAME               => %config<username>,
            PASSWORD               => %config<password>,
            AVATAR                 => %config<avatar>,
            HOST                   => %config<host>,
            PORT                   => %config<port>,
            SERVERID               => %config<serverid>,
            COMMAND                => %config<command>,
            ROOMS                  => set(%config<rooms>.map: &to-roomid),
            ADMINS                 => set(%config<admins>.map: &to-id),
            MAX_RECONNECT_ATTEMPTS => %config<max_reconnect_attempts>,
            GIT                    => %config<git>,
            DICTIONARY_API_ID      => %config<dictionary_api_id>,
            DICTIONARY_API_KEY     => %config<dictionary_api_key>,
            YOUTUBE_API_KEY        => %config<youtube_api_key>,
            TRANSLATE_API_KEY      => %config<translate_api_key>
        )
    }
}

每次我对配置文件进行更改时,我都必须删除precomp文件才能显示更改。有没有一种我可以编写这种方式的方法,以便在编译时就不必定义导出内容,因此用户不必这样做?

2 个答案:

答案 0 :(得分:4)

假设我正确理解了您的意图,做到这一点的一种方法是:

  1. 摆脱EXPORT
  2. $path%config的计算结果放入模块的主线
  3. 将您的“常量”声明为诸如

    sub term:<USERNAME> is export { %config<username> }
    

答案 1 :(得分:0)

阅读了你们的评论和@Christoph的回答后,我就此解决了。这就是我想要做的:

use v6.d;
use JSON::Fast;
use PSBot::Tools;
unit module PSBot::Config;

my Str $path = do if %*ENV<TESTING> {
    %?RESOURCES<test/config.json>.Str
} elsif $*DISTRO.is-win {
    Qh[%*ENV<LOCALAPPDATA>\PSBot\config.json]
} else {
    "$*HOME/.config/PSBot/config.json"
};

unless $path.IO.e {
    note "PSBot config at $path does not exist!";
    note "Copy config.json.example there and read the README for instructions on how to set up the config file.";
    exit 1;
}

my %config = from-json slurp $path;

sub term:<USERNAME>               is export  { %config<username>                   }
sub term:<PASSWORD>               is export  { %config<password>                   }
sub term:<AVATAR>                 is export  { %config<avatar>                     }
sub term:<HOST>                   is export  { %config<host>                       }
sub term:<PORT>                   is export  { %config<port>                       }
sub term:<SERVERID>               is export  { %config<serverid>                   }
sub term:<COMMAND>                is export  { %config<command>                    }
sub term:<ROOMS>                  is export  { set(%config<rooms>.map: &to-roomid) }
sub term:<ADMINS>                 is export  { set(%config<admins>.map: &to-id)    }
sub term:<MAX_RECONNECT_ATTEMPTS> is export  { %config<max_reconnect_attempts>     }
sub term:<GIT>                    is export  { %config<git>                        }
sub term:<DICTIONARY_API_ID>      is export  { %config<dictionary_api_id>          }
sub term:<DICTIONARY_API_KEY>     is export  { %config<dictionary_api_key>         }
sub term:<YOUTUBE_API_KEY>        is export  { %config<youtube_api_key>            }
sub term:<TRANSLATE_API_KEY>      is export  { %config<translate_api_key>          }