====== 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 : :-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. Działa bez zarzutu, wyświetlając okienko dialogowe. Ale już próba uruchomienia podobnego kodu w metodzie obiektu LogTalk: :-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. Powoduje dość ciekawy komunikat przy próbie kompilacji w swi : 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 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 : jpl_test:- { jpl_new('javax.swing.JFrame', ['Frame with dialog'], F) }, A poniżej działający już poniższy przykład : :-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.