jjg
jjg

Reputation: 1024

Matlab "class handles"?

I'd like to iterate over Matlab classes. Is this possible?

My application has several subclasses based on different structures and algorithms, but each subclass implements the same (class and instance) methods. So it is natural for me to have test-cases which have the subclass as a parameter. In Ruby, for example, this is would be easy

[ClassA, ClassB].each do |cls|
  if cls.some_class_method? then
    instance = cls.new
    :
  end
end

but I don't seem to be able to find a way to do this in Matlab, there don't seem to be "class handles".

Is there a way?

[edit]

Following @zeeMonkeez's solution I ended up with the following

function varargout = call_method(class_name, method_name, varargin)
  qualified_name = sprintf('%s.%s', class_name, method_name);
  [varargout{1:nargout}] = feval(qualified_name, varargin{:});
end

which I can call in my test-case like

class_name = 'MVPolyCube';
  :
[x, y, z] = call_method(class_name, 'variables');

which solves my problem and DRYs up my test suite. Thanks all!

Upvotes: 1

Views: 112

Answers (1)

zeeMonkeez
zeeMonkeez

Reputation: 5157

If you don't mind using feval, you could do something like the code below. Basically, we test if a static method of a given name exists for a class name (using meta.class). Then we get the return value of said method using feval. Based on that, we instantiate an object or not (again using feval).

A.m:

classdef A
    methods
        function whoami(this)
            fprintf('I am an A\n');
        end
    end
    methods(Static)
        function out = a
            out = true;
            fprintf('A.a returns %i\n', out);
        end
    end
end

B.m:

classdef B
    methods
        function whoami(this)
            fprintf('I am a B\n');
        end
    end
    methods(Static)
        function out = a
            out = false;
            fprintf('B.a returns %i\n', out);
        end
        function out = b
            out = true;
            fprintf('B.b returns %i\n', out);
        end
    end
end

has_static_method.m, will be used to test if a class has a static function:

function res = has_static_method(class_name, method_name) 
    mc = meta.class.fromName(class_name);
    ml = mc.MethodList;
    ml = ml([mc.MethodList.Static]);
    res = any(strcmp(method_name, {ml.Name}));
end

test.m:

classes = {'A', 'B'};
for i_c = 1:numel(classes)
    klass_name = classes{i_c};
    static_function_name = 'a';
    if has_static_method(klass_name, static_function_name) && feval(sprintf('%s.%s', klass_name, static_function_name))
        an_object = feval(klass_name);
        an_object.whoami
    end
    static_function_name = 'b';
    if has_static_method(klass_name, static_function_name) && feval(sprintf('%s.%s', klass_name, static_function_name))
        an_object = feval(klass_name);
        an_object.whoami
    end
end

Upvotes: 1

Related Questions