|
RSS Feed - WebSphere MQ Support
|
RSS Feed - Message Broker Support
|
 |
|
WMB 6 \ REFERENCE to non existing fields. |
« View previous topic :: View next topic » |
Author |
Message
|
hopsala |
Posted: Mon Oct 06, 2008 7:00 am Post subject: WMB 6 \ REFERENCE to non existing fields. |
|
|
 Guardian
Joined: 24 Sep 2004 Posts: 960
|
Found rather an interesting behavior of REFERENCE. Take the following code:
Code: |
DECLARE NameRef REFERENCE TO OutputRoot.MRM.Data.Names;
SET NameRef.FirstName = 'Gauri'; |
When 'OutputRoot.MRM.Data.Names' exists, everything works fine. But when it doesn't exist, NameRef points to the highest point in the tree that does exist.
For example, if 'OutputRoot.MRM.Data' exists, it will point to it; if it doesn't, but 'OutputRoot.MRM' exists, it will point to it; finally, if OutputRoot hasn't been set at all, NameRef will point to OutputRoot so that the output tree will look something like this:
OutputRoot
---FirstName
------'Gauri'
Personally, I find this quite unnerving. The unsuspecting programmer may get rather peculiar output trees in edge cases, which he will have a hell of a time debugging. It also means that the more familiar form of the said code:
Code: |
SET OutputRoot.MRM.Data.Names.FirstName = 'Gauri'; |
is not at all equivalent, which is highly unintuitive. I was not able to find any documentation about all this.
If for some reason IBM was unable to have REFERENCE work properly in these cases, the least they could do is throw an exception, which to me sounds a lot better than selecting some non-determinate (in the programmers POV) point in the tree, yielding unexpected results.
Has anyone come across this? Was this behavior changed in later versions perhaps? I feel like there might be a reason for all this, but I can't quite put my finger on it.. |
|
Back to top |
|
 |
fjb_saper |
Posted: Mon Oct 06, 2008 10:11 am Post subject: |
|
|
 Grand High Poobah
Joined: 18 Nov 2003 Posts: 20756 Location: LI,NY
|
Working as designed.
After setting/moving the reference you are supposed to check LASTMOVE(ref)
Enjoy  _________________ MQ & Broker admin |
|
Back to top |
|
 |
hopsala |
Posted: Tue Oct 07, 2008 7:55 am Post subject: |
|
|
 Guardian
Joined: 24 Sep 2004 Posts: 960
|
fjb_saper wrote: |
Working as designed.
After setting/moving the reference you are supposed to check LASTMOVE(ref) |
It may very well be that this is "working as designed", but it doesn't seem like a very good "design" to me.
Let's take XPath processing for example: say you ask for "/Data/Name/FirstName" which doesn't exist. Naturally, you either get an exception or a null pointer, which usually results in an exception in a later stage if not checked. This is good, healthy design. The programmer is forced to check his results, and nothing unexpected ever occurs - the code either works perfectly, or doesn't work at all, everything rolled back. It seems preposterous to me that the programmer may get the object for "/Data/Name" or "/Data" or even "/" , without so much as an error message or anything to indicate that something went wrong. No Java programmer that I know would stand for such behavior.
So either you throw an exception on MOVE (or on DECALRE with initial value), or you have SET work in the same way with and without references. No? |
|
Back to top |
|
 |
mqjeff |
Posted: Tue Oct 07, 2008 8:00 am Post subject: |
|
|
Grand Master
Joined: 25 Jun 2008 Posts: 17447
|
It is only in Java that one assumes one should catch an exception, rather than check a result code. In many many programming languages, it is normal to check the result of an operation for failure, rather than catch a failure exception.
It is only in very recent versions of Message Broker that ESQL allows you to catch exceptions in your code at all, without using a Try/Catch node. |
|
Back to top |
|
 |
hopsala |
Posted: Wed Oct 08, 2008 11:43 am Post subject: |
|
|
 Guardian
Joined: 24 Sep 2004 Posts: 960
|
True, but ESQL supports exceptions, so why not use it?
But still, here's the case against the current behavior:
1. Even in languages or API's which use code-checking, it is usually the return value which indicates error, not some other function. For example, in C we used to code funcs which returns "-1" rather than the expected value. Instead, we have here a case in which the value is set, but to some other point in the tree. I've never encountered anything like it in any API that I can remember.
2. There's a difference between function and operator behavior. While result checking is quite common with functions, operators just crash in case of error - as they should. "SET XX = XX" isn't really a function, or at least is not perceived as such, and checking results after using operators... Well, it's just plain weird.
3. I still hold the It-Should-Be-Equivalent argument
Anyway, I guess i'll just have to add SET dummy lines whenever I use REFERENCE to output trees, like so:
Code: |
SET OutputRoot.MRM.Data.Names.mleh = NULL;
DECLARE NameRef REFERENCE TO OutputRoot.MRM.Data.Names;
SET NameRef.FirstName = 'Gauri'; |
Which is a pain, but such is life. Cheers! |
|
Back to top |
|
 |
mgk |
Posted: Wed Oct 08, 2008 1:57 pm Post subject: |
|
|
 Padawan
Joined: 31 Jul 2003 Posts: 1642
|
Hi.
I think I should correct some small points on this thread:
Quote: |
When 'OutputRoot.MRM.Data.Names' exists, everything works fine. But when it doesn't exist, NameRef points to the highest point in the tree that does exist. |
I believe that this is incorrect, as the example I give below shows. What actually happens is that when the target of a REFERENCE being DECLAREd does not exist, the reference actually points to the root of the tree in which the reference was being created (OutputRoot in the quote above). This is documented in the infocenter in topic ID ak04864. (If you are seeing different behaviour here then maybe this could been fixed in a fixpac?)
With regards to exceptions, REFERENCES were added to ESQL long before the ability to catch an exception with a handler was added. This meant that if an an exception was to be thrown when a REFERENCE's target did not exist on a DECLARE then the compute node as a whole would have been exited as mqjeff pointed out. This would not have been acceptable.
With regards
Quote: |
function and operator behavior |
SET is a statement in ESQL and no statement can return a value (only functions can). Therefore, the LASTMOVE function is used to check to see if the previous MOVE (or DECLARE) statements succeded and returns TRUE for success.
This code:
Code: |
SET OutputRoot.XMLNSC.Top.Test1 = 'created';
DECLARE x REFERENCE TO OutputRoot.XMLNSC.Top.Test1.DoesNotExist;
IF( LASTMOVE(x) ) THEN
SET OutputRoot.XMLNSC.Top.Test2.LastMoveReturned = 'true';
ELSE
SET OutputRoot.XMLNSC.Top.Test2.LastMoveReturned = 'false';
END IF;
SET x.result = 42;
|
Produced this tree:
Code: |
(0x01000000):XMLNSC = (
(0x01000000):Top = (
(0x03000000):Test1 = 'created'
(0x01000000):Test2 = (
(0x03000000):LastMoveReturned = 'false'
)
)
)
(0x03000000):result = 42
|
As you can see, result was created at the same level as the XMLNSC folder because x was pointing at OutputRoot as a result of its target field not existing when it DECLAREd (even though XMLNSC and Test1 did exist). And LASTMOVE returned false to allow you to determine this. If you search for "LASTMOVE" in the infocenter you will see several examples of the DECLARE ... LASTMOVE usage.
Also, if you can manage to think of code such as "IF( LASTMOVE(x) )" as being similar to a check for NULL in other languages, such an "if( x == NULL )" in 'C' for example then maybe it will feel a little less strange
I hope this helps to explain things a little.
Regards, _________________ MGK
The postings I make on this site are my own and don't necessarily represent IBM's positions, strategies or opinions. |
|
Back to top |
|
 |
|
|
 |
|
Page 1 of 1 |
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
|
|
|