octave-maintainers
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

OOP and load/save


From: Robert T. Short
Subject: OOP and load/save
Date: Wed, 22 Apr 2009 07:23:51 -0700
User-agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.21) Gecko/20090402 SeaMonkey/1.1.16

John (Eaton), did you ever get a chance to look at the attached patch? I submitted it some time back along with the message below...

I have figured out, conceptually at least, how to implement load and save for derived classes. Since the matfile format doesn't explicitly include the parent list, the only solution I can come up with seems real clunky to me. If someone has the time and energy I could sure use a little discussion.

Just FYI, I have exercised the derived class stuff quite extensively in real code, so feel pretty good about it.

Bob
--
Robert T. Short
PhaseLocked Systems

-- original message

Attached is an update to the OOP facilities. This fixes all of the major problems that I know about EXCEPT

- I don't see how load/save can work. I haven't tried yet, but I will do that and then I will look and see what happens in MATLAB and fix appropriately.

Notes.

There is a Changelog in both the root and in src. I didn't know which one to muck with so did the src one.

Other things that need attention.

- which(xxx) where xxx is a method should return a path to the method. In MATLAB it would be c:\path\xxx.m % xxx method. I expect octave should do "xxx is the method defined...".

- Documentation and tests.

Also attached is a tarball with my test class hierarchy. The ClassTest script works in both MATLAB and octave. In the Notes file contained in the tarball there are a lot of other notes. Mostly minor and mostly just reminders to myself to check all of these things out.

# HG changeset patch
# User address@hidden
# Date 1238865298 25200
# Node ID 316120e00366c8423fa208659b78f53068940922
# Parent  089bd295e4f7a04b08ceb5102d6280f2277cb16d
Update to OOP facilities.
* scripts/general/isa.m: Fixed isa so that multiple layers of
  class hierarchy are reported correctly.
* src/variables.cc: Make exist('obj') for objects report correctly.
* src/ov-base.h: Added an assign method so ov-class is able to
  assign structure elements properly.
* src/ov-class.h: Assign map elements.
* src/ov-class.cc:
  - Made sure that there are no duplicate classes in parent tree.
  - Simplified search algorithm for parent classes.
  - Fixed subsasgn so cls = method(cls,value) works when properly
    when method is a parent-class method.
  - Added __isa_parent__ so isa works correctly.

diff -r 089bd295e4f7 -r 316120e00366 scripts/general/isa.m
--- a/scripts/general/isa.m     Fri Mar 27 22:35:14 2009 -0700
+++ b/scripts/general/isa.m     Sat Apr 04 10:14:58 2009 -0700
@@ -44,10 +44,7 @@
     class_of_x = class (x);
     retval = strcmp (class_of_x, cname);
     if (! retval && isobject (x))
-      parent_classes_of_x = __parent_classes__ (x);
-      if (! isempty (parent_classes_of_x))
-       retval = any (strcmp (parent_classes_of_x, cname));
-      endif
+      retval = __isa_parent__ (x, cname);
     endif
   endif
 
diff -r 089bd295e4f7 -r 316120e00366 src/ChangeLog
--- a/src/ChangeLog     Fri Mar 27 22:35:14 2009 -0700
+++ b/src/ChangeLog     Sat Apr 04 10:14:58 2009 -0700
@@ -1,3 +1,20 @@
+2009-04-04  Robert T. Short  <address@hidden>
+
+        Update to OOP facilities.  This finishes a reasonably complete and
+        functional implementation of legacy (@Directory) OOP functionality.
+       * scripts/general/isa.m: Fixed isa so that multiple layers of
+          class hierarchy are reported correctly.
+        * src/variables.cc: Make exist('obj') for objects report correctly.
+        * src/ov-base.h: Added an assign method so ov-class is able to
+          assign structure elements properly.
+        * src/ov-class.h: Assign map elements.
+        * src/ov-class.cc:
+           - Made sure that there are no duplicate classes in parent tree.
+           - Simplified search algorithm for parent classes.
+           - Fixed subsasgn so cls = method(cls,value) works when properly
+             when method is a parent-class method.
+           - Added __isa_parent__ so isa works correctly.
+
 2009-03-27  Jaroslav Hajek  <address@hidden>
 
        * DLD-FUNCTIONS/balance.cc (Fbalance): Fix order of output args.
diff -r 089bd295e4f7 -r 316120e00366 src/ov-base.h
--- a/src/ov-base.h     Fri Mar 27 22:35:14 2009 -0700
+++ b/src/ov-base.h     Sat Apr 04 10:14:58 2009 -0700
@@ -170,6 +170,8 @@
 
   virtual octave_value_list
   do_multi_index_op (int nargout, const octave_value_list& idx);
+
+  virtual void assign(const std::string&, const octave_value&) { };
 
   virtual octave_value
   subsasgn (const std::string& type,
diff -r 089bd295e4f7 -r 316120e00366 src/ov-class.cc
--- a/src/ov-class.cc   Fri Mar 27 22:35:14 2009 -0700
+++ b/src/ov-class.cc   Sat Apr 04 10:14:58 2009 -0700
@@ -78,6 +78,9 @@
        {
          std::string cnm = parent.class_name ();
 
+         if (find_parent_class (cnm))
+           error ("duplicate class in parent tree");
+
          parent_list.push_back (cnm);
 
          map.assign (cnm, parent);
@@ -91,52 +94,27 @@
 octave_class::find_parent_class (const std::string& parent_class_name)
 {
   octave_base_value* retval = 0;
-  std::string dbg_clsnm = class_name ();
 
   if (parent_class_name == class_name ())
     retval = this;
   else
-    {
-      // Search in the list of immediate parents first, then in the
-      // ancestor tree.
+    for (std::list<std::string>::iterator pit = parent_list.begin ();
+        pit != parent_list.end ();
+        pit++)
+      {
+       Octave_map::const_iterator smap = map.seek (*pit);
+         
+       const Cell& tmp = smap->second;
 
-      std::list<std::string>::iterator 
-       p = find (parent_list.begin (), parent_list.end (), parent_class_name);
+       octave_value vtmp = tmp(0);
 
-      if (p != parent_list.end ())
-       {
-         Octave_map::const_iterator pmap = map.seek (parent_class_name);
+       octave_base_value *obvp = vtmp.internal_rep ();
 
-         if (pmap != map.end ())
-           {
-             const Cell& tmp = pmap->second;
+       retval = obvp->find_parent_class (parent_class_name);
 
-             octave_value vtmp = tmp(0);
-
-             retval = vtmp.internal_rep ();
-           }
-       }
-      else
-       {
-         for (std::list<std::string>::iterator pit = parent_list.begin ();
-              pit != parent_list.end ();
-              pit++)
-           {
-             Octave_map::const_iterator smap = map.seek (*pit);
-
-             const Cell& tmp = smap->second;
-
-             octave_value vtmp = tmp(0);
-
-             octave_base_value *obvp = vtmp.internal_rep ();
-
-             retval = obvp->find_parent_class (parent_class_name);
-
-             if (retval)
-               break;
-           }
-       }
-    }
+       if (retval)
+         break;
+      }
 
   return retval;
 }
@@ -628,7 +606,21 @@
 
            std::string key = key_idx(0).string_value ();
 
-           map.assign (key, t_rhs);
+           // FIXME -- Is there a "proper" way to do this?
+           octave_function* fcn = octave_call_stack::current ();
+           std::string my_dir = fcn->dir_name ();
+           int ipos = my_dir.find_last_of ("@");
+           std::string method_class = my_dir.substr (ipos+1);
+
+           // Find the class in which this method resides before 
+           // attempting to access the requested field.
+
+           octave_base_value *obvp = find_parent_class (method_class);
+
+           if (obvp==0)
+             error("malformed class");
+
+           obvp->assign (key, t_rhs);
 
            if (! error_state)
              {
@@ -1313,6 +1305,30 @@
   return retval;
 }
 
+DEFUN (__isa_parent__, args, ,
+  "-*- texinfo -*-\n\
address@hidden {Built-in Function} {} __isa_parent__ (@var{x})\n\
+Undocumented internal function.\n\
address@hidden deftypefn")
+{
+  octave_value retval;
+
+  if (args.length () == 2)
+    {
+      octave_value cls = args(0);
+      octave_value nm  = args(1);
+
+      if (cls.find_parent_class (nm.string_value ()))
+       return octave_value (true);
+      else
+       return octave_value (false);
+    }
+  else
+    print_usage ();
+
+  return retval;
+}
+
 DEFUN (__parent_classes__, args, ,
   "-*- texinfo -*-\n\
 @deftypefn {Built-in Function} {} __parent_classes__ (@var{x})\n\
diff -r 089bd295e4f7 -r 316120e00366 src/ov-class.h
--- a/src/ov-class.h    Fri Mar 27 22:35:14 2009 -0700
+++ b/src/ov-class.h    Sat Apr 04 10:14:58 2009 -0700
@@ -85,6 +85,9 @@
 
   static octave_value numeric_conv (const Cell& val,
                                    const std::string& type);
+
+  void assign(const std::string& k, const octave_value& rhs)
+  { map.assign (k, rhs); };
 
   octave_value subsasgn (const std::string& type,
                         const std::list<octave_value_list>& idx,
diff -r 089bd295e4f7 -r 316120e00366 src/variables.cc
--- a/src/variables.cc  Fri Mar 27 22:35:14 2009 -0700
+++ b/src/variables.cc  Sat Apr 04 10:14:58 2009 -0700
@@ -408,7 +408,7 @@
       if (! retval
          && var_ok
          && (type == "any" || type == "var")
-         && val.is_constant ())
+         && (val.is_constant () || val.is_object ()))
        {
          retval = 1;
        }

Attachment: classTest.tgz
Description: application/compressed-tar


reply via email to

[Prev in Thread] Current Thread [Next in Thread]