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

Kai*_*epi 7 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>
        )
    }
}
Run Code Online (Sandbox Code Playgroud)

每次更改配置文件时,都必须删除precomp文件以使更改出现。有没有一种方法可以编写此代码,以便在编译时不定义导出内容,因此用户不必这样做?

Chr*_*oph 4

假设我正确理解你的意图,一种方法是这样的:

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

    sub term:<USERNAME> is export { %config<username> }
    
    Run Code Online (Sandbox Code Playgroud)

  • 仅当您仅在编译单元中使用此模块一次时,这才有效。如果您想要更灵活,您可以基于以下代码实现一些内容:`sub EXPORT($path = "something") { { PATH =&gt; $path } }`,然后使用位置参数`加载模块use Foo &lt;bar&gt;”(这会将 `PATH` 设置为该范围内的“bar”),或者使用 `use Foo` 加载模块(在另一个范围内),在这种情况下,`PATH` 将是该范围内的“某物”范围。 (2认同)