Are Erlang -callbacks to be invoked only through MFA functions (apply/3, spawn/3, …)? (Custom Behaviors HOWTO)










0















That's my suspicion as this simple code



-module(simple_server).
-export( [sayHello/0] ).

-callback say(Num :: term()) -> term().

sayHello() ->
io:fwrite( "Hello 1: ~pn", [ say(1) ]) ,
io:fwrite( "Hello 2: ~pn", [ say(2) ]) .


fails to be compiled:



$ erlc simple_server.erl
simple_server.erl:7: function say/1 undefined
simple_server.erl:8: function say/1 undefined


If that is the case, then this is not explicitly commented elsewhere:
official docs, "learn erlang", this answer.










share|improve this question
























  • This question stackoverflow.com/questions/32336854/… exposes the same problem without clearly showing how callbacks are supposed to be called.

    – cibercitizen1
    Nov 14 '18 at 9:58












  • In the accepted answer, the callback function is called as CBM:fn(A).

    – legoscia
    Nov 14 '18 at 9:59











  • @legoscia Yes. Then, the name of the module implementing the callback must be supplied to the generic code.

    – cibercitizen1
    Nov 14 '18 at 10:02












  • @legoscia If you are sure about the ways a generic module can call a callback (to be provided in the future) you could write an answer here to be accepted. Thanks in advance.

    – cibercitizen1
    Nov 14 '18 at 10:06
















0















That's my suspicion as this simple code



-module(simple_server).
-export( [sayHello/0] ).

-callback say(Num :: term()) -> term().

sayHello() ->
io:fwrite( "Hello 1: ~pn", [ say(1) ]) ,
io:fwrite( "Hello 2: ~pn", [ say(2) ]) .


fails to be compiled:



$ erlc simple_server.erl
simple_server.erl:7: function say/1 undefined
simple_server.erl:8: function say/1 undefined


If that is the case, then this is not explicitly commented elsewhere:
official docs, "learn erlang", this answer.










share|improve this question
























  • This question stackoverflow.com/questions/32336854/… exposes the same problem without clearly showing how callbacks are supposed to be called.

    – cibercitizen1
    Nov 14 '18 at 9:58












  • In the accepted answer, the callback function is called as CBM:fn(A).

    – legoscia
    Nov 14 '18 at 9:59











  • @legoscia Yes. Then, the name of the module implementing the callback must be supplied to the generic code.

    – cibercitizen1
    Nov 14 '18 at 10:02












  • @legoscia If you are sure about the ways a generic module can call a callback (to be provided in the future) you could write an answer here to be accepted. Thanks in advance.

    – cibercitizen1
    Nov 14 '18 at 10:06














0












0








0


1






That's my suspicion as this simple code



-module(simple_server).
-export( [sayHello/0] ).

-callback say(Num :: term()) -> term().

sayHello() ->
io:fwrite( "Hello 1: ~pn", [ say(1) ]) ,
io:fwrite( "Hello 2: ~pn", [ say(2) ]) .


fails to be compiled:



$ erlc simple_server.erl
simple_server.erl:7: function say/1 undefined
simple_server.erl:8: function say/1 undefined


If that is the case, then this is not explicitly commented elsewhere:
official docs, "learn erlang", this answer.










share|improve this question
















That's my suspicion as this simple code



-module(simple_server).
-export( [sayHello/0] ).

-callback say(Num :: term()) -> term().

sayHello() ->
io:fwrite( "Hello 1: ~pn", [ say(1) ]) ,
io:fwrite( "Hello 2: ~pn", [ say(2) ]) .


fails to be compiled:



$ erlc simple_server.erl
simple_server.erl:7: function say/1 undefined
simple_server.erl:8: function say/1 undefined


If that is the case, then this is not explicitly commented elsewhere:
official docs, "learn erlang", this answer.







callback erlang otp






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 14 '18 at 12:01







cibercitizen1

















asked Nov 14 '18 at 9:35









cibercitizen1cibercitizen1

12.2k135483




12.2k135483












  • This question stackoverflow.com/questions/32336854/… exposes the same problem without clearly showing how callbacks are supposed to be called.

    – cibercitizen1
    Nov 14 '18 at 9:58












  • In the accepted answer, the callback function is called as CBM:fn(A).

    – legoscia
    Nov 14 '18 at 9:59











  • @legoscia Yes. Then, the name of the module implementing the callback must be supplied to the generic code.

    – cibercitizen1
    Nov 14 '18 at 10:02












  • @legoscia If you are sure about the ways a generic module can call a callback (to be provided in the future) you could write an answer here to be accepted. Thanks in advance.

    – cibercitizen1
    Nov 14 '18 at 10:06


















  • This question stackoverflow.com/questions/32336854/… exposes the same problem without clearly showing how callbacks are supposed to be called.

    – cibercitizen1
    Nov 14 '18 at 9:58












  • In the accepted answer, the callback function is called as CBM:fn(A).

    – legoscia
    Nov 14 '18 at 9:59











  • @legoscia Yes. Then, the name of the module implementing the callback must be supplied to the generic code.

    – cibercitizen1
    Nov 14 '18 at 10:02












  • @legoscia If you are sure about the ways a generic module can call a callback (to be provided in the future) you could write an answer here to be accepted. Thanks in advance.

    – cibercitizen1
    Nov 14 '18 at 10:06

















This question stackoverflow.com/questions/32336854/… exposes the same problem without clearly showing how callbacks are supposed to be called.

– cibercitizen1
Nov 14 '18 at 9:58






This question stackoverflow.com/questions/32336854/… exposes the same problem without clearly showing how callbacks are supposed to be called.

– cibercitizen1
Nov 14 '18 at 9:58














In the accepted answer, the callback function is called as CBM:fn(A).

– legoscia
Nov 14 '18 at 9:59





In the accepted answer, the callback function is called as CBM:fn(A).

– legoscia
Nov 14 '18 at 9:59













@legoscia Yes. Then, the name of the module implementing the callback must be supplied to the generic code.

– cibercitizen1
Nov 14 '18 at 10:02






@legoscia Yes. Then, the name of the module implementing the callback must be supplied to the generic code.

– cibercitizen1
Nov 14 '18 at 10:02














@legoscia If you are sure about the ways a generic module can call a callback (to be provided in the future) you could write an answer here to be accepted. Thanks in advance.

– cibercitizen1
Nov 14 '18 at 10:06






@legoscia If you are sure about the ways a generic module can call a callback (to be provided in the future) you could write an answer here to be accepted. Thanks in advance.

– cibercitizen1
Nov 14 '18 at 10:06













2 Answers
2






active

oldest

votes


















1














You need to provide the name of the callback module, which can be done through apply and spawn, but you can also make a simple call using a variable as the module name, e.g. CallbackModule:say(1).



So you could do either:



sayHello(CallbackModule) ->
io:fwrite( "Hello 1: ~pn", [ CallbackModule:say(1) ]) ,
io:fwrite( "Hello 2: ~pn", [ CallbackModule:say(2) ]) .


or



sayHello(CallbackModule) ->
io:fwrite( "Hello 1: ~pn", [ apply(CallbackModule, say, [1]) ]) ,
io:fwrite( "Hello 2: ~pn", [ apply(CallbackModule, say, [2]) ]) .


Those two versions are equivalent.



Let's create a callback module implementing the simple_server behaviour:



-module(my_callback).
-behaviour(simple_server).
-export([say/1]).

say(N) ->
N, is, the, loneliest, number.


Now we can call simple_server:sayHello with the module name as the argument:



> simple_server:sayHello(my_callback).
Hello 1: 1,is,the,loneliest,number
Hello 2: 2,is,the,loneliest,number





share|improve this answer


















  • 1





    Thanks a lot! I've also prepared a simple explanatory example, including compile orders, which are very important (-pa flag).

    – cibercitizen1
    Nov 14 '18 at 11:30


















1














HOWTO Erlang Custom Behaviors (template method pattern).



-1. Write a generic module. Here, an algorithm is defined, but some steps (callback functions in Erlang nomenclature) are left for a future specific definition.



%% generic.erl 
-module(generic).
-export( [sayHello/1] ).

-callback say(Num :: term()) -> term(). %% future definition

%% generic algorithm: needs the reference to the provider module
sayHello(ProviderModule) ->
io:fwrite( "Hello 1: ~pn", [ ProviderModule:say(1) ]) ,
io:fwrite( "Hello 2: ~pn", [ ProviderModule:say(2) ]) .


-2. Compile generic.erl



erlc generic.erl


-(3.) Try to write a provider (callback) module



%% callbacks1.erl (fails to implement say/1 callback)
-module( callbacks1 ).
-behaviour( generic ).


-(4.) Compile callbacks1.erl: use -pa . to say where generic.beam is. (Therefore, the expected warning about say/1 is issued).



erlc -pa . callbacks1.erl
callbacks1.erl:2: Warning: undefined callback function say/1 (behaviour 'generic')


(Note: If -pa is not given, you'll got this: "callbacks1.erl:2: Warning: behaviour generic undefined")



-3. Write a correct provider (callback) module.



%% callbacks2.erl
-module( callbacks2 ).
-behaviour( generic ).

-export( [say/1] ).

say(1) -> "good morning";
say(2) -> "bon jour";
say(_) -> "hi".


-4. Compile it



erlc -pa . callbacks2.erl


(Ok now).



-5. Write a main.erl to gather generic module with callback module.



%% main.erl
-module( main ).
-export( [main/0] ).

main() ->
%% call the generic algorithm telling it what callback module to use
generic:sayHello( callbacks2 )
. % ()


-6. Compile and run main



erlc main.erl
erl -noshell -s main main -s init stop


We get:



Hello 1: "good morning"
Hello 2: "bon jour"





share|improve this answer
























    Your Answer






    StackExchange.ifUsing("editor", function ()
    StackExchange.using("externalEditor", function ()
    StackExchange.using("snippets", function ()
    StackExchange.snippets.init();
    );
    );
    , "code-snippets");

    StackExchange.ready(function()
    var channelOptions =
    tags: "".split(" "),
    id: "1"
    ;
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function()
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled)
    StackExchange.using("snippets", function()
    createEditor();
    );

    else
    createEditor();

    );

    function createEditor()
    StackExchange.prepareEditor(
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader:
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    ,
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    );



    );













    draft saved

    draft discarded


















    StackExchange.ready(
    function ()
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53296965%2fare-erlang-callbacks-to-be-invoked-only-through-mfa-functions-apply-3-spawn-3%23new-answer', 'question_page');

    );

    Post as a guest















    Required, but never shown

























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    1














    You need to provide the name of the callback module, which can be done through apply and spawn, but you can also make a simple call using a variable as the module name, e.g. CallbackModule:say(1).



    So you could do either:



    sayHello(CallbackModule) ->
    io:fwrite( "Hello 1: ~pn", [ CallbackModule:say(1) ]) ,
    io:fwrite( "Hello 2: ~pn", [ CallbackModule:say(2) ]) .


    or



    sayHello(CallbackModule) ->
    io:fwrite( "Hello 1: ~pn", [ apply(CallbackModule, say, [1]) ]) ,
    io:fwrite( "Hello 2: ~pn", [ apply(CallbackModule, say, [2]) ]) .


    Those two versions are equivalent.



    Let's create a callback module implementing the simple_server behaviour:



    -module(my_callback).
    -behaviour(simple_server).
    -export([say/1]).

    say(N) ->
    N, is, the, loneliest, number.


    Now we can call simple_server:sayHello with the module name as the argument:



    > simple_server:sayHello(my_callback).
    Hello 1: 1,is,the,loneliest,number
    Hello 2: 2,is,the,loneliest,number





    share|improve this answer


















    • 1





      Thanks a lot! I've also prepared a simple explanatory example, including compile orders, which are very important (-pa flag).

      – cibercitizen1
      Nov 14 '18 at 11:30















    1














    You need to provide the name of the callback module, which can be done through apply and spawn, but you can also make a simple call using a variable as the module name, e.g. CallbackModule:say(1).



    So you could do either:



    sayHello(CallbackModule) ->
    io:fwrite( "Hello 1: ~pn", [ CallbackModule:say(1) ]) ,
    io:fwrite( "Hello 2: ~pn", [ CallbackModule:say(2) ]) .


    or



    sayHello(CallbackModule) ->
    io:fwrite( "Hello 1: ~pn", [ apply(CallbackModule, say, [1]) ]) ,
    io:fwrite( "Hello 2: ~pn", [ apply(CallbackModule, say, [2]) ]) .


    Those two versions are equivalent.



    Let's create a callback module implementing the simple_server behaviour:



    -module(my_callback).
    -behaviour(simple_server).
    -export([say/1]).

    say(N) ->
    N, is, the, loneliest, number.


    Now we can call simple_server:sayHello with the module name as the argument:



    > simple_server:sayHello(my_callback).
    Hello 1: 1,is,the,loneliest,number
    Hello 2: 2,is,the,loneliest,number





    share|improve this answer


















    • 1





      Thanks a lot! I've also prepared a simple explanatory example, including compile orders, which are very important (-pa flag).

      – cibercitizen1
      Nov 14 '18 at 11:30













    1












    1








    1







    You need to provide the name of the callback module, which can be done through apply and spawn, but you can also make a simple call using a variable as the module name, e.g. CallbackModule:say(1).



    So you could do either:



    sayHello(CallbackModule) ->
    io:fwrite( "Hello 1: ~pn", [ CallbackModule:say(1) ]) ,
    io:fwrite( "Hello 2: ~pn", [ CallbackModule:say(2) ]) .


    or



    sayHello(CallbackModule) ->
    io:fwrite( "Hello 1: ~pn", [ apply(CallbackModule, say, [1]) ]) ,
    io:fwrite( "Hello 2: ~pn", [ apply(CallbackModule, say, [2]) ]) .


    Those two versions are equivalent.



    Let's create a callback module implementing the simple_server behaviour:



    -module(my_callback).
    -behaviour(simple_server).
    -export([say/1]).

    say(N) ->
    N, is, the, loneliest, number.


    Now we can call simple_server:sayHello with the module name as the argument:



    > simple_server:sayHello(my_callback).
    Hello 1: 1,is,the,loneliest,number
    Hello 2: 2,is,the,loneliest,number





    share|improve this answer













    You need to provide the name of the callback module, which can be done through apply and spawn, but you can also make a simple call using a variable as the module name, e.g. CallbackModule:say(1).



    So you could do either:



    sayHello(CallbackModule) ->
    io:fwrite( "Hello 1: ~pn", [ CallbackModule:say(1) ]) ,
    io:fwrite( "Hello 2: ~pn", [ CallbackModule:say(2) ]) .


    or



    sayHello(CallbackModule) ->
    io:fwrite( "Hello 1: ~pn", [ apply(CallbackModule, say, [1]) ]) ,
    io:fwrite( "Hello 2: ~pn", [ apply(CallbackModule, say, [2]) ]) .


    Those two versions are equivalent.



    Let's create a callback module implementing the simple_server behaviour:



    -module(my_callback).
    -behaviour(simple_server).
    -export([say/1]).

    say(N) ->
    N, is, the, loneliest, number.


    Now we can call simple_server:sayHello with the module name as the argument:



    > simple_server:sayHello(my_callback).
    Hello 1: 1,is,the,loneliest,number
    Hello 2: 2,is,the,loneliest,number






    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered Nov 14 '18 at 11:14









    legoscialegoscia

    28.9k1181111




    28.9k1181111







    • 1





      Thanks a lot! I've also prepared a simple explanatory example, including compile orders, which are very important (-pa flag).

      – cibercitizen1
      Nov 14 '18 at 11:30












    • 1





      Thanks a lot! I've also prepared a simple explanatory example, including compile orders, which are very important (-pa flag).

      – cibercitizen1
      Nov 14 '18 at 11:30







    1




    1





    Thanks a lot! I've also prepared a simple explanatory example, including compile orders, which are very important (-pa flag).

    – cibercitizen1
    Nov 14 '18 at 11:30





    Thanks a lot! I've also prepared a simple explanatory example, including compile orders, which are very important (-pa flag).

    – cibercitizen1
    Nov 14 '18 at 11:30













    1














    HOWTO Erlang Custom Behaviors (template method pattern).



    -1. Write a generic module. Here, an algorithm is defined, but some steps (callback functions in Erlang nomenclature) are left for a future specific definition.



    %% generic.erl 
    -module(generic).
    -export( [sayHello/1] ).

    -callback say(Num :: term()) -> term(). %% future definition

    %% generic algorithm: needs the reference to the provider module
    sayHello(ProviderModule) ->
    io:fwrite( "Hello 1: ~pn", [ ProviderModule:say(1) ]) ,
    io:fwrite( "Hello 2: ~pn", [ ProviderModule:say(2) ]) .


    -2. Compile generic.erl



    erlc generic.erl


    -(3.) Try to write a provider (callback) module



    %% callbacks1.erl (fails to implement say/1 callback)
    -module( callbacks1 ).
    -behaviour( generic ).


    -(4.) Compile callbacks1.erl: use -pa . to say where generic.beam is. (Therefore, the expected warning about say/1 is issued).



    erlc -pa . callbacks1.erl
    callbacks1.erl:2: Warning: undefined callback function say/1 (behaviour 'generic')


    (Note: If -pa is not given, you'll got this: "callbacks1.erl:2: Warning: behaviour generic undefined")



    -3. Write a correct provider (callback) module.



    %% callbacks2.erl
    -module( callbacks2 ).
    -behaviour( generic ).

    -export( [say/1] ).

    say(1) -> "good morning";
    say(2) -> "bon jour";
    say(_) -> "hi".


    -4. Compile it



    erlc -pa . callbacks2.erl


    (Ok now).



    -5. Write a main.erl to gather generic module with callback module.



    %% main.erl
    -module( main ).
    -export( [main/0] ).

    main() ->
    %% call the generic algorithm telling it what callback module to use
    generic:sayHello( callbacks2 )
    . % ()


    -6. Compile and run main



    erlc main.erl
    erl -noshell -s main main -s init stop


    We get:



    Hello 1: "good morning"
    Hello 2: "bon jour"





    share|improve this answer





























      1














      HOWTO Erlang Custom Behaviors (template method pattern).



      -1. Write a generic module. Here, an algorithm is defined, but some steps (callback functions in Erlang nomenclature) are left for a future specific definition.



      %% generic.erl 
      -module(generic).
      -export( [sayHello/1] ).

      -callback say(Num :: term()) -> term(). %% future definition

      %% generic algorithm: needs the reference to the provider module
      sayHello(ProviderModule) ->
      io:fwrite( "Hello 1: ~pn", [ ProviderModule:say(1) ]) ,
      io:fwrite( "Hello 2: ~pn", [ ProviderModule:say(2) ]) .


      -2. Compile generic.erl



      erlc generic.erl


      -(3.) Try to write a provider (callback) module



      %% callbacks1.erl (fails to implement say/1 callback)
      -module( callbacks1 ).
      -behaviour( generic ).


      -(4.) Compile callbacks1.erl: use -pa . to say where generic.beam is. (Therefore, the expected warning about say/1 is issued).



      erlc -pa . callbacks1.erl
      callbacks1.erl:2: Warning: undefined callback function say/1 (behaviour 'generic')


      (Note: If -pa is not given, you'll got this: "callbacks1.erl:2: Warning: behaviour generic undefined")



      -3. Write a correct provider (callback) module.



      %% callbacks2.erl
      -module( callbacks2 ).
      -behaviour( generic ).

      -export( [say/1] ).

      say(1) -> "good morning";
      say(2) -> "bon jour";
      say(_) -> "hi".


      -4. Compile it



      erlc -pa . callbacks2.erl


      (Ok now).



      -5. Write a main.erl to gather generic module with callback module.



      %% main.erl
      -module( main ).
      -export( [main/0] ).

      main() ->
      %% call the generic algorithm telling it what callback module to use
      generic:sayHello( callbacks2 )
      . % ()


      -6. Compile and run main



      erlc main.erl
      erl -noshell -s main main -s init stop


      We get:



      Hello 1: "good morning"
      Hello 2: "bon jour"





      share|improve this answer



























        1












        1








        1







        HOWTO Erlang Custom Behaviors (template method pattern).



        -1. Write a generic module. Here, an algorithm is defined, but some steps (callback functions in Erlang nomenclature) are left for a future specific definition.



        %% generic.erl 
        -module(generic).
        -export( [sayHello/1] ).

        -callback say(Num :: term()) -> term(). %% future definition

        %% generic algorithm: needs the reference to the provider module
        sayHello(ProviderModule) ->
        io:fwrite( "Hello 1: ~pn", [ ProviderModule:say(1) ]) ,
        io:fwrite( "Hello 2: ~pn", [ ProviderModule:say(2) ]) .


        -2. Compile generic.erl



        erlc generic.erl


        -(3.) Try to write a provider (callback) module



        %% callbacks1.erl (fails to implement say/1 callback)
        -module( callbacks1 ).
        -behaviour( generic ).


        -(4.) Compile callbacks1.erl: use -pa . to say where generic.beam is. (Therefore, the expected warning about say/1 is issued).



        erlc -pa . callbacks1.erl
        callbacks1.erl:2: Warning: undefined callback function say/1 (behaviour 'generic')


        (Note: If -pa is not given, you'll got this: "callbacks1.erl:2: Warning: behaviour generic undefined")



        -3. Write a correct provider (callback) module.



        %% callbacks2.erl
        -module( callbacks2 ).
        -behaviour( generic ).

        -export( [say/1] ).

        say(1) -> "good morning";
        say(2) -> "bon jour";
        say(_) -> "hi".


        -4. Compile it



        erlc -pa . callbacks2.erl


        (Ok now).



        -5. Write a main.erl to gather generic module with callback module.



        %% main.erl
        -module( main ).
        -export( [main/0] ).

        main() ->
        %% call the generic algorithm telling it what callback module to use
        generic:sayHello( callbacks2 )
        . % ()


        -6. Compile and run main



        erlc main.erl
        erl -noshell -s main main -s init stop


        We get:



        Hello 1: "good morning"
        Hello 2: "bon jour"





        share|improve this answer















        HOWTO Erlang Custom Behaviors (template method pattern).



        -1. Write a generic module. Here, an algorithm is defined, but some steps (callback functions in Erlang nomenclature) are left for a future specific definition.



        %% generic.erl 
        -module(generic).
        -export( [sayHello/1] ).

        -callback say(Num :: term()) -> term(). %% future definition

        %% generic algorithm: needs the reference to the provider module
        sayHello(ProviderModule) ->
        io:fwrite( "Hello 1: ~pn", [ ProviderModule:say(1) ]) ,
        io:fwrite( "Hello 2: ~pn", [ ProviderModule:say(2) ]) .


        -2. Compile generic.erl



        erlc generic.erl


        -(3.) Try to write a provider (callback) module



        %% callbacks1.erl (fails to implement say/1 callback)
        -module( callbacks1 ).
        -behaviour( generic ).


        -(4.) Compile callbacks1.erl: use -pa . to say where generic.beam is. (Therefore, the expected warning about say/1 is issued).



        erlc -pa . callbacks1.erl
        callbacks1.erl:2: Warning: undefined callback function say/1 (behaviour 'generic')


        (Note: If -pa is not given, you'll got this: "callbacks1.erl:2: Warning: behaviour generic undefined")



        -3. Write a correct provider (callback) module.



        %% callbacks2.erl
        -module( callbacks2 ).
        -behaviour( generic ).

        -export( [say/1] ).

        say(1) -> "good morning";
        say(2) -> "bon jour";
        say(_) -> "hi".


        -4. Compile it



        erlc -pa . callbacks2.erl


        (Ok now).



        -5. Write a main.erl to gather generic module with callback module.



        %% main.erl
        -module( main ).
        -export( [main/0] ).

        main() ->
        %% call the generic algorithm telling it what callback module to use
        generic:sayHello( callbacks2 )
        . % ()


        -6. Compile and run main



        erlc main.erl
        erl -noshell -s main main -s init stop


        We get:



        Hello 1: "good morning"
        Hello 2: "bon jour"






        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Nov 14 '18 at 13:29

























        answered Nov 14 '18 at 11:52









        cibercitizen1cibercitizen1

        12.2k135483




        12.2k135483



























            draft saved

            draft discarded
















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid


            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.

            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function ()
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53296965%2fare-erlang-callbacks-to-be-invoked-only-through-mfa-functions-apply-3-spawn-3%23new-answer', 'question_page');

            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            Popular posts from this blog

            Top Tejano songwriter Luis Silva dead of heart attack at 64

            ReactJS Fetched API data displays live - need Data displayed static

            Evgeni Malkin