|
|
— |
pl:miw:miw08_ruleruntimeo:prologmodules [2019/06/27 15:50] (aktualna) |
| ====== Używanie modułów Prologa z obiektów Logtalk ====== |
| |
| ==== Problem ==== |
| |
| Próba wywołania kodu Javy z LogTalka. Mimo iż modul jpl bardzo dobrze się sprawdza przy tworzeniu obiektów Javy, wywoływany z standardowego kodu Prolog'a jak widać np w tym przykładzie : |
| <code prolog> |
| |
| :-use_module(library(jpl)). |
| |
| jpl_test:- |
| jpl_new('javax.swing.JFrame', ['Frame with dialog'], F), |
| jpl_call(F, setLocation, [400, 300], _), |
| jpl_call(F, setSize, [400, 300], _), |
| jpl_call(F, setVisible, [@(true)], _), |
| jpl_call(F, toFront, [], _), |
| jpl_call('javax.swing.JOptionPane', showInputDialog, [F, 'Write sth'], N), |
| jpl_call(F, dispose, [], _), |
| ( N == @(null) -> |
| write('You cancelled'); |
| write('You typed'), write(N) |
| ), |
| nl. |
| |
| |
| |
| :-jpl_test. |
| |
| </code> |
| Działa bez zarzutu, wyświetlając okienko dialogowe. Ale już próba uruchomienia podobnego kodu w metodzie obiektu LogTalk: |
| <code prolog> |
| |
| :-use_module(library(jpl),[jpl_new/3, jpl_call/4]). |
| |
| :-object(logTalkControler). |
| :-public(toString/0). |
| :-public(testValue/1). |
| :-public(jpl_test/0). |
| |
| :-initialization( |
| write('Constructor speaking')). |
| test(a). |
| test(b). |
| test(c). |
| value(a). |
| |
| testValue(X) :- |
| test(X), |
| value(X). |
| |
| jpl_test:- |
| jpl_new('javax.swing.JFrame', ['Frame with dialog'], F), |
| jpl_call(F, setLocation, [400, 300], _), |
| jpl_call(F, setSize, [400, 300], _), |
| jpl_call(F, setVisible, [@(true)], _), |
| jpl_call(F, toFront, [], _). |
| |
| :-end_object. |
| |
| |
| </code> |
| |
| Powoduje dość ciekawy komunikat przy próbie kompilacji w swi : |
| <code> |
| 63 ?- logtalk_load(logTalkControler). |
| <<< reloading source file logTalkControler... |
| >>> compiling source file logTalkControler... |
| compiling object logTalkControler... |
| WARNING! These predicates are called but never defined: jpl_call/4, jpl_new/3 |
| compiled object logTalkControler... |
| >>> logTalkControler source file compiled |
| WARNING! Redefining object logTalkControler |
| Constructor speaking |
| % logTalkControler.pl compiled 0.00 sec, 92 bytes |
| <<< logTalkControler source file reloaded |
| (1 compilation warning and 1 loading warning) |
| true. |
| |
| 64 ?- logTalkControler::jpl_test. |
| ERROR: Undefined procedure: jpl_new/3 |
| ERROR: However, there are definitions for: |
| ERROR: jpl_new/3 |
| </code> |
| I oczywiście nie działa. Podejrzewam, że problem tkwi w niewłaściwie dodanym pakiecie. Ale nie udało mi się jeszcze znaleźć rozwiązania.. |
| |
| ===== Rozwiązanie ===== |
| |
| Rozwiązaniem problemu z jest stosunkowo proste, mianowicie do wywoływania metod z pakietu należy użyć operatora **{}/1**. Inaczej LogTalk próbuje jakoś zrobić z modułu obiekt i nie zawsze to działa. |
| Także poprawne wywołanie wygląda tak : |
| <code prolog> |
| jpl_test:- |
| { jpl_new('javax.swing.JFrame', ['Frame with dialog'], F) }, |
| </code> |
| |
| A poniżej działający już poniższy przykład : |
| <code prolog> |
| |
| :-use_module(library(jpl),[jpl_new/3, jpl_call/4]). |
| |
| :-object(logTalkControler). |
| :-public(toString/0). |
| :-public(testValue/1). |
| :-public(jpl_test/0). |
| |
| :-initialization( |
| write('Constructor speaking')). |
| test(a). |
| test(b). |
| test(c). |
| value(a). |
| |
| testValue(X) :- |
| test(X), |
| value(X). |
| |
| jpl_test:- |
| {jpl_new('javax.swing.JFrame', ['Frame with dialog'], F)}, |
| {jpl_call(F, setLocation, [400, 300], _)}, |
| {jpl_call(F, setSize, [400, 300], _)}, |
| {jpl_call(F, setVisible, [@(true)], _)}, |
| {jpl_call(F, toFront, [], _)}. |
| |
| :-end_object. |
| |
| |
| </code> |
| |