2

I'm asking this question to test a concept. I'm not trying to have a solution presented in code, I simply need advice as to what direction to continue.

I would like to make a structure field that is always a function of other fields of the same structure.

I have been able to implement code that can modify the existing structure and update it with a new field. But this doesn't work without re-initializing a code this is not ideal.

I need the ability to add another structure, give it values for certain fields, then automatically update the rest of the fields via functions I have defined.

Is a structure even the right method to accomplish this task? I think it isn't but I am not sure what method can be used.

I've attached a very simple code snippet to demonstrate the problem.

    module = struct('dim', [ 3 1 0.05], ...
                    'point', [0 0 0],   ...
                     'shape', cubeshape(module.dim,module.point))
                              % cubeshape is my function of dim & point

matlab returns an error....

    Undefined function or variable 'dim'.

this makes sense because the struct() function has not yet been closed which means that the module struct has not yet been defined.

If my question is too novice, please just tell me I can continue to research, but some guidance would be appreciated.

Thanks!

ShadowMan
  • 381
  • 2
  • 10

1 Answers1

5

You can set the 'shape' field to a function handle:

module = struct('dim', [3 1 0.05], ...
                'point', [0 0 0], ...
                'shape', @()cubeshape(module.dim,module.point))

And then access the value of the 'shape' field via

module.shape()

However, you'll find that if you change the value of module.dim in your struct, the values returned by module.shape() do not get updated. This is because the two function handle parameters gets set at the time of instantiation. You probably don't want this. Instead you can pass module.dim and module.point into your function handle as arguments:

module = struct('dim', [3 1 0.05], ...
                'point', [0 0 0], ...
                'shape', @(dim,point)cubeshape(dim,point))
module.shape(module.dim,module.point)

It's less graceful, but solves the problem, as the current values of module.dim and module.point will be used.

There are numerous other ways to solve your problem. The most standard is via object-oriented approaches. However, sometimes, that can be like swatting a fly with a sledgehammer (a very slow sledgehammer sometimes in Matlab's case). You may be able to do what you need with functions and some re-thinking of your problem.

Community
  • 1
  • 1
horchler
  • 18,384
  • 4
  • 37
  • 73
  • Thank you for the good response. Say that I want to add, 3 more modules to the structure, they all may have different dim and point values. Would I have to call module.shape(module.dim,module.point) each time? – ShadowMan Aug 07 '13 at 19:24
  • I don't know what you mean by "add 3 more modules to the structure". Your structure itself is called `module`. Do you mean an array of structures, i.e. `module(1) = struct(...)`, `module(2) = struct(...)`,...? Or do you mean adding more fields? [This video](http://blogs.mathworks.com/pick/2008/04/22/matlab-basics-array-of-structures-vs-structures-of-arrays/) might help you. – horchler Aug 07 '13 at 19:35
  • Sorry my terminology is lacking. I want to make more module structures in a structure array. i.e. `module(1) = struct(...)`, `module(2) = struct(...)` and I would like to have the `shape` field of each of these structures correspond to the `dim` and `point` – ShadowMan Aug 07 '13 at 19:43
  • 1
    For a struct array you have to call `module(i).shape(module(i).dim,module(i).point);` But if you're using the same function `cubeshape` for every element of your struct array there may be no point in even having it in your structure. Maybe the structure should contain the result of the function, but to do that you need to keep track of every time any of the fields are modified (something you can easily do with object-oriented programming). – horchler Aug 07 '13 at 19:59