Function in class not working which normally works

Hi,
I get the message:
Undefined function 'get_Var' for input arguments of type 'char'.
Error in ClmRun/getVar_std_tot (line 35) data = get_Var(file, name);
Error in ClmRun (line 14) data = getVar_std_tot(run, 'area');
when trying to create a variable of the class ClmRun. Strangely, the same kind of function works perfect when I use it in a non-class environment (just a standard function).
Here is the code of the class I try to create:
classdef ClmRun
properties
CASE % The Case name which should be the beginning of all the final files
nlon % Number of grid cells in longitude direction
nlat % Number of grid cells in latitude direction
end
methods
function run = ClmRun(name) % Constructor
if(ischar(name))
run.CASE = name;
data = getVar_std_tot(run, 'area');
else
error('The case of the run should be a string')
end
end
function output(run) % Disp the CASE
disp(run.CASE)
end
function data = getVar(file, name) % Gets the variable name from file
data = netcdf.open(file,'NOWRITE');
data = netcdf.getVar(data, netcdf.inqVarID(data, name));
end
function data = getVar_std_tot(run, name) % Get the standard output multiyear average
file = strcat(run.CASE, '_totavg_standard.nc');
disp(file)
disp(name)
data = getVar(file, name);
end
end
end

댓글 수: 1

That error message:
Undefined function 'get_Var' for input arguments of type 'char'
gives a function name get_Var that does not exist in your code.

댓글을 달려면 로그인하십시오.

 채택된 답변

Adam
Adam 2017년 9월 12일
편집: Adam 2017년 9월 12일
Class functions must take the object of the class as their first argument unless they are static. You are missing this.
function data = getVar_std_tot(obj,run, name) % Get the standard output multiyear average
file = strcat(run.CASE, '_totavg_standard.nc');
disp(file)
disp(name)
data = getVar(file, name);
end
although your function doesn't seem to need the object and nor do you do anything with the returned value so not sure what you are really wanting to do. Make it static if you don't need to object/instance of the class.

댓글 수: 7

Ronny
Ronny 2017년 9월 12일
Okay that was the issue. Thanks. I don't understand what's the reason behind the fact that you always have to hand the object as the first input argument but that's another question.
Adam
Adam 2017년 9월 12일
In any language a class function needs to know the object of the class that it is acting on. In C++ this is hidden from you as the programmer, but is still there. In Matlab, as in other languages you must explicitly pass the object into the function (I have only really ever programmed in Matlab and C++ so I'm not familiar with many languages, but I think there are other scripting languages where the programmer must explicitly pass the object too).
Be careful with your terminology. There are differences between a method of an object (which as Adam said must be called with an instance of that object unless it is a Static method) and a class-related function.
The getVar_std_tot function in this class needs to access properties of the object, so it seems reasonable that it should be a method of the class. Since it only accesses that one property you could instead define it as a class-related function and have whoever calls it pass the properties into it rather than having getVar_std_tot access them internally, but if it were to access more than just that one property I'd leave it as a method. And if it needed to call a method on the object, I would definitely leave it as a method.
The getVar function in this class does not need to access properties of this object, and I assume it's not intended to be called by other code outside of this class itself. If that is the case, I would make it a class-related function by defining it after the end of the classdef block. See myUtilityFcn in the example in the class-related functions section of the documentation page to which I linked above.
Adam
Adam 2017년 9월 13일
I had never actually realised that defining a function after the classdef block was even valid syntax. I guess I've never needed to try, I've always used Static Private functions, but that does add a little more 'noise' than doing it after the classdef block.
Shouldn't
data = getVar(file, name);
be
data = obj.getVar(file, name);
?
Adam
Adam 2017년 9월 15일
Yes, it should actually, and the definition of getVar updated accordingly. I only looked at the signature and glanced quickly at the code inside it!
per,
Yes, if you want to keep getVar as a non-Static method rather than a class-based function it needs to accept an instance of the object as an input. Technically it doesn't have to be the first input, but at least one input has to be an instance of the object.
Why might you want to have a non-Static method where the first input isn't an instance of the class? See the example on the operator overloading documentation page. Using the Adder class as defined on that page you could calculate both Adder(1:10) + 1 and 2 + Adder(1:10). The plus method on the Adder class handles both cases.

댓글을 달려면 로그인하십시오.

추가 답변 (0개)

카테고리

도움말 센터File Exchange에서 Data Type Identification에 대해 자세히 알아보기

태그

질문:

2017년 9월 12일

댓글:

2017년 9월 15일

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by