Author |
Message
|
smdavies99 |
Posted: Wed Jul 14, 2010 12:02 am Post subject: Declaring a reference |
|
|
 Jedi Council
Joined: 10 Feb 2003 Posts: 6076 Location: Somewhere over the Rainbow this side of Never-never land.
|
I am looking for some comments on the situation where the local Flow Development guidelines state that References must be declared at the beginning of a module.
Ok for those on the input side. However if we look at the following code.
Code: |
DECLARE l_odsContent BLOB;
DECLARE l_odsContent1 CHAR;
DECLARE l_odsXml CHAR;
CALL CopyMessageHeaders();
DECLARE refOutReq REFERENCE TO OutputRoot;
DECLARE refConf REFERENCE TO OutputRoot.XMLNSC.tsns:ContentReq.tsns:content.ns1:Configuration;
DECLARE refReq REFERENCE TO OutputRoot.XMLNSC.tsns:ContentReq;
|
Do a load of stuf... including creating the OutputRoot.XMLNSC... that should make the refReq valid
Code: |
SET l_odsContent = CAST(ASBITSTREAM(refReq OPTIONS l_folderBitStream)AS BLOB CCSID 1208);
SET l_odsXml = CAST (l_odsContent AS CHAR CCSID 1208);
|
The second CAST throws an exception. The developer (who is very inexperienced) says that they were merely following the coding standards. IMHO, declaring a reference before the place where you are referenceing to exists should not be allowed.
Comments?
Thoughts? _________________ WMQ User since 1999
MQSI/WBI/WMB/'Thingy' User since 2002
Linux user since 1995
Every time you reinvent the wheel the more square it gets (anon). If in doubt think and investigate before you ask silly questions. |
|
Back to top |
|
 |
mgk |
Posted: Wed Jul 14, 2010 12:26 am Post subject: |
|
|
 Padawan
Joined: 31 Jul 2003 Posts: 1642
|
Hello. You are correct. Although it is "allowed" in the language, declaring a reference to somewhere that does not exist means that the reference actually points to the root of the tree the reference was being declared to point inside and LASTMOVE will return false. Therefore, references to elements in the Output trees should only be made after the element they want to point to has been created.
Kind 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 |
|
 |
gfrench |
Posted: Wed Jul 14, 2010 12:44 am Post subject: |
|
|
 Acolyte
Joined: 10 Feb 2002 Posts: 71
|
The point is to get the DECLARATION statements at the top of the code, with comments on what they are used for. Proper coding standards!
There is no requirement to initialise the variables or set the references at this point, but in some cases its useful. Not however in this instance where the reference does not exist.
- Keep the declarations where they are, but add proper comments.
- Change the reference refReq to point to OutputRoot
- In the code before the bitstream move the reference to the appropriate place and do an "if lastmove(refReq) then", unless its a mandatory field
Graham |
|
Back to top |
|
 |
elvis_gn |
Posted: Wed Jul 14, 2010 2:32 am Post subject: |
|
|
 Padawan
Joined: 08 Oct 2004 Posts: 1905 Location: Dubai
|
Hi guys,
I've noticed the coding practice of declaring all variables and references right at the top....and I can understand this comes from Java where people like to declare the variables first.
But in broker I don't think it makes sense. I would not want to create a bulk of variables and references which are not even indicative of the values I really want them to hold, right at the start and associate memory for them when I perhaps might not even require them in every instance of that flow or maybe only in the last line of code.
I prefer declaring variables/references right above where I'm going to use them for the first time.
Regards. |
|
Back to top |
|
 |
fjb_saper |
Posted: Wed Jul 14, 2010 3:47 am Post subject: |
|
|
 Grand High Poobah
Joined: 18 Nov 2003 Posts: 20756 Location: LI,NY
|
Well I must confess I use a mix of both.
Declaring some references at the top of the procedure / module but the ref should be valid there when declared and declaring some just before they are being used.
Let's be a little bit more specific...
(note that this is from memory and not necessarily syntactically correct)
Code: |
DECLARE outRef REFERENCE to OutputRoot.XMLNSC.myns:{xmlrootname}.{level1};
-- and further down
MOVE sourceRef TO mysource.listItem[1];
CREATE LASTCHILD OF outRef NAME 'itemList';
DECLARE listItemRef REFERENCE TO outRef;
-- start loop
WHILE LASTMOVE(sourceRef)
CREATE LASTCHILD OF outRef.itemList AS listItemRef NAME 'item';
SET listItemRef.field = sourceRef.field;
-- many more statements
--sets loop exit condition to true:
MOVE sourceRef NEXT SIBLING REPEAT TYPE NAME;
-- END WHILE LOOP
|
Have fun
Hope this helps and makes sense ....  _________________ MQ & Broker admin |
|
Back to top |
|
 |
Vitor |
Posted: Wed Jul 14, 2010 4:02 am Post subject: |
|
|
 Grand High Poobah
Joined: 11 Nov 2005 Posts: 26093 Location: Texas, USA
|
elvis_gn wrote: |
I've noticed the coding practice of declaring all variables and references right at the top....and I can understand this comes from Java where people like to declare the variables first. |
It's not just Java. I write C & VB.NET the same way, and COBOL enforces it (or used to, back in the day).
I prefer to see all the variables in one easy to read block so I can a) ensure that everything I need is defined & b) ensure they're the right type, initialised to the correct (or sensible) values. I accept this associates memory potentially way before it's needed but how much space does an integer or reference use?
My 2 cents of course.  _________________ Honesty is the best policy.
Insanity is the best defence. |
|
Back to top |
|
 |
smdavies99 |
Posted: Wed Jul 14, 2010 4:46 am Post subject: |
|
|
 Jedi Council
Joined: 10 Feb 2003 Posts: 6076 Location: Somewhere over the Rainbow this side of Never-never land.
|
Elvis,
You are describing what I see as a very common thing. I've done it for years especially when writing in Assembler where you had to separate out the I & D stuff or allocating variables on the stack. IF you didn't then the stack wouldn't unwind properly.
That said, I'd be interested in how your method stacks up with what happens under the hood as described by mgk.
mgk wrote: |
declaring a reference to somewhere that does not exist means that the reference actually points to the root of the tree the reference was being declared to point inside and LASTMOVE will return false. |
IMHO declaring something that is not actually what you think it is is bad programming.
You should never (IMHO) declare a pointer into the middle of nowhere which is what my example is doing. The result is that a reference is created but it is not what you might think it is from the code. Then if you start assigning it relative to it, you are in danger of really messing things up.
I'm inclined to agree with Vitor especially where you are referencing the OutputRoot tree. _________________ WMQ User since 1999
MQSI/WBI/WMB/'Thingy' User since 2002
Linux user since 1995
Every time you reinvent the wheel the more square it gets (anon). If in doubt think and investigate before you ask silly questions. |
|
Back to top |
|
 |
mqjeff |
Posted: Wed Jul 14, 2010 5:28 am Post subject: |
|
|
Grand Master
Joined: 25 Jun 2008 Posts: 17447
|
I think when it specifically comes to REFERENCE variables, I will lean towards declaring them only at the point in code when I know they make sense.
The only realistic choices are to do that, or to declare the REFERENCE at the top of the module and explicitly point it at a place that exists and then down where it needs to point somewhere else, do a MOVE.
The MOVE is an extra step that's not entirely necessary -but on the third hand is not otherwise too expensive (well, I guess that depends on how you code the MOVE statement and whether that causes the message tree to be walked more than needed.. I'm looking at you [n]).
Otherwise, having all variable declarations at the top of the module should at least imply that you've planned out what the module is doing enough to know what you need before you get there.
And it's much easier to read, mostly. As long as your modules aren't too long and you've lost the declarations off the top of the page... |
|
Back to top |
|
 |
elvis_gn |
Posted: Wed Jul 14, 2010 8:20 am Post subject: |
|
|
 Padawan
Joined: 08 Oct 2004 Posts: 1905 Location: Dubai
|
Hi,
smdavies99 wrote: |
That said, I'd be interested in how your method stacks up with what happens under the hood as described by mgk.
mgk wrote: |
declaring a reference to somewhere that does not exist means that the reference actually points to the root of the tree the reference was being declared to point inside and LASTMOVE will return false. |
|
This will anyway be a problem irrespective of declaring the reference right on top or 1 line before you actually need it...
My usual logic with pointers is:
1. In case of loops, use FOR loops rather than WHILE and get the reference created in the FOR statement automatically. So if no loop, then no reference declared, and its auto MOVEing.
2. Declare a reference only if I have atleast 3-5 fields to map and the fields are atleast 3 levels deeper within the current pointer. This way I can justify the performance cost of a new pointer.
3. CREATE statements have the AS clause. So you can get the pointer to the correct Output field without a separate statement.
4. Why you do need to keep checking for LASTMOVEs ? Whats the possibility of the same destination field path existing from the pointer and from Root (in case of failed pointer). So you can do most mappings with COALESCE and NULLIFs.
These work most of the time, but you just might need to work around in few cases.
So after doing all this to get small performance improvements, why would I want to declare references right at the top
Regards. |
|
Back to top |
|
 |
Vitor |
Posted: Wed Jul 14, 2010 8:32 am Post subject: |
|
|
 Grand High Poobah
Joined: 11 Nov 2005 Posts: 26093 Location: Texas, USA
|
elvis_gn wrote: |
So after doing all this to get small performance improvements, why would I want to declare references right at the top
|
Because you still need to pre-declare the reference for case 3 to work (a feature I find really useful btw) and you might as well put it at the top with the rest. _________________ Honesty is the best policy.
Insanity is the best defence. |
|
Back to top |
|
 |
|