Jump to content

Testing for the same class


Recommended Posts

Isn't there at least one better way to architect so that checking for such equivalence isn't needed?

Indeed: dynamic dispatches.

In my case though simply switching to dynamic dispatches wont work because of a more fundamental flaw in an underlying serialization scheme I invented for my application. I *will* fix the flaw, but it will take time which I can't afford now, so the right way of doing it is going to have to wait.

Link to comment

But we're still back to the same fundamental point: why do you really want to check for such "equivalence"? I know and understand that some people "clearly want to" as you point out but that does beg the question IMO. Isn't there at least one better way to architect so that checking for such equivalence isn't needed?

Lets say you have a JSON stream where each element is an object (which is what JSON is). So it comes in via TCPIP and you create an object of that type using simple string/case detection so that it can be shoehorned into a class ASAP. Depending on what that type is (histogram, chart,value etc) you need to check it's type and do the appropriate processing for that class (e.g. update a chart display).Sooner or later you will need to test the equivalence (since you can't just wire a class to a case structure as you can with strings). To do this you would use the "typeof" in JavaScript if roles were reversed.

I'm all ears on a "better" architecture apart from (of course) not using classes at all - where it becomes trivial.

Link to comment

No, Shaun. You'd create JSON Object.lvclass. As each one comes in, you'd create the object of the named type (all of which inherit from JSON Object), and then invoke "JSON Object.lvclass:Do Appropriate Processing.vi" and each class would have overridden the method to do whatever it needs to do. At no point would you type test.

Ideally you would implement this as an interface, if LV had those, but plain inheritance would suffice for the problem as you've described it here. Oh, and you'd be a lot better off than the string testing of the non-OO solution.

Edited by Aristos Queue
Link to comment

No, Shaun. You'd create JSON Object.lvclass. As each one comes in, you'd create the object of the named type (all of which inherit from JSON Object), and then invoke "JSON Object.lvclass:Do Appropriate Processing.vi" and each class would have overridden the method to do whatever it needs to do. At no point would you type test.

Ideally you would implement this as an interface, if LV had those, but plain inheritance would suffice for the problem as you've described it here. Oh, and you'd be a lot better off than the string testing of the non-OO solution.

Show me. The string version (which I already have - see Passa Mak for a rough idea how) is about 15 VIs. If you can do even just a chart in less than 50 hand made VIs with LVPOOP I'd be surprised (It got ugly very quickly, but maybe you have a better grasp on an approach without re-inventing every property and method for every object in LV).

Back OT. I see what you are saying with a JSON object (I think). By adding an extra layer of abstraction, you can take advantage of the dynamic despatch so that type checking isn't required. But inside it is still the same. You still need to create the individual objects (from the string as said), but unless you are prepared to re-code every property and method that LV has in your child classes, you are no better off apart from if you want to substitute an XML version instead. It will still be a monster. If you can type check the object, then you can reduce the properties and methods of your children and get away from the linear escalation of the VIs.

Link to comment
To do this you would use the "typeof" in JavaScript if roles were reversed.

Not to go off topic - but doesn't typeof just return 'object' in javascript for any user defined data types?

E.g.


function Test() {}

alert(typeof new Test()); // alerts 'object'

[/CODE]

  • Like 1
Link to comment

Not to go off topic - but doesn't typeof just return 'object' in javascript for any user defined data types?

E.g.


function Test() {}

alert(typeof new Test()); // alerts 'object'

[/CODE]

Yup (for objects). It will return if it is a boolean, number etc.My bad (good call)."[color=#000000]myobject.prototype" will return the class and you can just check with "===".[/color]

  • Like 1
Link to comment

This is interesting because the JSON example is essentially the same as the problem I'm facing all serialization essentially boils down to the same thing when you think about it. I don't think it would be too difficult to implement via OOP. As AQ said, create a parent class which defines the interface for generating the data stream and any serializable object just overrides that method. Voila, stream generated. Going from stream to object on the other hand requires a factory pattern in the patent class: it would parse the stream for identifiers telling it which child class to use. Once the factory has chosen the right type, deserialization is just a matter of calling another dynamic dispatch which consumes as much of the stream as it requires. These functions would need to be recursable for many stream types, including JSON.

Or maybe I've missed the boat on this one? That's what I was going to do with my project when I get around to making my project work the "right" way.

Link to comment

But we're still back to the same fundamental point: why do you really want to check for such "equivalence"? I know and understand that some people "clearly want to" as you point out but that does beg the question IMO. Isn't there at least one better way to architect so that checking for such equivalence isn't needed?

I can’t say I’ve ever actually wanted to check for equivalence. But I understand not having the time to re-architecture things. In a past career I ran multi-day experiments at a nuclear physics accelerator, and the failure to get equipment working on time could lead to many months delay and tens of thousands of taxpayer dollars wasted. I have fixed high-vacuum system leaks at 4AM with fast curing epoxy, which is very much NOT the “best" way of repairing vacuum leaks, but it’s the only way to do it NOW. It’s a backup plan. It’s a HACK.

Having no ability to fix a problem in a LVOOP program except a time-consuming re-architecture, no ability to “hack” it, certainly has some strong advantages. No ability to pile hack on hack. But you also have no ability to hack it when don’t have any other option but to hack it! It’s like working without a safety net.

— James

Link to comment

This is interesting because the JSON example is essentially the same as the problem I'm facing all serialization essentially boils down to the same thing when you think about it. I don't think it would be too difficult to implement via OOP. As AQ said, create a parent class which defines the interface for generating the data stream and any serializable object just overrides that method. Voila, stream generated. Going from stream to object on the other hand requires a factory pattern in the patent class: it would parse the stream for identifiers telling it which child class to use. Once the factory has chosen the right type, deserialization is just a matter of calling another dynamic dispatch which consumes as much of the stream as it requires. These functions would need to be recursable for many stream types, including JSON.

Interestingly, I also was working on serializing my message classes recently, and, though it didn’t involve testing for equivalence exactly, it was a bit “ugly” in that way, so perhaps its a good example to show (as I might be doing it all wrong). It’s sort of a hack between using the default LabVIEW flattening of objects, and custom flattening with dynamic dispatch.

The only problem I had with the default LabVIEW flattening of my Message objects is size; a simple “Hello World” message is 75 bytes. I wanted to reduce the size of at least my most commonly sent messages. Yet I didn’t want to have to commit to creating Flatten and Unflatten override VIs for every single child message class ever created. I certainly didn’t want to create two extra VIs for every Command-Pattern Style message. I wanted to do a little bit of targeted custom flattening, where it would do me the most good.

One way of making the flattened messages smaller is to use an index to identify the object class, rather than the much longer regular flat format. So the classes with custom flattening do this. But, children of these classes, which don’t have custom overrides, must include a normally-flattened object. That means that there must be some mechanism for the parent “Flatten Data.vi”, called on the child object, to be able to identify that it is not the parent object and thus needs a modified flattened form.

That might be too unclear, but I think that is in the same "anathema to good design” vein as MJE’s quick fix. Here is a picture of the code of the “Flatten Data” vi of the Message class, and overrides for two other classes that are custom-flattened: VariantMessage and OuterEnvelope (a message inside another message).

post-18176-0-58045400-1326063471_thumb.p

As I said, it isn’t pretty. It basically strips out the internal data of the three selected message types, flattening it in custom form, then tests to see if the remnant object is actually of one of those three types and not a child. If it does turn out to be a child, the remnant object is flattened by the normal LabVIEW function. Because I’ve just removed all the data, I can use a straight search function from an array of default objects, but otherwise this is the same as using a type equivalence comparison just as MJE has done.

Except I’m not doing this as a quick hack; I can’t think of a better way to do it. :blink: What am I doing wrong?

— James

Link to comment

Yup (for objects). It will return if it is a boolean, number etc.My bad (good call)."myobject.prototype" will return the class and you can just check with "===".

Nice!

Here is my contribution to find an object's name :P


// Custom TypeOf Function

function returnObjectType(object) {

  // Constructor has syntax 'function Object(){ [native code] }'

  var typeRegex = /function [A-z_][A-z0-9_]*\(/;

  var testType = typeRegex.exec(object.constructor.toString());

  // Parse and return the object's name, otherwise return null

  if (testType != null) {

    // Slice off leading 'function ' and trailing '(' to resolve object's name

    return testType.toString().slice(9, -1);

  }

  return null;

}

 

// Test returnObjectType function

// Constructor for Data Type

function UserDataType() {}

 

document.write(returnObjectType("hi") + '<br />'); // returns String

document.write(returnObjectType(2) + '<br />'); // returns Number

document.write(returnObjectType(true) + '<br />'); // returns Boolean

document.write(returnObjectType(new Array) + '<br />'); // returns Array

document.write(returnObjectType(new UserDataType()) + '<br />'); // returns UserDataType[/CODE]

Link to comment

Nice!

Here is my contribution to find an object's name :P


// Custom TypeOf Function

function returnObjectType(object) {

  // Constructor has syntax 'function Object(){ [native code] }'

  var typeRegex = /function [A-z_][A-z0-9_]*\(/;

  var testType = typeRegex.exec(object.constructor.toString());

  // Parse and return the object's name, otherwise return null

  if (testType != null) {

    // Slice off leading 'function ' and trailing '(' to resolve object's name

    return testType.toString().slice(9, -1);

  }

  return null;

}

 

// Test checkObjectType function

// Constructor for Data Type

function UserDataType() {}

 

document.write(returnObjectType("hi") + '<br />'); // returns String

document.write(returnObjectType(2) + '<br />'); // returns Number

document.write(returnObjectType(true) + '<br />'); // returns Boolean

document.write(returnObjectType(new Array) + '<br />'); // returns Array

document.write(returnObjectType(new UserDataType()) + '<br />'); // returns UserDataType[/CODE]

Great. So you can do my documentation and my client side stuff too :D Funny how you do in your JS exactly what I'm talking about in Labview with strings eh?

Edited by ShaunR
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
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
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.