jruizaranguren
jruizaranguren

Reputation: 13605

Import functions in Matlab for every local function

I have an m-file with a couple of tests defined as local functions. They are called from the main function:

function tests = main_function_test()
    tests = functiontests(localfunctions);
end

I am doing assertions with some tolerance, so I need to import in each local function:

import matlab.unittest.constraints.IsEqualTo;
import matlab.unittest.constraints.AbsoluteTolerance;

in order to make assertions of the form:

verifyThat(testCase, actual, IsEqualTo(expected, ...
        'Within', AbsoluteTolerance(0.00001)));

Is it possible to import those functions just once so they can be reused in each local function?

Upvotes: 0

Views: 490

Answers (2)

Andy Campbell
Andy Campbell

Reputation: 2187

There are two things you can do here.

  1. Use the verifyEqual function (doc) to get most of the functionality you have with verifyThat. Note that there exists the 'RelTol' and 'AbsTol' name value pairs with that function.

  2. Define special local functions to use like import statements. These will have precedence within the file just like you would expect from a file level import.

This looks like so:

function tests = main_function_test()
tests = functiontests(localfunctions);
end

function firstTest(testCase)
testCase.verifyThat(actual, IsEqualTo(expected, ...
        'Within', AbsoluteTolerance(0.00001)));
end

function testASecondThing(testCase)
testCase.verifyThat(actual, IsEqualTo(expected, ...
        'Within', RelativeTolerance(0.0005)));
end

% "import" functions
function c = IsEqualTo(varargin)
c = matlab.unittest.constraints.IsEqualTo(varargin{:});
end
function t = AbsoluteTolerance(varargin)
t = matlab.unittest.constraints.AbsoluteTolerance(varargin{:});
end
function t = RelativeTolerance(varargin)
t = matlab.unittest.constraints.RelativeTolerance(varargin{:});
end

Hope that helps!

Upvotes: 1

sco1
sco1

Reputation: 12214

This is not possible per the documentation:

Scope is the function and the function does not share the import list of the parent function. If the import list is needed in a MATLAB function or script and in any local functions, you must call the import function for each function.

That being said, you could use eval with the output from import (cell array of strings) but it's extremely poor coding practice and I highly recommend against doing it.

function trialcode
import matlab.unittest.constraints.IsEqualTo;
import matlab.unittest.constraints.AbsoluteTolerance;

importlist = import;
sub1(importlist)
end

function sub1(L)
for ii = 1:length(L)
    estr = sprintf('import %s', L{ii});
    eval(estr);
end
disp(import)
end

Again, this is technically possible but please don't do it this way. You have little control over the imports (and controlling logic would likely be longer than implicitly importing them in the first place), it's difficult to debug, impossible for MATLAB's compiler to optimize, and makes the code tremendously unclear.

Upvotes: 1

Related Questions