Jump to content

Force the use of class data accessors (Property or VI) by class members


Recommended Posts

Is there some way to force the use of class data accessors to access class data for class members? My use case is I simply don't want the use of unbundle node to be used. I like to massage the data (sometimes) before it's accessed and want to make sure developers and users of the data only access it through the accessors (VIs or Property nodes). Perhaps there's another way to enforce this? Note: This need is for members within a class, you can't do unbundle outside the class already.

 

This also raises another philosophical discussion on the decision between VIreadwrite vs propertyreadwrite. What are the best practices for this and what are the factors in deciding one over the other?

Link to comment
This also raises another philosophical discussion on the decision between VIreadwrite vs propertyreadwrite. What are the best practices for this and what are the factors in deciding one over the other?

 

For me I use accessors in all cases except where I'm making specific attempts to work in-place, often when manipulating large arrays or variants for example.

 

It goes without saying that most of my accessors are declared as inline such that there's no functional difference between the accessor and an unbundle proper (this is the default for VIs created via the project explorer's template).

 

I doubt there's a way to prevent using the bundling primitives.

  • Like 1
Link to comment

Some options:

  1. Lock the class so that only people you trust can edit it.
  2. Add a VI analyzer test that checks that each element in the cluster is only bundled/unbundled in a single VI.
  3. Encrypt the data in the cluster and put the encryption/decryption code in your locked VIs. I'm going to assume you're not going to use this one.

 

This also raises another philosophical discussion on the decision between VIreadwrite vs propertyreadwrite. What are the best practices for this and what are the factors in deciding one over the other?

 

Assuming there are no bugs or performance issues with the property node call, I think the answer to this is very simple: if the VI has more than one input/output, you call the VI, because you can't use the node. Otherwise, it's a matter of taste and personal preference. You would probably call the node if you want to do a direct DVR access or if you want to serialize calls. I often use the node if I don't want to create icons for the VIs and that API isn't one that needs them. Personally, for VIs which have properties, I almost always use the node.

  • Like 2
Link to comment
This also raises another philosophical discussion on the decision between VIreadwrite vs propertyreadwrite. What are the best practices for this and what are the factors in deciding one over the other?

There were bugs with PNs early on, so I avoided them - and it stuck.

Link to comment
Is there some way to force the use of class data accessors to access class data for class members? My use case is I simply don't want the use of unbundle node to be used. I like to massage the data (sometimes) before it's accessed and want to make sure developers and users of the data only access it through the accessors (VIs or Property nodes). Perhaps there's another way to enforce this? Note: This need is for members within a class, you can't do unbundle outside the class already.

 

This also raises another philosophical discussion on the decision between VIreadwrite vs propertyreadwrite. What are the best practices for this and what are the factors in deciding one over the other?

It sounds like your class has become to big manage. I've never had this requirement.

Link to comment
Is there some way to force the use of class data accessors to access class data for class members? My use case is I simply don't want the use of unbundle node to be used. I like to massage the data (sometimes) before it's accessed and want to make sure developers and users of the data only access it through the accessors (VIs or Property nodes). Perhaps there's another way to enforce this? Note: This need is for members within a class, you can't do unbundle outside the class already.

 

This also raises another philosophical discussion on the decision between VIreadwrite vs propertyreadwrite. What are the best practices for this and what are the factors in deciding one over the other?

 

Is this purely for read accessors? Why not massage the data when you write it, and store it in that state, rather than massaging it on the way out? Of course, this just moves the issue to the bundle/set method instead of the unbundle/read method. At some point, I think you can only get so much compile time protection, and protect a developer from themselves so much

 

I am of the opinion (and this is just my opinion) that this would be a bit of an unnecessary enforcement, since I think you could just call the member variable something more descriptive like "scaled data" rather than "raw data" and store data in the scaled state. I think for a most developers this would be enough to imply what needs to be done. That said, I can see why this could be beneficial. On the other hand, since this is only the case for accessors when used inside the class (private accessors?), it implies some enforcement over what a class can do to its own private data, which seems a bit off.

 

Edit: the more I think about this, is this a code smell for the possibility that the data you are accessing in this class should be moved to another class? Then, the initial class could hold the new class in its member data. The new class could provide public methods or accessors that the current class would now be forced to call in order to set and "massage" the data? I know this doesn't directly answer your question, but I think it would resolve the enforcement issue you're having (i think...)

Edited by for(imstuck)
Link to comment

I've been bitten a few times by having to edit a class such that some of its data has to be coerced/validated on access (be it reading or writing). It is far easier to do this if you've stuck to the rule of using accessors from the beginning: all you need to do is place the new code in one place rather than tracking down every place which operates on the data. This is the main reason I use accessors-- except for when inplaceness is required/desired.

 

I love the idea of a VI analyzer test.

 

As for properties, I've largely stopped using them due to buggy behavior I've observed over the years and have continued to see as of LabVIEW 2012. I also see no reason to wrap all my access around error logic.

  • Like 1
Link to comment
This also raises another philosophical discussion on the decision between VIreadwrite vs propertyreadwrite. What are the best practices for this and what are the factors in deciding one over the other?

 

There are of course numerous approaches and personal preferences to that matter, so this is how I generally handle it:

 

First of all, each element of my class private data is accessible via property nodes, however there are some exceptions for arrays >> you can't have an index terminal on a property node :throwpc:

Some of the properties are public, some are private, some are read or write only. However each property has a read and a write accessor for use by the class itself (no bundle/unbundle)

All data that is absolutely required for the general function of my class is presented by member VIs. However you could use the public read/write properties to directly access data or get additional information if necessary and possible (remember some of the properties are private :shifty: ).

Also the member VIs do not necessarely just return the private data, but they return data in a way the developer can handle it (Trying to avoid complex clusters).

 

If NI would allow us to create property node hierarchies and invoke nodes all the considerations would not be necessary... Just thinking about it makes me so :rolleyes:

 

As for properties, I've largely stopped using them due to buggy behavior I've observed over the years and have continued to see as of LabVIEW 2012. I also see no reason to wrap all my access around error logic.

 

You mind sharing your experience / knowledge?

My applications are heavily based on property nodes and there is just one nasty issue I found up till now >> Property nodes are slowing down the IDE if they contain complex data (class, clusters). :angry:

Link to comment

I've heard that if you name the property folders akin to polymorphic Menu items then you'll have a property node hierarchy.  I've never actually tried it though.

 

Read:Data

Read:Status

Read:Otherstuff

Write:Data

Write:Status

 

should give you a hierarchy when choosing the property node with Read and Write sub-menus.

  • Like 1
Link to comment
I've heard that if you name the property folders akin to polymorphic Menu items then you'll have a property node hierarchy.  I've never actually tried it though.

 

Read:Data

Read:Status

Read:Otherstuff

Write:Data

Write:Status

 

should give you a hierarchy when choosing the property node with Read and Write sub-menus.

 

Just tried, but unfortunately LabVIEW removes the colon :o Tried 10 times

However I'm stuck with LabVIEW 2011, so maybe its a new feature?

 

EDIT:

 

Found a thread that describes what you mean: http://lavag.org/topic/13581-property-node-names/

Mr. Mike described how to do that >> Thanks man! :worshippy:

 

The long name is what shows in the property selection menu (when you click on an item in the property node). This name is also used to structure that menu. If there is a colon in the long name, you'll get a submenu ("pull-right"). e.g.: If you had two properties with long names "Color:Foreground" and "Color:Background," they would both be in a "Color" menu listed as "Foreground" and "Background."

 

The Long Name can be set in the editor by going to the class properties dialog (i.e. right clicking on the class and selecting "Properites"), selecting "Item Settings" and choosing the property you want to edit. The same for the Short Name.

 

Set the Long Name with a colon and you'll get a nice property selection list! :wub:

 

@shoneill: You're the best, thanks! :thumbup1:

Edited by LogMAN
Link to comment
You mind sharing your experience / knowledge?

My applications are heavily based on property nodes and there is just one nasty issue I found up till now >> Property nodes are slowing down the IDE if they contain complex data (class, clusters). :angry:

 

The slow down was probably the biggest one, though I believe that was addressed some time ago. I'm still not convinced property nodes were the cause though so much as poor architecture on my part, the project that exhibited the behavior was old and refactoring has since improved it considerably.

 

I have also seen properties "go bad", wherin they turn black and become unwirable: here and here. I've also had a few cases where using a property node broke the VI, but replacing the property node with the actual VIs worked just fine, this was posted some time ago to lava but my searching is failing me. I have also seen problems with property nodes getting confused about their types, where a VI will suddenly break a wire because of an apparent type mismatch between source and sink, however deleting the wire and rewiring works just fine.

 

The kicker about these issues is they tend to creep up in re-use libraries seemingly randomly, and to fix any of them I need to trigger recompiles in those libraries, which sends source code control into a tizzy. My work around: I no longer use property nodes in re-use libraries, and as habit I rarely use them other code either because who knows when something will get promoted to a library.

  • Like 1
Link to comment
The slow down was probably the biggest one, though I believe that was addressed some time ago. I'm still not convinced property nodes were the cause though so much as poor architecture on my part, the project that exhibited the behavior was old and refactoring has since improved it considerably.

 

I have also seen properties "go bad", wherin they turn black and become unwirable: here and here. I've also had a few cases where using a property node broke the VI, but replacing the property node with the actual VIs worked just fine, this was posted some time ago to lava but my searching is failing me. I have also seen problems with property nodes getting confused about their types, where a VI will suddenly break a wire because of an apparent type mismatch between source and sink, however deleting the wire and rewiring works just fine.

 

The kicker about these issues is they tend to creep up in re-use libraries seemingly randomly, and to fix any of them I need to trigger recompiles in those libraries, which sends source code control into a tizzy. My work around: I no longer use property nodes in re-use libraries, and as habit I rarely use them other code either because who knows when something will get promoted to a library.

 

Turns out LabVIEW is connected to this forum. It has given me the right answer directly after my innocent question...

The issues you described are exactly what happened to me today while changing a whole class tree, RIP project!

 

B) The property node mechanism is nothing more than syntactic sugar around the subVIs. Since I eliminate the error terminals from my property accessors these days, the property node syntax isn't even an option for me -- the dataflow advantages (not forcing fake serialization of operations that don't need serialization) are obvious... the memory benefits of not having error clusters are *massive* (many many cases of data copies can be eliminated when the data accessors are unconditional). 

 

I've been trying to broadcast that far and wide ... it isn't that property nodes are slow or getting slow. It's that the LV compiler is getting lots smarter about optimizing unconditional code, which means that if you can eliminate the error cluster check around the property access LV can often eliminate data copies. This gets even more optimized in LV 2013. That means creating data accessor VIs that do not have error clusters, which rules out the property node syntax.

 

Interesting point...

I'll take that in mind for my future development. I always considered property nodes as a huge advantage over accessor VIs when it comes to large amount of elements (you know its small and tidy...). It seems there are some major drawbacks!

 

The whole 'Error Cluster Everywhere!' story is also something I'm very concerned / confused about. In many cases I just have an error terminal going in-out with no particular meaning to my VI, just to maintain facade.

Is it a way to get rid of the 'IDE slowing down' issue if I remove all the case structures from the property Read/Write VIs?

Link to comment

> It seems there are some major drawbacks!

 

Didn't used to be, and there may not be again in the future. Various folks have talked about reworking the property node to allow VIs that don't have error terminals. there's already a way to disable the error cluster on the property node itself (rarely used and little known popup menu item).

 

> Is it a way to get rid of the 'IDE slowing down' issue

> if I remove all the case structures from the property Read/Write VIs?

 

This isn't an "IDE slowing down" issue. This is "my code runs slower at runtime". The choice to use property nodes vs subVIs has *nothing* -- repeat *nothing* -- to do with any IDE slowdowns.

 

Unfortunately, just writing your diagrams to wire the error cluster through and using that popup menu option doesn't suffice -- the property node adds a case structure around every VI call because the syntax of the property node promises not to execute properties if the first one returns an error and it doesn't know whether or not the subVI is going to pass that error wire through unmodified or not when it compiles the caller.

Link to comment
> Is it a way to get rid of the 'IDE slowing down' issue

> if I remove all the case structures from the property Read/Write VIs?

 

This isn't an "IDE slowing down" issue. This is "my code runs slower at runtime". The choice to use property nodes vs subVIs has *nothing* -- repeat *nothing* -- to do with any IDE slowdowns.

 

Unfortunately, just writing your diagrams to wire the error cluster through and using that popup menu option doesn't suffice -- the property node adds a case structure around every VI call because the syntax of the property node promises not to execute properties if the first one returns an error and it doesn't know whether or not the subVI is going to pass that error wire through unmodified or not when it compiles the caller.

 

I see, two different matters. An interesting point for further investigation... Thanks for clarification!

I will have to run some tests to fully understand the actual impact that is caused by error clusters (speaking at runtime now!).

 

I'll take that 'IDE Slowdown' matter into a different thread as it has nothing more to do with the topic at hand.

 

:beer_mug:

Link to comment

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.