Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is self-reference possible in MATLAB?

As noted here, functions in packages, as well as static methods in classes, still need to use a packagename.functionname syntax or import packagename.* for each function (since the imports are part of the function workspace and not global). This means that changing the package/class name later on can become a tedious nuisance.

Is there any way to do something like import this.*, i.e. a package/class name agnostic method to access all functions/static methods in the same package/class?

like image 287
Tobias Kienzler Avatar asked Apr 12 '11 14:04

Tobias Kienzler


3 Answers

So... doesn't this require importthis to also be imported? Or is importthis a function you always have in your path?

It seems hardly more complex to just paste an "import this" block with this at the top of each function, and then you don't have to worry about importthis being in your path. I tend to feel that reliance on path is dangerous.

"Import This" block

%% Import own package
[~, pkgdir] = fileparts(fileparts(mfilename('fullpath')));
import([pkgdir(2:end) '.*']);

You can even put it in a try/catch block to make sure it's in a package directory, and decide what to do if it's not.

%% Import own package
try
    [~, pkgdir] = fileparts(fileparts(mfilename('fullpath'))); 
    import([pkgdir(2:end)'.*']);
catch err
    if ~strcmp(err.identifier,'MATLAB:UndefinedFunction'), rethrow(err); end
end
like image 200
Randy Avatar answered Oct 10 '22 22:10

Randy


I recently ran into a similar problem and found the following solution for packages. However it is VERY hacky.

You create a function called import this with an optional argument.

function to_eval = importthis(exclude_list)
if nargin == 0
    exclude_list = [];
end
var_name = genvarname('A', exclude_list); %avoid shadowing
to_eval = ['[~,'...
    , var_name...
    , ']=fileparts(fileparts(mfilename(''fullpath'')));'... %get containing dir
    , 'eval([''import '','...
    , var_name...
    , '(2:end),''.*'']);'... %remove '+'
    , 'clear '... %clean up
    , var_name
    ];
end

This function returns a string which can then be evaled that imports the "this" package. So in your package functions you would put the following near the top:

function B = myfunc(A)
eval(importthis);
%function body
end

You can also pass who to importhis, leaving your function's namespace clean.

function B = myfunc(A)
eval(importthis(who));
%function body
end

I can't decide whether I should feel proud or discusted by what I did.

like image 4
AE426082 Avatar answered Oct 10 '22 22:10

AE426082


This probably is not a bounty worthy answer but as you do not have any answers I thought I would post it anyway! You can invoke static methods via an instance of the class which you would only need to define once. You can invoke functions via a function handle but this would require one handle per function.

Using these techniques you could define all your static method and function references in one place. Then you would use these references throughout your package. Then if you decided to change the package name at a later point you would only need to update these references which are all stored in one place.

See:

Calling Static Methods

You can also invoke static methods using an instance of the class, like any method:

obj = MyClass;

value = obj.pi(.001);

function_handle (@)

The following example creates a function handle for the humps function and assigns it to the variable fhandle.

fhandle = @humps;

like image 3
Mark McLaren Avatar answered Oct 10 '22 21:10

Mark McLaren