Jump to content

Ruminations on libraries; not sure I understand hierarchical behavior


Recommended Posts

I’ve been thinking about how best to use libraries in LabVIEW for some time. There are definitely still some things that confuse me a bit, so I thought I’d throw out some questions for the larger community to solicit ideas.

I’m going to focus on LabVIEW project libraries (.lvlib files), as these seem to have the properties in which we are most interested.

I think of project libraries primarily as collections of things. We use these collections in a couple different ways.

Templates and Namespaces

In some cases we have a low-level set of concrete classes and other types of files [e.g., shared variable libraries, XML configuration files, and typedefs (which we only use for Enums and when we need a representation on a View, since classes don’t have controls—but that is another topic altogether)]. For each application the contents of these files vary. (The concrete classes inherit behavior from abstract classes in another set.) So for each application we need to write custom code, but we only need to change a few things. Of course we can copy and rename each class or file one by one, but we have found it practical instead to put the items in template collection (e.g., A.lvlib), and then copy the library to A’. lvlib or A’’.lvlib, and customize the implementations there. Since each project library has its own namespace, we can use the elements of the collection with their original names without creating conflicts.

This may not be an ideal solution, however. It has worked well for us so far.

Note: In UML a “package” (which has a folder icon) has its own namespace and is essentially a collection of elements as well.

Collections for Isolation and Reuse

We also use project libraries as convenient collections of related items we want to group together. We may or may not want to reuse the collections in other applications. (An obvious advantage if we do choose to reuse a project library is that changes to a project library in one instance will reflect in all other instances of that library, so that we only have to make changes once.)

One example of a not for reuse (probably) collection is a set of classes implementing the State Pattern. We have an abstract State class, and then a collection of <ConcreteState> classes. None of the <ConcreteState> classes knows about any of the others (an important improvement we made to our earlier implementation), and State only knows about (via an input on its methods) an abstract Context class (in our implementation actually a Model class, but that isn’t important). What is important is that we can open a project library containing a collection of <ConcreteState> classes, and it only will include the abstract State and Context classes (functioning as interfaces) in the dependencies, so we can focus on implementing the State classes without concerning myself with the implementation — or even presence — of a <ConcreteModel> class.

Then my application consists of an assembly of smaller collections. It seems logical, then, to have a project library containing smaller project libraries.

Here, though, is where I get confused about how project libraries work in LabVIEW. In particular, if we open a project library contained in a larger project library, LabVIEW opens the entire project library hierarchy (i.e., the top-level project library and all its sublibraries). LabVIEW does not allow opening a sublibrary independently. Is that necessary? In particular, such behavior prevents reuse of sublibraries. For instance, if b and c are sublibraries of E, we can’t reuse b in another project without E and c coming along for the ride. That seems odd (and counterproductive). (I think the reason for this is that each element has membership in one and only library, and each member “knows” its library membership. LabVIEW considers a sublibrary simply another element in a superlibrary.)

Note: In the UML tool we use (Enterprise Architect), we can check in a package at any level. We can retrieve any checked-in (controlled) package, and this means we include the controlled package and its subpackages—but not its superpackages—in the new project. This allows us to reuse subpackages in various projects. I wish LabVIEW project libraries worked the same way. Is there some good reason they don’t or can’t? Is there another good way to accomplish the same goal?

Link to comment

...

Note: In the UML tool we use (Enterprise Architect), we can check in a package at any level. We can retrieve any checked-in (controlled) package, and this means we include the controlled package and its subpackages—but not its superpackages—in the new project. This allows us to reuse subpackages in various projects. I wish LabVIEW project libraries worked the same way. Is there some good reason they don’t or can’t? Is there another good way to accomplish the same goal?

AQ's reply in another thread probably explains why subprojects can't be separated.

I think the difficulty is that lvlibs look like a package management system. In reality, lvlibs really aren't very well suited to that function.

JZ

Edited by jzoller
Link to comment

I’m going to focus on LabVIEW project libraries (.lvproj files), as these seem to have the properties in which we are most interested.

"Project libraries" refers to .lvlib files. .lvproj files are just "projects." I'm a little confused by the rest of your post--it's not clear to me when you mean "project" and when you mean "project library."

Of course we can copy and rename each class or file one by one, but we have found it practical instead to put the items in template collection (e.g., A.lvproj), and then copy the library to A’. lvproj or A’’.lvproj, and customize the implementations there. Since each project library has its own namespace, we can use the elements of the collection with their original names without creating conflicts.

To clarify, each open project has it's own application instance, not it's own namespace. Labview creates app instances dynamically when the project is opened or created. Each app instance (open project) has it's own protected memory space that is not accessable from other app instances (open projects.) App instances are a transient construct used to aid souce code development. Project files, as currently implemented, don't really make good containers for distributing reusable code.

Libraries (lvlib, lvclass, etc.) do prepend namespaces to all members; however, namespacing is a side effect of library membership, not a reason for library membership. Only put things in the library if it is required by the other members of the library. Labview's namespacing capabilities aren't as advanced as I'd like them to be and I've been crying about it for a year and a half or so. AQ acknowledged the use case for better namespacing but the idea languishes in obscurity on the idea exchange.

Here, though, is where I get confused about how project libraries work in LabVIEW. In particular, if we open a project library contained in a larger project library, LabVIEW opens the entire project library hierarchy (i.e., the top-level project library and all its sublibraries). LabVIEW does not allow opening a sublibrary independently. Is that necessary? In particular, such behavior prevents reuse of sublibraries.

Yes, it is necessary, and yes, it does prevent sublibraries from being used independently. Libraries are functional collections of related code. In other words, it's a group of vis that are (usually, but not necessarily) interdependent on each other to function correctly. What you're looking for is logical collections of related code you can organize in a hierarchy that makes sense. That's what namespaces are typically used for. Unfortunately Labview's namespacing is tied to library membership. Hopefully they will separate that functionality some time in the near future...

What to do in the meantime? One option is to use library names that are self-namespaced. For example, suppose you wanted an "Instrument" namespace with a sub namespace for "Oscilloscope." If you had one library for an Agilent ModelA and another for an Agilent ModelB, you would have two libraries with the file names:

Instrument.Oscilloscope.AgilentModelA.lvlib

Instrument.Oscilloscope.AgilentModelB.lvlib

Personally I don't do that. It's too painful to reorganize the namespaces when the need arises. Instead my libraries are usually flat (no nesting) and I use virtual folders in the project to do the hierarchical organization. That doesn't help much if you have a large set of reuse libraries that are hierarchical in nature as there's nothing inherent to each library that describes its position in the hierarchy. In that case... documentation?

Link to comment

AQ's reply in another thread probably explains why subprojects can't be separated.

I think the difficulty is that lvlibs look like a package management system. In reality, lvlibs really aren't very well suited to that function.

JZ

Thanks for the link. That does explain this better.

"Project libraries" refers to .lvlib files. .lvproj files are just "projects." I'm a little confused by the rest of your post--it's not clear to me when you mean "project" and when you mean "project library."

What you're looking for is logical collections of related code you can organize in a hierarchy that makes sense. That's what namespaces are typically used for. Unfortunately Labview's namespacing is tied to library membership. Hopefully they will separate that functionality some time in the near future...

Instead my libraries are usually flat (no nesting) and I use virtual folders in the project to do the hierarchical organization. That doesn't help much if you have a large set of reuse libraries that are hierarchical in nature as there's nothing inherent to each library that describes its position in the hierarchy. In that case... documentation?

You are of course correct--I meant .lvlib files. Thanks for the correction!

Yes, I want logical collections; but it is important to be able to use the logical collections in multiple projects in much the same way as I currently use project libraries.

In practice I have found it necessary to move to flatter and flatter hierarchies because of this limitation, but I also find this is often far from ideal when it comes to code reuse.

Link to comment

Yes, I want logical collections; but it is important to be able to use the logical collections in multiple projects in much the same way as I currently use project libraries.

Yeah, I haven't found a way to do this in LV that I'm happy with.

In practice I have found it necessary to move to flatter and flatter hierarchies because of this limitation, but I also find this is often far from ideal when it comes to code reuse.

Same for me. In fact, the only time I use nested libraries is when I'm creating a library (A.lvlib) that needs some functionality provided by another library (B.lvlib) and no part of B will be exposed from A publicly. Then I copy B over to the directory containing the code for A and make the new B a private member of A.

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.