[Bese-devel] I'm in trouble again

Friedrich Dominicus frido at q-software-solutions.de
Sat Sep 10 15:56:39 UTC 2005


with a similar but now stripped down problem which I simply did not
understand. Here's the code:

The problem is "artificial" here but if it comes to integrating other
things it probably will be needed (but in the case I did screw it up
fully)

- base idea 
- I have a backend object to store things
- I have the view classes to display things
- I have a controller in between which steers the whole stuff

My idea was: 
- initialize the view is initialized from the store
- after that the view steers the backend. (I know it could (but
should?) be done in the defactions AFAIU, are the defaction the
"controllers" in UCW. But let us assume I like to wrap up that stuff i
in it's own "controller" class. 

The code below works till it comes to the 
save-and-show-data action. When it tries to render the next view I get
the following error:

The slot IT.BESE.UCW::PLACE is unbound in the object #<SIMPLE-CONTROLLER {1000927891}>.
   [Condition of type UNBOUND-SLOT]

Restarts:
  0: [SHOW-BACKTRACE] Send the client a backtrace page.
  1: [RETRY] Clearout the response and retry calling the action.
  2: [SERVER-ERROR] Send the client an internal server error page.
  3: [GENERATE-BACKTRACE-FOR-EMACS] Generate a bug report in Emacs.
  4: [ABORT-RESPONSE] Abort this response and answer another request
  5: [TERMINATE-THREAD] Terminate this thread (#<THREAD {1000FFB621}>)

The things I found with place in it are the following:
COMPONENT.PLACE (fbound)
MAKE-PLACE (fbound)
IT.BESE.UCW::PLACE.FORM (fbound)
IT.BESE.UCW::INITIALIZE-PLACE-SLOT (fbound)
IT.BESE.UCW::CLONE-PLACE-VALUE (fbound)
IT.BESE.UCW::COMPONENT-CLASS.PLACE-SLOT (fbound)
IT.BESE.UCW::PLACE (fbound)
IT.BESE.UCW::PLACE.COPYER (fbound)
IT.BESE.UCW::PLACE-SLOT
IT.BESE.UCW::PLACE.SETTER (fbound)
IT.BESE.UCW::PLACE.GETTER (fbound)
IT.BESE.UCW::REPLACE-AT-INDEX (fbound)
IT.BESE.UCW::*SERVER-DUMP-PLACEHOLDER* (bound

all this have to do with backtacking? Why do I need it here?

However there are other slots unfilled:
0. CONTINUATION: "unbound"
1. CALLING-COMPONENT: "unbound"
2. PLACE: "unbound"

Marc has written something about that in another mail:

> Friedrich Dominicus <frido at q-software-solutions.de> writes:
> 
> > Well ucw is way too much a mystery too me, as you've seen but giving
> > up is not what I like to do. So I have a general question
> > Do I understand it correctly that creating of a component can not be
> > done with make-instance?
> 
> it can be done (call macro expands into a make-instance form). however
> the call-component method does some neccassary bookkeeping work (like
> setting up the continuation, the place, the parent, etc.) which you'll
> need to repeat if you just use make-instance. of course, this
> bookkeeping stuff requires that there be a valid *context* object in
> the dynamic environment.
> 
> basically it can be done, but it's a goodly amoun of work. why are you
> trying to do it?
> 
so it should not be done that way I guess. 
Probably simple controller should not have a standard-component-class
as metaclass. (see (1)), but if I drop it then I got this messages (as
obscur to me)
When attempting to test to see whether slot is bound (SLOT-BOUNDP), the slot
IT.BESE.UCW::TRANSACTION-STACK is missing from the object
#<SIMPLE-CONTROLLER {1000BA53B1}>.
   [Condition of type SIMPLE-ERROR]

Restarts:
  0: [SERVER-ERROR] Send the client an internal server error page.
  1: [GENERATE-BACKTRACE-FOR-EMACS] Generate a bug report in Emacs.
  2: [ABORT-RESPONSE] Abort this response and answer another request
  3: [TERMINATE-THREAD] Terminate this thread (#<THREAD {10018A60F1}>)

I assume it's a fundamental miunderstanding on how UCW works from my
side. Can anyone clarify it for me, please?

Regards
Friedrich






(eval-when (:compile-toplevel :execute)
  (defparameter *simple-app*
    (make-instance 'cookie-session-application
                   :url-prefix "/ucw/simple/"
                   :tal-generator (make-instance 'yaclml:file-system-generator
                                                 :cachep t
                                                 :root-directories (list *ucw-tal-root*))
                   :www-roots (list *ucw-tal-root*)))
  )

so it seems I have to fill the slots manually, but I do not know how
and if it's good idea (I feel it isn't)


(defclass simple-controller ()
  ((view-obj :accessor view-obj :initarg :view-obj)
   (db-obj :accessor db-obj :initarg :db-obj))
  (:metaclass standard-component-class)) ;; needed ? (1)


  


(defentry-point "index.ucw" (:application *simple-app*) ()
  (call 'simple-view))




;; (register-application *default-server* *simple-app*)

(defmethod update-from-view ((controller simple-controller))
    (setf (val (db-obj controller)) (read-client-value (val (view-obj controller)))))
    
(defclass be-class ()
  ((val :accessor val :initarg :val)))



  

(defcomponent simple-text (simple-window-component)
  ((view-text :initarg :view-text :reader view-text)
   (db-text :initarg :db-text :reader db-text)))



(defmethod render-on ((res response) (text simple-text))
  (inspect text)
  (<:p "view data"
       (<:as-is (view-text text)))
  (<:p "database data"
       (<:as-is (db-text text))))

         
(defaction save-and-show-data ((controller simple-controller))
  (inspect controller)
  (update-from-view controller)
  (call 'simple-text
        :view-text (format nil "view val = ~a~%"
                           (read-client-value (val (view-obj controller))))
        :db-text (format nil "db val = ~a~%"
                           (val (db-obj controller)))))
        



(defcomponent simple-view (simple-window-component standard-component)
  ((val :component (text-field :size 20 :maxlength 20) :accessor val :initarg :val)))


(defmethod initialize-vfd ((view simple-view) (controller simple-controller))
  (setf (ucw::client-value (val view)) (val (db-obj controller)))
  (setf (view-obj controller) view)
  (values))


    


(defmethod render-on ((res response) (view simple-view))
  (let ((controller (make-instance 'simple-controller)))
  ;; initialize the backend data 
    (setf (db-obj controller) (make-instance 'be-class :val "some
value frido"))    
      ;; use that data to initialize the store
    (initialize-vfd view controller)

        
    (<ucw:form :action (save-and-show-data controller)
               (<:table 
                (<:tr
                 (<:td "val")
                 (<:td (render-on res (val view)))))
               (<:p (<:input :type "submit" :value "Accept")))))



More information about the bese-devel mailing list