# HG changeset patch # User John W. Eaton # Date 1316202126 14400 # Node ID 6c952376482ddbfc4c563e5f687a5b8933d8d5a9 # Parent 1ce5cd703af0a722649874e33dccd0a7150b038f look for methods before constructors * symtab.cc (symbol_table::fcn_info::fcn_info_rep::find): Look for class methods before constructors, contrary to Matlab documentation. * test/ctor-vs-method: New directory of test classes. * test/test_ctor_vs_method.m: New file. * test/Makefile.am: Include ctor-vs-method/module.mk. (FCN_FILES): Include test_ctor_vs_method.m in the list. diff -r 1ce5cd703af0 -r 6c952376482d src/symtab.cc --- a/src/symtab.cc Fri Sep 16 21:04:30 2011 +0200 +++ b/src/symtab.cc Fri Sep 16 15:42:06 2011 -0400 @@ -575,13 +575,16 @@ // variable // subfunction // private function +// class method // class constructor -// class method // legacy dispatch // command-line function // autoload function // function on the path // built-in function +// +// Matlab documentation states that constructors have higher precedence +// than methods, but that does not seem to be the case. octave_value symbol_table::fcn_info::fcn_info_rep::find (const octave_value_list& args, @@ -687,6 +690,18 @@ } } + // Class methods. + + if (! args.empty ()) + { + std::string dispatch_type = get_dispatch_type (args); + + octave_value fcn = find_method (dispatch_type); + + if (fcn.is_defined ()) + return fcn; + } + // Class constructors. The class name and function name are the same. str_val_iterator q = class_constructors.find (name); @@ -716,18 +731,6 @@ } } - // Class methods. - - if (! args.empty ()) - { - std::string dispatch_type = get_dispatch_type (args); - - octave_value fcn = find_method (dispatch_type); - - if (fcn.is_defined ()) - return fcn; - } - // Legacy dispatch. if (! args.empty () && ! dispatch_map.empty ()) diff -r 1ce5cd703af0 -r 6c952376482d test/Makefile.am --- a/test/Makefile.am Fri Sep 16 21:04:30 2011 +0200 +++ b/test/Makefile.am Fri Sep 16 15:42:06 2011 -0400 @@ -25,6 +25,7 @@ test_args.m \ test_classes.m \ test_contin.m \ + test_ctor_vs_method.m \ test_diag_perm.m \ test_error.m \ test_eval-catch.m \ @@ -61,6 +62,8 @@ include @Snork/module.mk include @Spork/module.mk +include ctor-vs-method/module.mk + check: test_sparse.m test_bc_overloads.m $(top_builddir)/run-octave --norc --silent --no-history $(srcdir)/fntests.m $(srcdir) diff -r 1ce5cd703af0 -r 6c952376482d test/ctor-vs-method/@derived/derived.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/ctor-vs-method/@derived/derived.m Fri Sep 16 15:42:06 2011 -0400 @@ -0,0 +1,5 @@ +function r = derived (varargin) + __trace__ ('begin derived/derived'); + r = class (struct (), 'derived', parent ()); + __trace__ ('end derived/derived'); +end diff -r 1ce5cd703af0 -r 6c952376482d test/ctor-vs-method/@derived/parent.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/ctor-vs-method/@derived/parent.m Fri Sep 16 15:42:06 2011 -0400 @@ -0,0 +1,9 @@ +function r = parent (a) + __trace__ ('begin derived/parent'); + if (isa (a, 'parent')) + r = parent (a.parent); + else + error ('foo'); + end + __trace__ ('end derived/parent'); +end diff -r 1ce5cd703af0 -r 6c952376482d test/ctor-vs-method/@other/other.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/ctor-vs-method/@other/other.m Fri Sep 16 15:42:06 2011 -0400 @@ -0,0 +1,5 @@ +function r = other (varargin) + __trace__ ('begin other/other'); + r = class (struct (), 'other'); + __trace__ ('end other/other'); +end diff -r 1ce5cd703af0 -r 6c952376482d test/ctor-vs-method/@other/parent.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/ctor-vs-method/@other/parent.m Fri Sep 16 15:42:06 2011 -0400 @@ -0,0 +1,4 @@ +function r = parent (a) + __trace__ ('begin other/parent'); + __trace__ ('end other/parent'); +end diff -r 1ce5cd703af0 -r 6c952376482d test/ctor-vs-method/@parent/method.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/ctor-vs-method/@parent/method.m Fri Sep 16 15:42:06 2011 -0400 @@ -0,0 +1,5 @@ +function r = method (a) + __trace__ ('begin parent/method'); + r = parent (a); + __trace__ ('end parent/method'); +end diff -r 1ce5cd703af0 -r 6c952376482d test/ctor-vs-method/@parent/parent.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/ctor-vs-method/@parent/parent.m Fri Sep 16 15:42:06 2011 -0400 @@ -0,0 +1,15 @@ +function rot = parent (a) + __trace__ ('begin parent/parent'); + if (nargin == 0) + rot = class (struct (), 'parent'); + else + switch class (a) + case 'parent' + %% copy constructor + rot = a; + otherwise + error ('type mismatch in parent constructor') + end + end + __trace__ ('end parent/parent'); +end diff -r 1ce5cd703af0 -r 6c952376482d test/ctor-vs-method/__trace__.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/ctor-vs-method/__trace__.m Fri Sep 16 15:42:06 2011 -0400 @@ -0,0 +1,18 @@ +function r = __trace__ (t) + persistent history + if (isempty (history)) + history = {}; + end + if (nargin == 0) + if (nargout == 0) + history = {}; + else + r = history; + end + elseif (nargin == 1); + history = [history; t]; + else + error ('incorrect call to __trace__'); + end +end + \ No newline at end of file diff -r 1ce5cd703af0 -r 6c952376482d test/ctor-vs-method/module.mk --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/ctor-vs-method/module.mk Fri Sep 16 15:42:06 2011 -0400 @@ -0,0 +1,10 @@ +ctor_vs_method_FCN_FILES = \ + ctor-vs-method/@derived/derived.m \ + ctor-vs-method/@derived/parent.m \ + ctor-vs-method/@other/other.m \ + ctor-vs-method/@other/parent.m \ + ctor-vs-method/@parent/method.m \ + ctor-vs-method/@parent/parent.m \ + ctor-vs-method/__trace__.m + +FCN_FILES += $(ctor_vs_method_FCN_FILES) diff -r 1ce5cd703af0 -r 6c952376482d test/test_ctor_vs_method.m --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/test_ctor_vs_method.m Fri Sep 16 15:42:06 2011 -0400 @@ -0,0 +1,56 @@ +## Copyright (C) 2011 John W. Eaton +## +## This file is part of Octave. +## +## Octave is free software; you can redistribute it and/or modify it +## under the terms of the GNU General Public License as published by +## the Free Software Foundation; either version 3 of the License, or (at +## your option) any later version. +## +## Octave is distributed in the hope that it will be useful, but +## WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +## General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with Octave; see the file COPYING. If not, see +## . + +%% Test script for legacy OOP. +%% Requires the path to contain the directory ctor-vs-method. +%% +%% Note: This script and all classes are also intended to run +%% in Matlab to test compatibility. Don't break that! + +%!shared d, o +%! d = derived (); +%! o = other (); +%! +%!error method (o); + +%!test +%! ctrace = {'begin parent/method'; +%! 'begin derived/parent'; +%! 'begin parent/parent'; +%! 'end parent/parent'; +%! 'end derived/parent'; +%! 'end parent/method'}; +%! __trace__ (); %% clear call trace info +%! method (d); +%! assert (__trace__ (), ctrace); + +%!test +%! ctrace = {'begin other/parent'; +%! 'end other/parent'}; +%! __trace__ (); %% clear call trace info +%! parent (o); +%! assert (__trace__ (), ctrace); + +%!test +%! ctrace = {'begin derived/parent'; +%! 'begin parent/parent'; +%! 'end parent/parent'; +%! 'end derived/parent'}; +%! __trace__ (); %% clear call trace info +%! parent (d); +%! assert (__trace__ (), ctrace);