如何分解此Erlang sys.config?

如何分解此Erlang sys.config?,erlang,beagleboneblack,beagleboard,slack,Erlang,Beagleboneblack,Beagleboard,Slack,给定如下所示的Erlang: [ {mousetrap, [ {slack_user, "mousetrap"}, {slack_channel, "#mousetrap"}, {slack_token, "<slack token here>"}, {pins_export_file, "/sys/class/gpio/export"}, {pins_root_directory, "/sys/

给定如下所示的Erlang:

[
    {mousetrap, [
        {slack_user, "mousetrap"},
        {slack_channel, "#mousetrap"},
        {slack_token, "<slack token here>"},
        {pins_export_file, "/sys/class/gpio/export"},
        {pins_root_directory, "/sys/class/gpio/gpio"},
        {pins, [
                {gpio0, 30, "1 (over workshop door)"},
                {gpio0, 31, "2 (by basement freezer)"},
                {gpio1, 16, "3 (in the kitchen pantry)"},
                {gpio0, 5, "4 (Not yet wired)"}
        ]},
        {quiet_minutes, 5},
        {pin_check_interval_seconds, 1}
    ]}
].
application:set_env(nonexisting, foo, bar).
application:set_env(anotherphantom, bat, baz).
使用

{ok, PinsRootDirectory} = application:get_env(pin_server, pins_root_directory),
编辑:

我只是想澄清为什么我认为这很重要。pin_服务器和通知_库试图遵守的组件。但是当pin_服务器调用
应用程序:get_env(mousetrap,pins_root_目录)
时,它打破了SRP的壁垒,因为它创建了对组件的依赖,而该组件不应该具有依赖性。也就是说,在捕鼠器应用程序上。现在,如果不更改代码,它就不能在其他应用程序中重用。通知库也是如此。pin_服务器可能适用于任何想要查询BBB pin的应用程序。通知库在任何希望发送延迟通知的应用程序中都很有用。也不应该引用捕鼠器应用程序,因为他们不应该对该应用程序有任何“知识”

编辑:


根据@michael的指导,我首先向位于的一个单独的OTP库发出松弛通知。

由于Erlang不以任何方式控制节点内应用程序和环境之间的访问(任何应用程序都可以访问任何其他应用程序环境),因此我不确定这种细微的使用变化究竟能带来什么好处。。。事实上,如果pin_服务器显然是捕鼠器应用程序的一部分是合乎逻辑的,那么我认为您不应该尝试这样做;按照预期使用的方式使用系统

尽管如此,由于不存在访问控制,您可以为不存在的应用程序设置如下环境:

[
    {mousetrap, [
        {slack_user, "mousetrap"},
        {slack_channel, "#mousetrap"},
        {slack_token, "<slack token here>"},
        {pins_export_file, "/sys/class/gpio/export"},
        {pins_root_directory, "/sys/class/gpio/gpio"},
        {pins, [
                {gpio0, 30, "1 (over workshop door)"},
                {gpio0, 31, "2 (by basement freezer)"},
                {gpio1, 16, "3 (in the kitchen pantry)"},
                {gpio0, 5, "4 (Not yet wired)"}
        ]},
        {quiet_minutes, 5},
        {pin_check_interval_seconds, 1}
    ]}
].
application:set_env(nonexisting, foo, bar).
application:set_env(anotherphantom, bat, baz).
但是,如果在sys.config中使用不存在的应用程序运行节点,则不会加载这些应用程序的配置

你能做的黑客 您可以让您的应用程序在启动顶级主管之前开始读取您的环境并设置不真正存在的pin_服务器应用程序的环境,并从mousetrap应用程序中取消设置环境。这会达到你想要的,但是

尽管这是可能的,但我不建议这样做,因为很明显,如果您盗取的名称的应用程序后来被引入,发布经理将不会发现冲突

更好的替代方案(应用程序和包含的应用程序) 另一种方法是将pin_服务器作为应用程序

如果唯一的障碍是,除了在捕鼠器应用程序的上下文中,建议的pinu服务器应用程序实际上没有任何意义,那么您可以将其作为“包含的应用程序”。包含的应用程序具有自己的应用程序文件,与普通(主)应用程序非常相似,但它们是在主应用程序的监督树中启动的(请参阅),如果您不介意创建额外的应用程序,它们将立即允许您更改所需的用途

图书馆应用
同样,它是一个应用程序,我认为这在您的情况下可能不合适,但是,还有一个“库应用程序”,它是一个没有服务器的应用程序(您不需要实现应用程序回调模块,它只是您的模块、API和环境的逻辑分组)。如果创建的应用程序文件没有
mod
条目,则它将成为库应用程序。我认为它不合适的原因可能是
pin_server
听起来像一个服务器,因此应该受到监督,但这也会允许您更改所需的用途。

我看到的最佳解决方案是要求任何使用
pin\u server
notification\u library
的应用程序读取环境变量,并在初始化时将其注入这些组件。

听起来像是在提倡我所称的打断我的回答。我真的只是为了完整性而列出了这个选项,因为它直接允许您在不改变结构的情况下完成您想要的。。。然而,考虑到您对SRP合规性的额外编辑,我想说的比以往任何时候都多,正确的答案是将pin_服务器和通知_库作为单独的(主要)应用程序。你已经澄清了它们是独立的,所以如果你让它们成为任何Erlang开发者都会期待和理解的自己的应用程序,那么你就可以编写sys.config,而不会造成任何混乱。它们单独使用是没有用的。它们只在应用程序中有用。另外,我的建议与你的建议不同,我会注入设置,而不是设置另一个环境变量。这一点很好。例如,像iNet一样,作为一个Erlang应用程序,在独立应用程序中非常有用。是的,或者stdlib、内核、公钥、编译器。。。可能只有一小部分Erang应用程序是那些收集并使用其他应用程序的应用程序,实际上构成了普通人认为的应用程序。如果pin_服务器可能适用于任何应用程序,那么我实际上会说,在Erlang应用程序/节点/发布模式下,我会说它必须是Erlang应用程序或Erlang应用程序的一部分,以及您喜欢的任何其他应用程序,只要添加不会破坏您的SRP合规性。