From bug-request at octave dot org Mon Mar 13 15:11:41 2006 Subject: Function handle not correctly updated From: "John W. Eaton" To: Laurent Mazet Cc: bug at octave dot org Date: Mon, 13 Mar 2006 16:11:26 -0500 On 27-Jan-2006, Laurent Mazet wrote: | I think, there's a trouble with function handles. When script file | change, the function definition is not change when the function handle | is updated. There is a very simple work-around which consist off | clearing the function definition before updating the function handle | i.e "clear foo, f= at foo;" | | Laurent | | $ octave | GNU Octave, version 2.1.71 (i586-mandriva-linux-gnu). | Copyright (C) 2005 John W. Eaton. | This is free software; see the source code for copying conditions. | There is ABSOLUTELY NO WARRANTY; not even for MERCHANTIBILITY or | FITNESS FOR A PARTICULAR PURPOSE. For details, type `warranty'. | | Additional information about Octave is available at http://www.octave.org. | | Please contribute if you find this software useful. | For more information, visit http://www.octave.org/help-wanted.html | | Report bugs to (but first, please read | http://www.octave.org/bugs.html to learn how to write a helpful report). | | octave:1> system("echo 'function y = foo(x)\n y = 3 + x;\nendfunction' > | foo.m"); octave:2> f = at foo; | octave:3> f(4) | ans = 7 | octave:4> system("echo 'function y = foo(x)\n y = 3 - x;\nendfunction' > | foo.m"); octave:5> f = at foo; | octave:6> f(4) | ans = 7 I do not see a quick fix for this problem, and I don't have time now to do the major surgery that would be required to properly fix it. So for now, I'm checking in the following patch (for 2.9.x), which will at least provide a warning for the case above. Here is what I see after the patch is applied: octave:1> system("echo 'function y = foo(x)\n y = 3 + x;\nendfunction' > foo.m"); octave:2> f = at foo; octave:3> f(4) ans = 7 octave:4> system("echo 'function y = foo(x)\n y = 3 - x;\nendfunction' > foo.m"); octave:5> f = at foo; octave:6> f(4) warning: reloading functions functions referenced by function handles is not implemented ans = 7 jwe src/ChangeLog: 2006-03-13 John W. Eaton * variables.cc (fcn_out_of_date): No longer static. * ov-fcn-handle.cc (warn_reload): New function. (octave_fcn_handle::subsref): Implement basic logic for updating when pointed-to function changes. Index: src/ov-fcn-handle.cc =================================================================== RCS file: /cvs/octave/src/ov-fcn-handle.cc,v retrieving revision 1.23 diff -u -r1.23 ov-fcn-handle.cc --- src/ov-fcn-handle.cc 28 Apr 2005 02:06:34 -0000 1.23 +++ src/ov-fcn-handle.cc 13 Mar 2006 21:06:04 -0000 at @ -31,6 +31,7 @@ #include "defun.h" #include "error.h" #include "gripes.h" +#include "input.h" #include "oct-map.h" #include "ov-base.h" #include "ov-fcn-handle.h" at @ -56,6 +57,18 @@ "function handle", "function handle"); +void +octave_fcn_handle::reload_warning (const std::string& fcn_type) const +{ + if (warn_reload) + { + warn_reload = false; + + warning ("reloading %s functions referenced by function handles is not implemented", + fcn_type.c_str ()); + } +} + octave_value_list octave_fcn_handle::subsref (const std::string& type, const std::list& idx, at @ -69,20 +82,35 @@ { octave_function *f = function_value (); - // XXX FIXME XXX -- need to check to see if the function has a - // new definition. The following does not work for function - // handles that refer to subfunctions or functions defined on - // the command line. - // - // if (function_out_of_date (f)) - // { - // octave_value tmp = lookup_function (fcn_name ()); - // - // octave_function *ftmp = tmp.function_value (true); - // - // if (ftmp) - // f = ftmp; - // } + if (f && f->time_checked () < Vlast_prompt_time) + { + std::string ff_nm = f->fcn_file_name (); + + time_t tp = f->time_parsed (); + + if (ff_nm.empty ()) + { + // XXX FIXME XXX -- need to handle inline and + // command-line functions here. + } + else + { + if (fcn_out_of_date (f, ff_nm, tp)) + { + // XXX FIXME XXX -- there is currently no way to + // parse a .m file or reload a .oct file that + // leaves the fbi symbol table untouched. We need + // a function that will parse the file and return + // a pointer to the new function definition + // without altering the symbol table. + + if (f->is_nested_function ()) + reload_warning ("nested"); + else + reload_warning ("functions"); + } + } + } if (f) retval = f->subsref (type, idx, nargout); Index: src/ov-fcn-handle.h =================================================================== RCS file: /cvs/octave/src/ov-fcn-handle.h,v retrieving revision 1.18 diff -u -r1.18 ov-fcn-handle.h --- src/ov-fcn-handle.h 9 Mar 2006 19:04:53 -0000 1.18 +++ src/ov-fcn-handle.h 13 Mar 2006 21:06:04 -0000 at @ -41,16 +41,17 @@ { public: octave_fcn_handle (void) - : fcn (), nm () { } + : warn_reload (true), fcn (), nm () { } octave_fcn_handle (const std::string& n) - : fcn (), nm (n) { } + : warn_reload (true), fcn (), nm (n) { } octave_fcn_handle (const octave_value& f, const std::string& n) - : fcn (f), nm (n) { } + : warn_reload (true), fcn (f), nm (n) { } octave_fcn_handle (const octave_fcn_handle& fh) - : octave_base_value (fh), fcn (fh.fcn), nm (fh.nm) { } + : octave_base_value (fh), warn_reload (fh.warn_reload), + fcn (fh.fcn), nm (fh.nm) { } ~octave_fcn_handle (void) { } at @ -109,6 +110,13 @@ DECLARE_OV_TYPEID_FUNCTIONS_AND_DATA + // If TRUE, print a warning if the pointed-to fucntion is out of + // date. This variable may be removed when updating is properly + // implemented. + mutable bool warn_reload; + + void reload_warning (const std::string& fcn_type) const; + protected: // The function we are handling. Index: src/variables.cc =================================================================== RCS file: /cvs/octave/src/variables.cc,v retrieving revision 1.275 diff -u -r1.275 variables.cc --- src/variables.cc 10 Mar 2006 15:35:21 -0000 1.275 +++ src/variables.cc 13 Mar 2006 21:06:04 -0000 at @ -980,7 +980,7 @@ return (f_fs.ino () == g_fs.ino () && f_fs.dev () == g_fs.dev ()); } -static bool +bool fcn_out_of_date (octave_function *fcn, const std::string& ff, time_t tp) { bool retval = false; Index: src/variables.h =================================================================== RCS file: /cvs/octave/src/variables.h,v retrieving revision 1.81 diff -u -r1.81 variables.h --- src/variables.h 17 Jun 2005 07:52:28 -0000 1.81 +++ src/variables.h 13 Mar 2006 21:06:04 -0000 at @ -82,6 +82,9 @@ extern std::string unique_symbol_name (const std::string& basename); +extern bool +fcn_out_of_date (octave_function *fcn, const std::string& ff, time_t tp); + extern bool lookup (symbol_record *s, bool exec_script = true); extern symbol_record * ------------------------------------------------------------- Octave is freely available under the terms of the GNU GPL. Octave's home on the web: http://www.octave.org How to fund new projects: http://www.octave.org/funding.html Subscription information: http://www.octave.org/archive.html -------------------------------------------------------------