Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can you import a package *after* using its content in a function?

I'm on MATLAB R2014b and have a question that I will illustrate with the following example.

MWE can be made as follows or download it as a .zip file here.

Create a package folder +test on your path with four function files in it:

+test
    a.m
    b.m
    c.m
    d.m

Content of a.m:

function a
disp 'Hello World!'

Content of b.m:

function b
a

If you run b from the command line, you will have to import the test package first (import test.*) or run test.b.

Running b will result in an error, since the scope of function b doesn't contain function a. We must import it before it can be used. For this I've created c.m:

function c
import test.*
a

Now running c works fine.

Now my question. If I change c.m to (saved in d.m):

function d
a
import test.*

I.e. the import command is issued after the call to package function a. Running d still works just fine, as if the position of the import command in d.m does not matter. The import appears to have occurred before the call to function a, which in d.m happens on the line before the import.

Why does this happen. Is this the intended behaviour and what are its uses? How and in what order does MATLAB read a .m file and process it? And more off-topic, but in general: how is importing packages handled in different languages compared to MATLAB, does the order of commands matter?

My preemptive conclusion based on the comments: It is probably best practice to only use the import function at or near the beginning of MATLAB code. This makes clearly visible the imported content is available throughout the entire element (e.g. function). It also prevents the incorrect assumption that before the import, the content is not yet available or refers to a different thing with the same name.

like image 210
Erik Avatar asked May 23 '16 09:05

Erik


People also ask

What does from module import * mean in Python?

It just means that you import all(methods, variables,...) in a way so you don't need to prefix them when using them.

What is the difference between import and import * in Python?

Artturi Jalli. The difference between import and from import in Python is: import imports the whole library. from import imports a specific member or members of the library.

Can we import package inside function Python?

Importing inside a function will effectively import the module once.. the first time the function is run. It ought to import just as fast whether you import it at the top, or when the function is run.

Why do we import packages in Python?

This makes a project (program) easy to manage and conceptually clear. Similarly, as a directory can contain subdirectories and files, a Python package can have sub-packages and modules.


1 Answers

MATLAB performs static code analysis prior to evaluating a function in order to determine the variables/functions used by that function. Evaluation of the import statements is part of this static code analysis. This is by design because if you import a package and then use it's functions, MATLAB needs to know this during the static code analysis. As a result, regardless of where you put the import statement within your function, it will have the same effect as if it were at the beginning of the function.

You can easily test this by looking at the output of import which will list all of the current imported packages.

+test/a.m

function a(x)
    disp(import)
    import test.*
end

test.a()

%   test.*

This is why the documentation states to not put an import statement within a conditional.

Do not use import in conditional statements inside a function. MATLAB preprocesses the import statement before evaluating the variables in the conditional statements.

function a(x)
    disp(import)
    if x
        import test.*
    else
        import othertest.*
    end
end

test.a()

%   test.*
%   othertest.*

The only way to avoid this behavior is to allow the static code analyzer to determine (without a doubt) that an import statement won't be executed. We can do this by having our conditional statement be simply a logical value.

function a()
    disp(import)
    if true
        import test.*
    else
        import othertest.*
    end
end

test.a()

%   test.*

As far as importing compared to other languages, it really depends on the language. In Python for example, you must place the import before accessing the module contents. In my experience, this is the typical case but I'm sure there are many exceptions. Every language is going to be different.

like image 178
Suever Avatar answered Sep 26 '22 01:09

Suever