Dymaxion Fuller
Dymaxion Fuller

Reputation: 105

Accessing an Object from Within an Object

I have created a TestData object that is use by multiple files to put data in a particular format. Here is the class (snipped down version):

classdef TestData
properties
    metaData  = [];  % stores meta data in Nx2 array
end

methods
%% Getters    
    %Meta-Data
    function metaData = get.metaData(this)
       metaData = this.metaData; 
    end    

%% Setters
    %Meta-data
    function this = set.metaData(this, metaData)
        this.metaData = metaData;
    end
end %methods
end %class

One of the files that has access to it is my FileIO object. This handles the case of there being an external file instead of raw data. The problem I seem to be having is with the interface between the two objects. My intent is to be able to read in a file using the readDataFromFile function in FileIO; organize the data inside the FileIO object; and then pass that data to the TestData object, where it can be combed through for final verification and then written to a separate external file.

classdef FileIO < TestData

methods

    function this = readDataFromFile(this, thisFile)
        [filepath, name, ext] = fileparts(thisFile);  
        inFile = textread(thisFile, '%s', 'delimiter', '\n');

        this = this.setMetaDataFromFile(inFile, ext);
        myTestData = TestData;
        myTestData.metaData = this;    
    end %readDataFromFile        

    function this = setMetaDataFromFile(this, inFile, ext)
        strForm = string(inFile);

        if strcmp(ext, '.txt')
            dataBegin = find(~cellfun(@isempty, strfind(inFile, 'start of data')));
            metaDataBegin = find(~cellfun(@isempty, strfind(inFile, 'meta data')));
            metaDataOutForm = strForm(metaDataBegin+1:dataBegin-4);
            metaDataOutForm = cellfun(@(x)strsplit (x, '='), metaDataOutForm, 'UniformOutput', false);

            this.metaData = cat(1,metaDataOutForm{:});
        end
    end

end % Methods
end % Class

I tried inheritance and I have been racking my brain with this for a bit and I just can't seem to be able to find the solution. I can do this no problem from other files that are not classes, which is why I am under the assumption it has to do with the two objects trying to interact. The line where I make an instance of TestData and the the line directly below it are just one of my many attempts to try and solve this issue.

Thank you for the help in advance. If there is anything else I can offer please let me know.

Upvotes: 1

Views: 52

Answers (1)

Cris Luengo
Cris Luengo

Reputation: 60574

I don't see the need for inheritance here.

The closest solution to your current code would be something like this:

classdef FileIO
properties
    metaData  = [];  % stores meta data in Nx2 array
end
methods

    function myTestData = readDataFromFile(this, thisFile)
        [filepath, name, ext] = fileparts(thisFile);
        inFile = textread(thisFile, '%s', 'delimiter', '\n');
        this = this.setMetaDataFromFile(inFile, ext);
        myTestData = TestData;
        myTestData.metaData = this.metaData;
    end %readDataFromFile        

    function this = setMetaDataFromFile(this, inFile, ext)
        % ...
    end

end % Methods
end % Class

Here, FileIO.readDataFromFile returns a TestData object. You'd write:

myFileIO = FileIO;
myTestData = myFileIO.readDataFromFile('filename');

But I think that is a really ugly use of a class, if you create an object, call a single function in it, and then never use the object again, it means you need to have a free function:

    function myTestData = readDataFromFile(this, thisFile)

    [filepath, name, ext] = fileparts(thisFile);
    inFile = textread(thisFile, '%s', 'delimiter', '\n');
    metaData = getMetaDataFromFile(inFile, ext);
    myTestData = TestData;
    myTestData.metaData = metaData;

    function metaData = getMetaDataFromFile(inFile, ext)
    % ...

Here, getMetaDataFromFile is a private function (assuming you don't need to call this on its own). Now you just do:

myTestData = readDataFromFile('filename');

Note that the free function version is easier to call (don't need to create an object that you don't really use), and its code is shorter because it doesn't have a classdef around it.


Another alternative is to make readDataFromFile a method of the TestData class. Note that you can simply move the function we created above into a directory @TestData to make it a method, it doesn't need to be written inside the classdef file.

Upvotes: 1

Related Questions