Kenneth Tilton
1/6/2016 5:10:00 PM
On Wednesday, January 6, 2016 at 11:37:44 AM UTC-5, His Kennyness wrote:
> On Sunday, January 3, 2016 at 8:36:01 AM UTC-5, Frank DG1SBG wrote:
> > Hi Kenny,
> >
> > HNY! (sorry, somehow lost your email address, so posting here hoping you
> > will read this. - You may want to answer via email. See above for my
> > email address - Thx!)
> >
> > The challenge: Lispworks (haven't teste any other implementation)
> > complains:
> >
> > Undefined function (SETF
> > NET.GOENNINGER.THINGBONE.TRANSPORT.MQTT::NEXT-CONNECTION-STATE) called
> > with arguments (:CONNECTED FRGO)
> >
> > I have two packages where class mqtt-transport inherits from class
> > transport. These two classes are defined in two separate packages...
> >
> > I have:
> >
> > --- file: .../transport/defpackage.lisp ---
> >
> > (in-package "CL-USER")
> >
> > (defpackage "NET.GOENNINGER.THINGBONE.TRANSPORT"
> > (:use "CL"
> > "CELLS")
> > (:export
> >
> > ;; CLASSES AND METHODS
> >
> > #:transport
> > #:connect
> > #:disconnect
> >
> > ;; ....
> > ))
> >
> > --- file: .../transport/transports.lisp ---
> >
> > (cells:defmd transport ()
> >
> > connection-state
> > next-connection-state
> >
> > :connection-state (cells:c-in :disconnected)
> > :next-connection-state (cells:c-in :disconnected)
> >
> > :md-name (gensym "THINGBONE-TRANSPORT-"))
> >
> > (defmethod connected? ((self transport))
> > (eql (connection-state self) :connected))
> >
> > (defmethod disconnected? ((self transport))
> > (not (eql (connection-state self) :connected)))
> >
> > (defmethod connect ((self transport))
> > (log:warn "TRANSPORT-CONNECT called on base class. Will not actually connect."))
> >
> > (defmethod disconnect ((self transport))
> > (log:warn "TRANSPORT-DISCONNECT called on base class. Will not actually disconnect."))
> >
> > --- file: .../transport/plugins/mqtt/defpackage.lisp ---
> >
> > (in-package "CL-USER")
> >
> > (defpackage "NET.GOENNINGER.THINGBONE.TRANSPORT.MQTT"
> > (:nicknames "GBT.TB.MQTT")
> > (:use "CL"
> > "CELLS"
> > "NET.GOENNINGER.THINGBONE.TRANSPORT")
> > (:export
> >
> > ;; GLOBAL VARS
> >
> > ;; CLASSES AND METHODS
> >
> > #:mqtt-transport
> > #:connect
> > #:disconnect
> >
> > ;; FUNCTIONS AND MACROS
> >
> > #:mk-mqtt-transport
> >
> > ))
> >
> > --- file: .../transport/plugin/mqtt/mqtt-transport.lisp ---
> >
> > (cells:defmd mqtt-transport (net.goenninger.thingbone.transport:transport)
> > :md-name (gensym "THINGBONE-MQTT-TRANSPORT-"))
> >
> > (defmethod connect ((self mqtt-transport))
> > (setf (next-connection-state self) :connected) ;; <<<= THERE !!!
> > self)
> >
> > (defmacro mk-mqtt-transport (client-id &rest args)
> > (alexandria:with-gensyms (g-client-id)
> > `(let* ((,g-client-id (stringify-client-name ,client-id))
> > (transport (make-instance 'mqtt-transport :md-name ,g-client-id ,@args)))
> > transport)))
> >
> > NOW, when I do:
> >
> > CL-USER> (defvar *mqtt*
> > (net.goenninger.thingbone.transport.mqtt:mk-mqtt-instance "frgo"))
>
> You do not do that. :) There is no such package.
>
> This is as far as I got after cleaning up other such typos and desperately guessing at what in-package forms to add to which files.
>
> This is why it is always wise to take a deep breath and an extra ten minutes to put your massive project aside and lose the elaborate package names and just go with root, left, right, and both (if that is your structure), actually make the four files and actually compile fresh and run fresh.
>
> I suspect the compiler will catch you unless you are adding the same symbol to different packages, in which case #'apropos will help you out.
>
> hth, hk
>
> ps. HNY!, Frank!
>
> >
> > ==>
> > FRGO
> >
> > CL-USER> (net.goenninger.thingbone.mqtt:connect *mqtt*)
> >
> > ==> Undefined function (SETF
> > NET.GOENNINGER.THINGBONE.TRANSPORT.MQTT::NEXT-CONNECTION-STATE) called
> > with arguments (:CONNECTED FRGO)
> >
> > I seem to understand that I can't use the Cell slot accessor methods
> > that are defined by defmd/defmodel as they are not exported
> > automagically. Or am I misinterpreting the error message?
> >
> > How do/would you tackle this?
> >
> > Thx again!
> >
> > Best,
> > Frank
OK, I dove back in and made like three more simple fixes and it seems to work. So your problem is the classic head fake bugs like to give us ("hey, Cells is hairy, so this must be a Cells problem") keeping us from seeing/finding the obvious.
I can only guess at your actual situation (did you really have source files with an in-package form missing, or was that just in your report?) but in some cases you got confused by the elaborate package names and miscoded those (making you wonder why the function does not exist, but it is the package). And it might be that in other cases you defined a method hoping it would go in one package but it went in cl-user. Again, not knowing your in-packages I can only guess.
I left the test code in its own file with cl-user as the in-package and added a package qualifier to the defmethod of ... oh, what the hell:
;--- file: .../transport/transports.lisp ---
(in-package :net.goenninger.thingbone.transport)
(cells:defmd transport ()
connection-state
next-connection-state
:connection-state (cells:c-in :disconnected)
:next-connection-state (cells:c-in :disconnected)
:md-name (gensym "THINGBONE-TRANSPORT-"))
(defmethod connected? ((self transport))
(eql (connection-state self) :connected))
(defmethod disconnected? ((self transport))
(not (eql (connection-state self) :connected)))
(defmethod connect ((self transport))
(warn "TRANSPORT-CONNECT called on base class. Will not actually connect."))
(defmethod disconnect ((self transport))
(warn "TRANSPORT-DISCONNECT called on base class. Will not actually disconnect."))
;;--- file: .../transport/defpackage.lisp ---
(in-package "cl-user")
(defpackage "net.goenninger.thingbone.transport"
(:use "cl"
"cells")
(:export
;; classes and methods
#:transport
#:connect
#:disconnect
;; ....
))
;;--- file: .../transport/plugins/mqtt/defpackage.lisp ---
(in-package "cl-user")
(defpackage "net.goenninger.thingbone.transport.mqtt"
(:nicknames "gbt.tb.mqtt")
(:use "cl"
"cells"
"net.goenninger.thingbone.transport")
(:export
;; global vars
;; classes and methods
#:mqtt-transport
#:connect
#:disconnect
;; functions and macros
#:mk-mqtt-transport
))
;; --- file: .../transport/plugin/mqtt/mqtt-transport.lisp ---
(in-package :cl-user)
(cells:defmd mqtt-transport (net.goenninger.thingbone.transport:transport)
:md-name (gensym "THINGBONE-MQTT-TRANSPORT-"))
(defmethod net.goenninger.thingbone.transport:connect ((self mqtt-transport))
(setf (net.goenninger.thingbone.transport::next-connection-state self) :connected) ;; <<<= THERE !!!
self)
(defmacro gbt.tb.mqtt:mk-mqtt-transport (client-id &rest args)
(alexandria:with-gensyms (g-client-id)
`(let* ((,g-client-id (string ,client-id))
(transport (make-instance 'mqtt-transport :md-name ,g-client-id ,@args)))
transport)))
;;; --- test file
(in-package :cl-user)
(defparameter *mqtt*
(net.goenninger.thingbone.transport.mqtt:mk-mqtt-transport "frgo"))
#|
Evaluate this:
(net.goenninger.thingbone.transport.mqtt:connect *mqtt*)
|#
All that was pulled together from multiple files so hopefully it still works. You will see some downcase package names because I use ACL modern. You might want also to double-check my guesswork.
hth, hk