2

I have a struct with relative sophisticated data trees. for example:

class.data.head{1}.data2

What I wish to get is a variable named data2_link to link with address class.data.head{1}.data2, so that:

(1) if there is any change on class.data.head{1}.data2, it will automatically reflected to data2_link as well, and vise versa.

(2) I do not have to type the long name to access the data at class.data.head{1}.data2.

Thanks!

Chenming Zhang
  • 2,446
  • 2
  • 26
  • 34

3 Answers3

4

Matlab does not support references. The only exception is handle which allows references to objects.

To use it, data2 must be an object with superclass handle, then you could simply write:

data2_link=class.data.head{1}.data2

Note that object oriented matlab significantly slows down your code unless you use Matlab 2015b or newer.

Community
  • 1
  • 1
Daniel
  • 36,610
  • 3
  • 36
  • 69
2

There is an extremely discouraged way to do it. you can create a function handle that evaluates the desired expression:

data2_link = @() evalin('caller', 'class.data.head{1}.data2')

Now every time you need that expression just call it using

>> data2_link()

The extra parentheses are necessary to invoke the function defined by function handle.

Mohsen Nosratinia
  • 9,844
  • 1
  • 27
  • 52
  • 1
    what is the consequence of using this approach? why it is not encouraged? – Chenming Zhang Nov 27 '15 at 22:58
  • 2
    Reasons to [avoid eval](http://de.mathworks.com/help/matlab/matlab_prog/string-evaluation.html) are listed here. Further using `evalin('caller'..` is even worse, because it violates the common notion of a variable scope, resulting in code which is difficult to debug. Further, you can not pass this reference to functions, it will always search in the caller scope for the variable. – Daniel Nov 27 '15 at 23:05
  • 1
    As a hack, this is brilliant, but although I really want to, I just can't bring myself to upvote it because I don't want to encourage someone to actually do this! But thank you for posting the answer anyway! – zelanix Nov 28 '15 at 12:41
1

Just got another idea, you could use subsref to access it and subassign to write. It is not really what I would call a reference because you still need S, but it probably comes as close to it as possible without using OOP.

S=substruct('.','data','.','head','{}',{1},'.','data2')
%previous line is the same as: S=struct('type',{'.','.','{}','.'},'subs',{'data','head',{1},'data2'})
f=subsref(class,S)
Daniel
  • 36,610
  • 3
  • 36
  • 69