Including function in configuration file

Previous Topic Next Topic
 
classic Classic list List threaded Threaded
10 messages Options
Reply | Threaded
Open this post in threaded view
|

Including function in configuration file

Code Wiget
Hi,

Say I want to include a function as an environment variable

I can do this:
 application:set_env(App, Key, NewValue). 

Is there any way to do this from a .config file? Such as:
 [{my_app, [ {my_fun, #Fun<my_app.12.39472874>}]}]

— this gives a compile error. 

_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|

Re: Including function in configuration file

Roger Lipscombe-2
No. The '#Fun<stuff>' isn't really a thing; it's just how the function
is printed in the shell.

If you want to reference a function in a config file, it needs to be a
real function, and you need to reference it by name. If you don't know
which module it's implemented in, you'll need to specify that in your
config file as well. Something like this:

[
  {my_app,
    [
      {my_magic_func, {the_module, func_name}}
    ]}
].

Then, in your code that reads the configuration value, you need to
explicitly invoke the function with erlang:apply...

    {ok, {Module, Func}} = application:get_env(my_app, my_magic_func),
    erlang:apply(Module, Func, [Arg1, Arg2]) % calls
the_module:func_name(Arg1, Arg2)



On 9 July 2018 at 19:57, Code Wiget <[hidden email]> wrote:

> Hi,
>
> Say I want to include a function as an environment variable
>
> I can do this:
>  application:set_env(App, Key, NewValue).
>
> Is there any way to do this from a .config file? Such as:
>  [{my_app, [ {my_fun, #Fun<my_app.12.39472874>}]}]
>
> — this gives a compile error.
>
> _______________________________________________
> erlang-questions mailing list
> [hidden email]
> http://erlang.org/mailman/listinfo/erlang-questions
>
_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|

Re: Including function in configuration file

Code Wiget
So, for the ssl options such as:
{reuse_session, fun()} {next_protocols_advertised, [binary()]}

{user_lookup_fun, {fun(), term()}}, {psk_identity, string()}, {srp_identity, {string(), string()}}

You have to manually set the configuration parameters, and cannot set them in a configuration file?


On Jul 9, 2018, 3:15 PM -0400, Roger Lipscombe <[hidden email]>, wrote:
No. The '#Fun<stuff>' isn't really a thing; it's just how the function
is printed in the shell.

If you want to reference a function in a config file, it needs to be a
real function, and you need to reference it by name. If you don't know
which module it's implemented in, you'll need to specify that in your
config file as well. Something like this:

[
{my_app,
[
{my_magic_func, {the_module, func_name}}
]}
].

Then, in your code that reads the configuration value, you need to
explicitly invoke the function with erlang:apply...

{ok, {Module, Func}} = application:get_env(my_app, my_magic_func),
erlang:apply(Module, Func, [Arg1, Arg2]) % calls
the_module:func_name(Arg1, Arg2)



On 9 July 2018 at 19:57, Code Wiget <[hidden email]> wrote:
Hi,

Say I want to include a function as an environment variable

I can do this:
 application:set_env(App, Key, NewValue).

Is there any way to do this from a .config file? Such as:
 [{my_app, [ {my_fun, #Fun<my_app.12.39472874>}]}]

— this gives a compile error.

_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions


_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|

Re: Including function in configuration file

Michael Truog
On 07/09/2018 12:16 PM, Code Wiget wrote:
So, for the ssl options such as:
{reuse_session, fun()} {next_protocols_advertised, [binary()]}

{user_lookup_fun, {fun(), term()}}, {psk_identity, string()}, {srp_identity, {string(), string()}}

You have to manually set the configuration parameters, and cannot set them in a configuration file?

I use {Module :: atom(), Function :: atom()} to represent a function for configuration because the arity can be inferred from the configuration value.  I also use {{Module :: atom(), Function :: atom()}} to allow an arity 0 function to return a function, to allow a closure to be used.  The source code I use for this is at https://github.com/CloudI/CloudI/blob/95e76d30ff655562682132f9ec04b07075ce055d/src/lib/cloudi_core/src/cloudi_args_type.erl#L53-L136

Best Regards,
Michael

_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|

Re: Including function in configuration file

Roger Lipscombe-2
In reply to this post by Code Wiget
On 9 July 2018 at 20:16, Code Wiget <[hidden email]> wrote:
> So, for the ssl options such as:
> {reuse_session, fun()} {next_protocols_advertised, [binary()]}
>
> {user_lookup_fun, {fun(), term()}}, {psk_identity, string()}, {srp_identity,
> {string(), string()}}
>
> You have to manually set the configuration parameters, and cannot set them
> in a configuration file?

Yes, but you _can_ come up with some other way to specify them in the
configuration file, and then convert that to an actual function before
you pass it to SSL options.

We have something like this in our code:

convert_ssl_opt({verify_opts, VerifyOpts}, Acc) ->
    Opt = {verify_fun, {fun do_verify/3, VerifyOpts}},
    [Opt | Acc];

...which converts our invented 'verify_opts' into the required
'verify_fun', by using a do_verify function in the module that does
the conversion.
_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|

Re: Including function in configuration file

Oliver Korpilla
Couldn't you store the code of the compiled module containing the function as binary in an list or binary literal, read it in and call it?

Oliver

On July 9, 2018 9:50:14 PM CEST, Roger Lipscombe <[hidden email]> wrote:
On 9 July 2018 at 20:16, Code Wiget <[hidden email]> wrote:
So, for the ssl options such as:
{reuse_session, fun()} {next_protocols_advertised, [binary()]}

{user_lookup_fun, {fun(), term()}}, {psk_identity, string()}, {srp_identity,
{string(), string()}}

You have to manually set the configuration parameters, and cannot set them
in a configuration file?

Yes, but you _can_ come up with some other way to specify them in the
configuration file, and then convert that to an actual function before
you pass it to SSL options.

We have something like this in our code:

convert_ssl_opt({verify_opts, VerifyOpts}, Acc) ->
Opt = {verify_fun, {fun do_verify/3, VerifyOpts}},
[Opt | Acc];

...which converts our invented 'verify_opts' into the required
'verify_fun', by using a do_verify function in the module that does
the conversion.


erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions

--
Sent from my Android device with K-9 Mail. Please excuse my brevity.
_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|

Re: Including function in configuration file

Grzegorz Junka
In reply to this post by Code Wiget

On 09/07/2018 18:57, Code Wiget wrote:
Hi,

Say I want to include a function as an environment variable

I can do this:
 application:set_env(App, Key, NewValue). 

Is there any way to do this from a .config file? Such as:
 [{my_app, [ {my_fun, #Fun<my_app.12.39472874>}]}]

— this gives a compile error. 


If you defined a function in the config how would you verify if it's correct? You will need to compile it first. In Erlang you can compile any arbitrary file directly in your application, see this for an example:
https://github.com/yoonka/migresia/blob/master/src/migresia_migrations.erl#L193

So, theoretically, you could define a function as a string or binary in your config, then in the application write this to a file, compile into a binary (i.e. without writing the compiled module to a file) and then load directly from that binary and execute. But that sounds a bit weird and it's probably not what you need. Maybe you can just tell us what are you trying to accomplish?

Best
Greg

_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|

Re: Including function in configuration file

Code Wiget
Hi Greg,

I sent this earlier, but it must not have gone through to everyone. I am trying to use special ssl options, for example:

{reuse_session, fun()} {next_protocols_advertised, [binary()]}

And

{user_lookup_fun, {fun(), term()}}, {psk_identity, string()}, {srp_identity, {string(), string()}}


Which require functions as input. This means that I can’t use a configuration file. Other members have suggested that I iterate over my environment variables and replace the “fun()” with a function at run time, rather than using a .config file. I think this is the most straightforward approach.


On Jul 9, 2018, 5:04 PM -0400, Grzegorz Junka <[hidden email]>, wrote:

On 09/07/2018 18:57, Code Wiget wrote:
Hi,

Say I want to include a function as an environment variable

I can do this:
 application:set_env(App, Key, NewValue). 

Is there any way to do this from a .config file? Such as:
 [{my_app, [ {my_fun, #Fun<my_app.12.39472874>}]}]

— this gives a compile error. 


If you defined a function in the config how would you verify if it's correct? You will need to compile it first. In Erlang you can compile any arbitrary file directly in your application, see this for an example:
https://github.com/yoonka/migresia/blob/master/src/migresia_migrations.erl#L193

So, theoretically, you could define a function as a string or binary in your config, then in the application write this to a file, compile into a binary (i.e. without writing the compiled module to a file) and then load directly from that binary and execute. But that sounds a bit weird and it's probably not what you need. Maybe you can just tell us what are you trying to accomplish?

Best
Greg

_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|

Re: Including function in configuration file

Grzegorz Junka

But you can specify here a function that you have written somewhere, then in that function read the configuration parameters that you want to use? For Erlang only the signature matters, i.e. that the function accepts the arguments  that the documentation says it should accept and that it returns the value it should return (e.g. boolean()). It's entirely up to you what the function does inside, e.g. it can execute some Java code, read a config file, or randomly return true/false.

What I was more interested is why do you think you need to specify anything in configuration related to those functions, why they can't be just static functions implemented somewhere.

Greg


On 09/07/2018 21:06, Code Wiget wrote:
Hi Greg,

I sent this earlier, but it must not have gone through to everyone. I am trying to use special ssl options, for example:

{reuse_session, fun()} {next_protocols_advertised, [binary()]}

And

{user_lookup_fun, {fun(), term()}}, {psk_identity, string()}, {srp_identity, {string(), string()}}


Which require functions as input. This means that I can’t use a configuration file. Other members have suggested that I iterate over my environment variables and replace the “fun()” with a function at run time, rather than using a .config file. I think this is the most straightforward approach.


On Jul 9, 2018, 5:04 PM -0400, Grzegorz Junka [hidden email], wrote:

On 09/07/2018 18:57, Code Wiget wrote:
Hi,

Say I want to include a function as an environment variable

I can do this:
 application:set_env(App, Key, NewValue). 

Is there any way to do this from a .config file? Such as:
 [{my_app, [ {my_fun, #Fun<my_app.12.39472874>}]}]

— this gives a compile error. 


If you defined a function in the config how would you verify if it's correct? You will need to compile it first. In Erlang you can compile any arbitrary file directly in your application, see this for an example:
https://github.com/yoonka/migresia/blob/master/src/migresia_migrations.erl#L193

So, theoretically, you could define a function as a string or binary in your config, then in the application write this to a file, compile into a binary (i.e. without writing the compiled module to a file) and then load directly from that binary and execute. But that sounds a bit weird and it's probably not what you need. Maybe you can just tell us what are you trying to accomplish?

Best
Greg


_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions
Reply | Threaded
Open this post in threaded view
|

Re: Including function in configuration file

Raimo Niskanen-2
In reply to this post by Roger Lipscombe-2
On Mon, Jul 09, 2018 at 08:50:14PM +0100, Roger Lipscombe wrote:

> On 9 July 2018 at 20:16, Code Wiget <[hidden email]> wrote:
> > So, for the ssl options such as:
> > {reuse_session, fun()} {next_protocols_advertised, [binary()]}
> >
> > {user_lookup_fun, {fun(), term()}}, {psk_identity, string()}, {srp_identity,
> > {string(), string()}}
> >
> > You have to manually set the configuration parameters, and cannot set them
> > in a configuration file?
>
> Yes, but you _can_ come up with some other way to specify them in the
> configuration file, and then convert that to an actual function before
> you pass it to SSL options.
>
> We have something like this in our code:
>
> convert_ssl_opt({verify_opts, VerifyOpts}, Acc) ->
>     Opt = {verify_fun, {fun do_verify/3, VerifyOpts}},
>     [Opt | Acc];
>
> ...which converts our invented 'verify_opts' into the required
> 'verify_fun', by using a do_verify function in the module that does
> the conversion.

I think that for this option it actuall works write an inline fun as in:
    Opt =
      {verify_fun,
       {fun (A, B, C) -> result end,
        VerifyOpts}}

(If this works) it creates a shell fun that is calls a precompiled fun in
the shell module that feeds the abstract code to the interpreter, so it is
much slower than a compiled fun.  But I think it works and suppose we will
not remove this (mis)feature.

--

/ Raimo Niskanen, Erlang/OTP, Ericsson AB
_______________________________________________
erlang-questions mailing list
[hidden email]
http://erlang.org/mailman/listinfo/erlang-questions