1

So I have the following (simplified) project structure.

scripts/
   client.m
src/
    +estimators/
        @estimator1/
            3party/
                shell_script.sh
            estimator1.m 
                

Basically, what I try to do is, calling estimator1.m from client.m. This is working very well, no issues. However, from within estimator1.m I try to call shell_script.sh. The problem, relative paths do not work since it is always looking from the path client.m is called.

What I tried from estimator1.m is:

pathToScript = fullfile('3Party','shell_script');
system(pathToScript);
    

I would really like to avoid absolute paths since I'd like this package to be used by others as well. So hardcoding paths to my home directory is not good.

Zeitproblem
  • 165
  • 1
  • 12

2 Answers2

4

Use mfilename('fullpath') to get the full path of the currently executing file. Use fileparts to get just the directory part. Putting it together,

scriptdir = fullfile (fileparts(mfilename('fullpath')), '3Party');
Edric
  • 23,676
  • 2
  • 38
  • 40
  • 1
    I was just about to start typing this same answer. :) – Cris Luengo May 13 '22 at 20:06
  • 1
    This is the way. My convention is to create a `resources/` subdirectory underneath the `@blah` directory for a class to hold any data or non-Matlab executable files that are "owned" and managed by that class. – Andrew Janke May 14 '22 at 04:33
  • Do you know how this works with class inheritance? I have a parent class, lets say `abstractEstimator` and all `estimatorX` classes are inheriting from the abstract/parent class. So I thought the smartest way would be to add a function to retrieve `scriptdir` would be to add it to the parent class -> only implement it once but accessible by all child classes. However, this only gives the position of the parent class and not the class where it is actually called from. – Zeitproblem May 14 '22 at 13:51
  • `mfilename` knows nothing about inheritance, it just tells you which actual file is currently executing. Unfortunately, this means that if you want each child class to have a separate `scriptdir`, you'll need each class to have its own call to `mfilename`. – Edric May 16 '22 at 09:58
  • I suppose the other option for class hierarchies is to consider something along the lines of `which(class(obj))` - this should tell you where the child class lives even if you run this in a base class method. – Edric May 16 '22 at 15:33
1

Here is an additional answer to the one by @Edric. My second issue was that I wanted to implement the feature in the parent class since it is a functionality used by all child classes. The proposed answer is perfect when you have the function implemented in the class itself. However:

scriptdir = fullfile (fileparts(mfilename('fullpath')));

would always return the location of my parent class. So I implemented following in the parent class to retrieve the correct location in child classes:

function classdir= getClassDir(obj)             
    [classdir, ~, ~] = fileparts(which(class(obj)));         
end
Zeitproblem
  • 165
  • 1
  • 12