bugGNU Octave - Bugs: bug #35881, clear all removes subfunctions

 
 

bug #35881: clear all removes subfunctions

Submitted by:  Alon Levy <alon>
Submitted on:  Sun 18 Mar 2012 07:20:12 AM UTC  
 
Category:  Interpreter Severity:  3 - Normal
Priority:  5 - Normal Item Group:  Matlab Compatibility
Status:  Fixed Assigned to:  None
Originator Name:  Open/Closed:  Closed
Release:  dev Operating System:  Any

Add a New Comment (Rich Markup)
   

You are not logged in

Please log in, so followups can be emailed to you.

 

( Jump to the original submission)

Mon 30 Oct 2017 12:34:12 AM UTC, comment #25: 

This was annoyingly tedious.  I adapted the example code here to be a proper BIST test for regressions, but then _run_test_suite_ failed because it was based on passing out-of-band information through global variables.  I modified _run_test_suite_ to use nested functions and sharing of variables with the parent function to get rid of the globals.  It now works and was checked in here (http://hg.savannah.gnu.org/hgweb/octave/rev/068556c5167e)

Rik <rik5>
Project Administrator
Tue 15 Aug 2017 05:54:08 PM UTC, comment #24: 

This bug appears to be resolved now on the default branch thanks to symbol table work by jwe. jbect's example in comment #10 works perfectly now.

Can someone propose a test case that we can add to the test suite to make sure we don't regress on this?

Mike Miller <mtmiller>
Project Administrator
Wed 07 Jun 2017 12:17:05 AM UTC, comment #23: 

I'm currently doing some significant refactoring of the symbol table, so maybe this will be easier to fix once that is done.

John W. Eaton <jwe>
Project Administrator
Sat 19 Nov 2016 09:06:33 PM UTC, comment #22: 

This issue is still present in Octave 4.2.0. (At least I still get different results as with Matlab in comment #10.)

Hartmut <hardy>
Tue 03 May 2016 06:35:15 PM UTC, comment #21: 

Yes, your translation is correct (this is what I meant).

Julien Bect <jbect>
Tue 03 May 2016 06:27:08 PM UTC, comment #20: 

Ok.  My translation of the comment #13 is that any function defined within a currently executing m-file is preserved.  This includes the top-level function which shares the name of the m-file, it includes subfunctions, and it includes nested functions.

I think this is possible becaause I believe Octave's symbol table records the file name where a function is stored.

Rik <rik5>
Project Administrator
Tue 03 May 2016 05:41:10 PM UTC, comment #19: 

Rik,

My comment #13 was meant to dissipate the confusion...

The only thing that needs to be changed, to address the problems discussed in this report, is the behaviour of clear with respect to clearing functions (see comment #13 or more details).

Is there anything else that needs to be clarified?

Julien Bect <jbect>
Tue 03 May 2016 05:33:46 PM UTC, comment #18: 

Can someone write a concise summary of how Octave should behave?  I see lots of test results from Matlab, but it is all very confusing.

Rik <rik5>
Project Administrator
Tue 03 May 2016 04:00:24 PM UTC, comment #17: 

I guess functions (unless nested or subfunctions) are global.

So, global variables and functions are cleared, but not top-level variables.

OK.

John W. Eaton <jwe>
Project Administrator
Tue 03 May 2016 03:22:14 PM UTC, comment #16: 

Same result in R2016a.

The same behaviour is observed if the "clear all" inside f1() is replaced with "clear functions" or "clear f2".

The action of "clear all" is indeed limited to the current scope (together with the global workspace) as far as variables are concerned.

For functions, what would be the "scope" ?

Julien Bect <jbect>
Tue 03 May 2016 02:55:42 PM UTC, comment #15: 

It's not. All my Matlab versions (tried 2014a and 2015b) behaves the same:

>> f2
p is not yet initialized
>> f2
p is initialized with value p = 1
>> f1
>> f2
p is not yet initialized

sergey plotnikov <nul0m>
Tue 03 May 2016 02:38:24 PM UTC, comment #14: 

If "clear all" is called within a function, does it only work within the current function scope or does it also clear variables defined in the top-level workspace and other functions (not the one currently executing or its sub and nested functions)?

Here is how I would test for this behavior.  Define the following functions:

function f1 ()
  clear all
end

function f2 ()
  persistent p
  if (isempty (p))
    disp ('p is not yet initialized')
    p = 1;
  else
    fprintf ('p is initialized with value p = %d', p)
  end
end

Then execute

f2
f2
f1
f2

You should see the message about p not initialized, then that it is initialized with value 1, then on the third call to f2, what happens?  Does the persistent variable need to be initialized?  If so, the "clear all" inside f1 must have also cleared f2.  Otherwise, I would guess that the scope of "clear" is limited to the scope where it is executed, which is behavior that makes more sense anyway.

Oh, after writing all of that, I now see that I asked this question previously and apparently the behavior I was hoping for is (once again!) NOT how Matlab behaves?!?

John W. Eaton <jwe>
Project Administrator
Tue 03 May 2016 01:57:01 PM UTC, comment #13: 

To sum it up: I believe that this bug report could be closed if clear() could be modified in such a way that any form of "clear" that can clear functions:

  • "clear all"
  • "clear functions"
  • clear name1 name2 name3...

is actually prevented from clearing

  • the current (sub)function,
  • the main function (it the current one is a subfunction),
  • and all the other subfunctions of the same main function.

I am not familiar enough with Octave's symbol table to know if this is possible (and how hard it is).

Julien Bect <jbect>
Tue 03 May 2016 01:46:52 PM UTC, comment #12: 

Thank you Sergey.

I believe the new behaviour makes more sense (it easier to explain to users) and will be easier to implement than the old "delayed deletion" behaviour.

Julien Bect <jbect>
Tue 03 May 2016 01:33:47 PM UTC, comment #11: 

Julien, I've just checked my "testpersist.m" on different Matlabs and may confirm it's version dependent.

Starting R2015b it yields your results, but all the older versions (tried R2014a and R2015a) shows the behavior as in comment(#6).

sergey plotnikov <nul0m>
Tue 03 May 2016 01:17:41 PM UTC, comment #10: 

Yet another follow-up to comment #8:

What I said there applies direcly to "clear functions", or to "clear MyFunc" (where MyFunc is the name of the current function) but the case of "clear all" requires a more detailed explanation.

We must first clarify what "clearing a function" actually means. I will assume that it simply means "clearing the persistent variables inside the function" (if not mlock'ed). It might mean something more in Octave internally, such as removing the function definition from memory, but from a user's perspective (mine at least) this is what it looks like.

Then, in my understanding, a persistent living inside MyFunc is cleared by a call to "clear all" inside MyFunc, not because the function is cleared (the doc says that it isn't), but simply becaused "clear all" also removes all variables from the current workspace.

Let me illustrate (R2016a):

>> type test_clear_inside_function.m

function test_clear_inside_function (flag)
persistent a
if isempty (a), a = 1; end
subf ();  fprintf ('a=%d\n', a);
switch flag
    case 0
        clear subf
    case 1
        clear functions
    case 2
        clear all
end
subf ();  fprintf ('a=%d\n', a);
fprintf ('------\n\n');
end

function subf ()
persistent x
fprintf ('subf: ');
if isempty (x)
  x = 1;
  fprintf ('INIT, ');
end
end

>> clear all;  test_clear_inside_function (0)
subf: INIT, a=1
subf: a=1
------

>> clear all;  test_clear_inside_function (1)
subf: INIT, a=1
subf: a=1
------

>> clear all;  test_clear_inside_function (2)
subf: INIT, a=1
subf: Reference to a cleared variable a.
Error in test_clear_inside_function (line 13)
subf ();  fprintf ('a=%d\n', a);

Julien Bect <jbect>
Tue 03 May 2016 12:38:05 PM UTC, comment #9: 

Following-up to my previous comment (#8):

Sergey Plotnikov's experiment seems to contradict the documentation, since it appears from his result that the call to clear() inside testpersist() clears the persistent in testpersist(), with a delay.

However, repeating the experiment today in R2016a I obtain a different result, which is in line with the documentation:

>> type testpersist
function testpersist
  persistent x;
  x
  if isempty(x)
    x = 1;
  end
  clear('functions');
  x
end

>> testpersist
x =
     []
x =
     1

>> testpersist
x =
     1
x =
     1

My interpretation is that in Matlab R2016a, as the documentation says, the current function is not cleared by clear ('functions').  The difference with Sergey's result is perhaps due a difference of versions.

In Octave (tested in 4.0.2), the current function is cleared by clear ('functions').

Julien Bect <jbect>
Tue 03 May 2016 12:15:56 PM UTC, comment #8: 

JWE asked (see Comment #3):

> What does Matlab remove when "clear all" appears inside a function? Does it clear all top-level variables and functions, but not the current function?


According to the documentation (R2016a), "clear all" basically clears everything except:

  • classes
  • the currently running function ("If a function is locked or currently running, it is not cleared from memory.")

http://fr.mathworks.com/help/matlab/ref/clear.html

Julien Bect <jbect>
Tue 03 May 2016 11:55:41 AM UTC, comment #7: 

JWE asked (see comment #3):

> What does Matlab remove when "clear all" appears inside a function? [...] Does it clear local variables defined inside the current function?


The documentation clearly states that "clear" or "clear all" removes all variables from the current workspace.

http://fr.mathworks.com/help/matlab/ref/clear.html

Here is a little experiment to confirm (R2016a):

>> type test_clear_localvariables.m
function test_clear_localvariables ()
x = 1;
clear all
disp (x)
end

>> test_clear_localvariables
Reference to a cleared variable x.

Error in test_clear_localvariables (line 4)
disp (x)

Octave (test in 4.0.2) does the same (although with a less explicit error message):

>> test_clear_localvariables
error: 'x' undefined near line 4 column 8
error: called from
    test_clear_localvariables at line 4 column 2
error: evaluating argument list element number 1
error: called from
    test_clear_localvariables at line 4 column 2

Julien Bect <jbect>
Tue 26 Nov 2013 02:51:07 PM UTC, comment #6: 

Playing with that testnestfun() in ML have led to interesting conclusion:

  1. "clear functions" doesn't clear nested/sub- functions when called, so those guys are probably locked by default during the whole run of the main function
  2. persistent variables are not reinitialized at the moment of "clear functions", but at the very beginning and at the very end of the main function:
  3. below are results for the following function

    function testpersist
      persistent x;
      x
      if isempty(x)
        x = 1;
      end
      clear('functions');
      x
    end

1st test, two consecutive calls
+verbatin+

>> testpersist

x =
     []
x =
     1

>> testpersist

x =
     []
x =
     1
-verbatim-

2nd test, "clear('functions')" is commented out, two consecutive calls
+verbatin+

>> testpersist

x =
     []
x =
     1

>> testpersist

x =
     1
x =
     1
-verbatim-
*3rd test, two consecutive calls -- first with "clear(.." commented out, second with uncommented "clear(.."
+verbatin+

>> testpersist

x =
     []
x =
     1

>> testpersist

x =
     []
x =
     1
-verbatim-

sergey plotnikov <nul0m>
Tue 15 Oct 2013 12:12:41 PM UTC, comment #5: 

Re-opening bug. This problem popped up when trying the IRIS toolbox. This toolbox uses a pattern like:

function testnestfun

  persistent x;

  if isempty(x)
    x = 1;
  end

  disp('testnestfun');
  clear('functions');
  nestfun;
  subfun;

  function nestfun
    disp ('nestfun');
  end

end

function subfun
  disp('subfun');
end

I suppose Matlab keeps a reference to the sub-/nested functions while the main function is executing so they're still visible after the "clear" call.

As a side note, it would be interesting to know what happens to the persistent variable after the clear call. More testing required, but I don't have access to Matlab, so I can't tell.

Michael Goffioul <goffioul>
Thu 20 Jun 2013 03:15:32 AM UTC, comment #4: 

No response to request for information after 1 year.  Closing report.

Rik <rik5>
Project Administrator
Mon 23 Jul 2012 07:38:00 PM UTC, comment #3: 

What does Matlab remove when "clear all" appears inside a function?

Does it clear all top-level variables and functions, but not the current function?

Does it clear local variables defined inside the current function?

John W. Eaton <jwe>
Project Administrator
Mon 23 Jul 2012 07:34:04 PM UTC, comment #2: 

well, octave is self consistent, I'll give you that. But matlab doesn't remove the subfunctions on clear -a, so I assumed we want octave to behave the same.

Alon Levy <alon>
Mon 23 Jul 2012 06:19:25 PM UTC, comment #1: 

Isn't this the expect behavior?  According to the documentation for clear, 'clear all' does the following:

`-all, -a'
          Clears all local and global user-defined variables and all
          functions from the symbol table.

All functions from the symbol table would include subfunctions.

Rik <rik5>
Project Administrator
Sun 18 Mar 2012 07:20:12 AM UTC, original submission:  

Tested with octave 3.6.1 and 3.7.0+ (14467:ec7ab7e37731) with the nested second patch applied.

x86_64 garlic:sub alon (master)$ cat call_f.m
f

x86_64 garlic:sub alon (master)$ cat f.m
function f();

clear all;
sub();

end

function sub()
end

x86_64 garlic:sub alon (master)$ /usr/bin/octave --silent call_f.m
error: `sub' undefined near line 4 column 1
error: called from:
error:   /home/alon/src/tests/octave/sub/f.m at line 4, column 1
error:   /home/alon/src/tests/octave/sub/call_f.m at line 1, column 1
x86_64 garlic:sub alon (master)$ /usr/bin/octave --version
GNU Octave, version 3.6.1

Alon Levy <alon>

 

(Note: upload size limit is set to 16384 kB, after insertion of the required escape characters.)

Attach Files:
   
   
Comment:
   

No files currently attached

 

Depends on the following items: None found

Digest:
   bug dependencies.

 

Carbon-Copy List
  • -email is unavailable- added by mtmiller (Posted a comment)
  • -email is unavailable- added by hardy (Posted a comment)
  • -email is unavailable- added by jbect (Posted a comment)
  • -email is unavailable- added by nul0m (Posted a comment)
  • -email is unavailable- added by jwe (Posted a comment)
  • -email is unavailable- added by rik5 (Posted a comment)
  • -email is unavailable- added by alon (Submitted the item)
  •  

    Do you think this task is very important?
    If so, you can add your encouragement to it.
    This task has 0 encouragements so far.

    Only project members can vote.

     

     

     

    Follow 11 latest changes.

    Date Changed by Updated Field Previous Value => Replaced by
    2017-10-30 rik5 StatusIn Progress => Fixed
        Open/ClosedOpen => Closed
    2017-08-15 mtmiller StatusNeed Info => In Progress
    2017-06-06 siko1056 Dependencies- => bugs #51096 is dependent
    2014-01-21 rik5 Dependencies- => bugs #41269 is dependent
    2013-10-15 goffioul Open/ClosedClosed => Open
        Release3.6.1 => dev
        Operating SystemGNU/Linux => Any
    2013-06-20 rik5 Open/ClosedOpen => Closed
    2012-07-23 rik5 Item GroupIncorrect Result => Matlab Compatibility
    2012-07-23 rik5 StatusNone => Need Info

    Back to the top


    Powered by Savane 3.5