bugGNU Octave - Bugs: bug #47807, run behaves differently from...

 
 

bug #47807: run behaves differently from Matlab on function m-files

Submitter:  Julien Bect <jbect>
Submitted:  Fri 29 Apr 2016 03:42:17 PM UTC
   
 
Category:  Octave Function Severity:  1 - Wish
Priority:  3 - Low Item Group:  Matlab Compatibility
Status:  Fixed Assigned to:  None
Originator Name:  Open/Closed:  * Closed
Release:  * dev Operating System:  * Any
Fixed Release:  None Planned Release:  None
* Mandatory Fields

Add a New Comment Rich Markup
   

Jump to the original submission

Tue 15 Aug 2017 05:33:54 PM UTC, comment #11: 

This has been fixed on the default branch, and even includes some tests to ensure that the behavior continues to work.

Mike Miller <mtmiller>
Group Member
Mon 16 May 2016 08:43:56 PM UTC, comment #10: 

Here is a simple modification of the existing run.m that behaves properly on the example of comment #8:


function run (script)

  if (nargin != 1)
    print_usage ();
  endif

  [d, f, ext] = fileparts (script);

  if (isempty (d))
    % Do not change directory if the input argument has no path
    evalin ("caller", f, "rethrow (lasterror ())");
  else
    if (exist (d, "dir"))
      startdir = pwd ();
      d = make_absolute_filename (d);
      unwind_protect
        cd (d);
        evalin ("caller", f, "rethrow (lasterror ())");
      unwind_protect_cleanup
        if (strcmp (d, pwd ()))
          cd (startdir);
        endif
      end_unwind_protect
    else
      error ("run: the path %s doesn't exist", d);
    endif
  endif
endfunction


What do you think?

Julien Bect <jbect>
Mon 16 May 2016 05:10:59 PM UTC, comment #9: 

Sorry, I forgot the attachment in my previous post. Here it is.

(file #37178)

Julien Bect <jbect>
Mon 16 May 2016 05:06:39 PM UTC, comment #8: 

I wrote below that "Matlab changes directory in all cases", and this indeed what the documentation of Matlab R2016a says (currently online at: http://fr.mathworks.com/help/matlab/ref/run.html).

Unfortunately, it seems that the truth is more complicated (arghhhhh). Here is the output of the attached example script in Matlab R2016a:


=== Calling mfunc directly ===
myfunc has been called with 0 argins
current directory is: /home/bect/code/octave/bugs/47807/essai1
myfunc has been called with 2 argins
current directory is: /home/bect/code/octave/bugs/47807/essai1
=== Calling mfunc with run ===
myfunc has been called with 0 argins
current directory is: /home/bect/code/octave/bugs/47807/essai1/subdir
myfunc has been called with 0 argins
current directory is: /home/bect/code/octave/bugs/47807/essai1/subdir
myfunc has been called with 0 argins
current directory is: /home/bect/code/octave/bugs/47807/essai1
myfunc has been called with 0 argins
current directory is: /home/bect/code/octave/bugs/47807/essai1


It seems that Matlab actually changes directory in all cases but one: it doesn't change directory when the input argument has no "path part" (the first output arg of fileparts is empty).

This is easy to implement,

Julien Bect <jbect>
Thu 05 May 2016 11:27:39 AM UTC, comment #7: 

This looks about right.

The evaluation should indeed take place in the parent (using evalin ("caller", ...)) and the change back of directory should only happen if the script/function does not modify the current directory (as already implemented in the current version of run ()).

Out of curiosity, as used in your mock function, the onCleanup object is stored in the "ans" variable and might therefore be cleared before the end of the function - should it be attributed to a variable or is there something I misunderstand about onCleanup ()?

Guillaume <gyom>
Wed 04 May 2016 06:34:28 PM UTC, comment #6: 

So should run be just as brain-dead simple as


function run (file_name)
curr_dir = pwd ();
onCleanup (@() chdir (currdir));
## Some code to check validity of file_name and determine directory part (if any) and function name...
chdir (dir_part_of_given_file_name);
eval (function_name_derived_from_file_name);
endfunction


?  Does the evaluation of the function need to happen in the parent (so instead of eval, use evalin ("caller", ...))?

John W. Eaton <jwe>
Group administrator
Sat 30 Apr 2016 02:09:51 PM UTC, comment #5: 

Yes, in Matlab it works even for a function that is not in the path.  (But remember that Matlab changes directory before executing the function.)

Julien Bect <jbect>
Sat 30 Apr 2016 01:48:39 PM UTC, comment #4: 

It occurs to me that the more complicated case might be if Matlab allows this to work on a function file that is not in the path. So I should amend saying it looks easy to support the cause of "run FUNCNAME", but not to support "run /path/to/some/funcfile.m". Does Matlab support that (if the directory is not in the load path)?

Mike Miller <mtmiller>
Group Member
Fri 29 Apr 2016 04:12:03 PM UTC, comment #3: 


> it seems simple enough to add if it's an important feature to someone.


I already lost some valuable time understanding this, so at least it's important to me ;-)


> Does Matlab also change directory to the location of the function file


Yes, Matlab changes directory in all cases.


> Does it show an error for functions that do require arguments?


Yes, exactly the same error that you get if you call the function directly: if the function actually uses the argument, you get an error; otherwise, no.


> Do errors occur in the same context as if the function were just called without run?


Not sure what you mean.  I think the answer is no: you can see that run() has been called in th dbstack (run only, nothing else).


> Can errors be caught with try or shown with lasterr?


Yes (both).



Julien Bect <jbect>
Fri 29 Apr 2016 03:50:37 PM UTC, comment #2: 

I think this has been known and ignored for a while, but it seems simple enough to add if it's an important feature to someone.

Does Matlab also change directory to the location of the function file when it is executed? What's the output for a function /some/path/foo.m


function foo()
disp(pwd);
end


Does it show an error for functions that do require arguments? Do errors occur in the same context as if the function were just called without run? Can errors be caught with try or shown with lasterr?

Mike Miller <mtmiller>
Group Member
Fri 29 Apr 2016 03:48:43 PM UTC, comment #1: 

Some thoughts about this issue:

  • Matlab's behaviour in this case is not clearly documented, but it is somewhat natural: in all cases, run ("toto.m") produces the same result as executing the command "toto" (assuming toto.m is on the path).


  • In Octave, run() relies internally on source().  There is of course nothing wrong with source() behaving this way, since source() is an Octave-only function (perhaps should it be documented explicitely ?).  The problem is that run() should not simply rely on source(), at least in this case.
Julien Bect <jbect>
Fri 29 Apr 2016 03:42:17 PM UTC, original submission:  

The run() function of Octave treats "function m-files" (i.e., m-files where all the code appears in function/end[function] pairs) differently form its Matlab couterpart:

  • Matlab executes the function without any input argument,


  • whereas Octave executes the m-file as a script that defines one or several functions.


Julien Bect <jbect>

 

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

Attach Files:
   
   
Comment:
   

Attached Files
file #37178:  essai1.tar.gz added by jbect (496B - application/gzip)

 

Depends on the following items: None found

Items that depend on this one: None found

 

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

    There are 0 votes so far. Votes easily highlight which items people would like to see resolved in priority, independently of the priority of the item set by tracker managers.

    Only group members can vote.

     

    Follow 8 latest changes.

    Date Changed by Updated Field Previous Value => Replaced by
    2017-08-15 mtmiller StatusNeed Info Fixed
        Open/ClosedOpen Closed
    2016-05-16 jbect Attached File- Added essai1.tar.gz, #37178
    2016-04-29 mtmiller CategoryLibraries Octave Function
        Severity3 - Normal 1 - Wish
        Priority5 - Normal 3 - Low
        StatusNone Need Info
        Release4.0.2 dev

    Back to the top

    Powered by Savane 3.13-54b4.
    Corresponding source code