SWI-Prolog / packages-pengines

Pengines: Prolog engines
11 stars 13 forks source link

pengines_io does not affect submodules #38

Open triska opened 6 years ago

triska commented 6 years ago

Let server.pl consist of the following code:

:- module(server, []).

:- use_module(library(pengines)).
:- use_module(library(http/thread_httpd)).
:- use_module(library(http/http_dispatch)).
:- use_module(library(http/http_server_files)).
:- use_module(library(http/http_files)).
:- use_module(library(http/http_unix_daemon)).

:- pengine_application(myapp).
:- use_module(myapp:library(pengines_io)).
pengines:prepare_module(Module, myapp, _Options) :-
        pengines_io:pengine_bind_io_to_html(Module).

:- use_module(myapp:interaction).

:- http_handler(/, http_reply_from_files(., []), [prefix]).

This is very similar to the code in #37, except that the server now uses a further module, provided by the file interaction.pl with the following content:

:- module(interaction, [main/0]).

main :-
        format("hello!", []).

The intention here is that format/2 in the submodule should also be rewritten (or reinterpreted) by pengines_io, so that I get decorated output from the submodule without having to change the submodule's code.

As a test case, I use demo.html:

<!DOCTYPE html>
<html lang="en">
  <head>
    <title>Demo</title>
    <script src="js/pengines.js"></script>
  </head>
  <body style="padding-left: 5%; padding-right: 5%">
    <br><br>

    <script>
    var p = new Pengine({
        oncreate: function () { p.ask('main'); },
        onoutput: function () { console.log(this.data); },
        application: "myapp",
        server: "pengine",
    });

    </script>
  </body>
</html>

Please start the server with:

$ swipl server.pl --port=5055 --interactive

and then visit http://localhost:5055/demo.html.

Judging from the JavaScript console, main/0 is not affected by the pengines_io declarations in server.pl.

Is this the intended behaviour? If so, could you please explain how I can obtain decorated output in the submodule too? Thank you!

JanWielemaker commented 6 years ago

Just a quick reply now. The pengines_io rebinds write/1, etc. to make nice Prolog terms. It does so by redefining these terms. There is not much choice: once you have a stream that contains a mixture of text and terms it gets hard. That is why it doesn't work for subodules. In addition the library rebinds the standard I/O streams to cacture output and forwards it to the client. That provides raw <pre> output from modules that try to write.

This whole stuff is primarily there to make SWISH work. You best look at the swish source to see how it is deployed.