Closed ramcdougal closed 12 months ago
By default, MATLAB classes are value classes. To get the behavior you desire, I think it simply needs to be defined as a handle class.
See comparison of the two types at: https://www.mathworks.com/help/matlab/matlab_oop/comparing-handle-and-value-classes.html
I don't think making the Matlab class a handle class will fix this issue; the issue (as far as I understand) has to do with the C++ object not being garbage collected properly. In other words, we probably have to fix the reference count decrease for the Section by calling the correct NEURON functions in the correct order.
I think handle class specification would impact calls to underlying C++ object constructors.
If there's a need to explicitly call the C++ object destructors, then that likely requires to implement explicitly the handle class destructor to make sure the underlying C++ destructor is called.
@vijayiyer05 Making Section a handle subclass now makes matlab call delete() as expected.
@ramcdougal However, the C++ object still is not deleted properly. I have tried a few ways to delete the Section but I run into some problems. When I follow the example in https://github.com/mcdougallab/neuron-c-api-demos/blob/delete-section/delete-section-demo/delete-section-demo.cpp#L64, by using:
function delete(self)
self.push();
clib.neuron.hoc_oc("delete_section()");
clib.neuron.nrn_sec_pop();
end
The first run (of example_allsec) goes well, but upon subsequent runs I get warnings:
nrn_test: Accessing a deleted section
near line 0
delete_section()
^
Warning: The following error was caught while executing 'neuron.Section' class destructor:
Error using clib.neuron.nrn_sec_pop
User Library threw std::exception with message:'hoc_execerror: Accessing a deleted section'.
Error in neuron.Section/delete (line 61)
clib.neuron.nrn_sec_pop();
Error in clearvars (line 107)
evalin('caller', clearExpr);
Error in example_allsec (line 2)
clearvars -except testCase; % Make sure testing params are not cleared.
> In clearvars (line 107)
In example_allsec (line 2)
nrn_test: Accessing a deleted section
near line 1
delete_section()
^
delete_section()
nrn_test: Section access unspecified
near line 0
^
Warning: The following error was caught while executing 'neuron.Section' class destructor:
Error using clib.neuron.nrn_sec_pop
User Library threw std::exception with message:'hoc_execerror: Section access unspecified'.
Error in neuron.Section/delete (line 61)
clib.neuron.nrn_sec_pop();
Error in clearvars (line 107)
evalin('caller', clearExpr);
Error in example_allsec (line 2)
clearvars -except testCase; % Make sure testing params are not cleared.
> In clearvars (line 107)
In example_allsec (line 2)
nrn_test: Accessing a deleted section
near line 1
delete_section()
^
delete_section()
nrn_test: Section access unspecified
near line 0
^
Warning: The following error was caught while executing 'neuron.Section' class destructor:
Error using clib.neuron.nrn_sec_pop
User Library threw std::exception with message:'hoc_execerror: Section access unspecified'.
Error in neuron.Section/delete (line 61)
clib.neuron.nrn_sec_pop();
Error in clearvars (line 107)
evalin('caller', clearExpr);
Error in example_allsec (line 2)
clearvars -except testCase; % Make sure testing params are not cleared.
> In clearvars (line 107)
In example_allsec (line 2)
nrn_test: Accessing a deleted section
near line 1
delete_section()
^
delete_section()
nrn_test: Section access unspecified
near line 0
^
Warning: The following error was caught while executing 'neuron.Section' class destructor:
Error using clib.neuron.nrn_sec_pop
User Library threw std::exception with message:'hoc_execerror: Section access unspecified'.
Error in neuron.Section/delete (line 61)
clib.neuron.nrn_sec_pop();
Error in clearvars (line 107)
evalin('caller', clearExpr);
Error in example_allsec (line 2)
clearvars -except testCase; % Make sure testing params are not cleared.
> In clearvars (line 107)
In example_allsec (line 2)
I am now wondering if I need to be using clib.neuron.section_unref(self.sec)
in the destructor.
Update: I think it's fixed now!
Running
leaves TWO sections, both called "dend2"