Possibility of creating a variable dynamically

Posted by deb2001 on 13-Apr-2009 23:23

Hello Guys,

               wanted to know if it is possible to create a variable at runtime with different data type at different runs ?

     What I'm looking for is -

                                         I need to return a value from a procedure where I would not know the data type of my return value for fixed. it would be character for some, but could be integer or date also. I do have the information of the data type from a DB field mentioned in another parameter, so accrodingly need to throw out the return value for the same data type.

Now can we have something like -

create a handle. then create a variable like that field on that handle , like any other dynamic object creation.

IS IT POSSIBLE ?

Progress 9.1E

OE 10.1C

AIX 5.3

TIA

Debayan

All Replies

Posted by Admin on 13-Apr-2009 23:45

Hello Debayan,

ordinary variables don't have handles in the ABL so you can't create them at runtime and return a handle.

You could:

  • create an object dynamically (DYNAMIC-NEW) and return that as a parameter of Progress.Lang.Object. You'd need a class with a single property for each possible data-type you wanna return. Be aware that in 10.1C the caller will have to delete the returned object as garbage collection is only available in 10.2A.
  • create a temp-table with a single field individually. As your description contains some dependency on database fields, that might make sense. But creating temp-tables at runtime has some overhead - so I wouldn't do that over and over in a loop.
  • have a number of output parameters for each possible data-type

DEFINE OUTPUT PARAMETER poChar AS CHAR NO-UNDO.

DEFINE OUTPUT PARAMETER poInt AS INTEGER NO-UNDO.

DEFINE OUTPUT PARAMETER poDecimal AS DECIMAL NO-UNDO.

....

     I guess this will have the least overhead... But it might be ugly to code, as you are expecting something with a handle.

But with a handle (thinking of the class or tt solution): How is the caller supposed to do something with that returned variable if you don't know the data-type? If you are just outputting the value - and not crossing the appserver boundary - how about returning a generic Character parameter?

Posted by Tim Kuehn on 14-Apr-2009 06:10

I'd suggest returning a character, since it's possible to convert just about every data type to a character and back again.

Another possibility is to have a single-record TT w/all the data types in it, and pass a BUFFER out of the procedure for a self-serve session.

Posted by Admin on 14-Apr-2009 06:32

timk519 schrieb:

I'd suggest returning a character, since it's possible to convert just about every data type to a character and back again.

But be careful, when an AppServer is involved! Client and AppServer do not need to have the same -d and -E settings (or -numsep and -numdec). In that case, the client might have difficulties interpreting and converting back and forth again the value.

Especially when using the new -useOsLocale parameter in 10.2A it's rather unpredictable to knjow what format the client want's to receive.

Posted by Thomas Mercer-Hursh on 14-Apr-2009 11:38

DYNAMIC-NEW won't be available in 9.1 ... if this were a sufficiently modern version, you could define a class with overloaded method signatures, but that won't fly in 9.1.

Posted by Thomas Mercer-Hursh on 14-Apr-2009 11:40

To pass dates, always put them in ISO format to avoid confusion, i.e., 2009-04-14

Posted by Admin on 14-Apr-2009 12:22

The original post mentioned

Progress 9.1E

OE 10.1C

Maybe a 9.1E DB and 10.1C client? DYNAMIC-NEW would work in that environment. Only guessing!

Posted by Admin on 14-Apr-2009 12:24

and how about decimal numeric values?

Seriously - with having a lot of experience with different numeric and date formats in action, I always prefer to pass original datatypes and not "homegrown" string formats.

Posted by Tim Kuehn on 14-Apr-2009 12:55

One can also pass INTEGER(date), and then convert it back via DATE(integerval) to avoid locale-specific issues.

Posted by Thomas Mercer-Hursh on 14-Apr-2009 13:03

No question that my preferred solution would be the overloaded method ... but not in 9.1.

Posted by Admin on 14-Apr-2009 13:13

And Decimals? I know, you could always multiply by 10^x and convert to string and back, but how to justify that when passing the original data type is available?

Need to know the use case of the original poster to discuss more.

Posted by Tim Kuehn on 14-Apr-2009 13:16

What about decimals?

Does this suffice -

message decimal("1,23") decimal("123") decimal("1,23.45") decimal("123.45").

Posted by Admin on 14-Apr-2009 13:21

Highly dependent on session settings - and those can be different between client and appserver. Try this

SESSION:NUMERIC-FORMAT = "EUROPEAN".

message decimal("1,23") decimal("123") decimal("1,23.45") decimal("123.45").

SESSION:NUMERIC-FORMAT = "AMERICAN".

message decimal("1,23") decimal("123") decimal("1,23.45") decimal("123.45").

Inpredictable when using the -useOsLocale startup parameter in 10.2A...

Posted by Thomas Mercer-Hursh on 14-Apr-2009 13:36

But, isn't SESSION:NUMERIC-FORMAT only a display parameter?  If one passes decimal values as "1234567.89" and converts using DECIMAL, it works the same with American or European format.

Posted by Admin on 14-Apr-2009 13:39

tamhas schrieb:

But, isn't SESSION:NUMERIC-FORMAT only a display parameter?

No - like the DATE-FORMAT it influences the result of the STRING, DATE and DECIMAL and INTEGER functions. Everything that converts a date, decimal or integer to string and back.

Ever wondered why the footer of the .d dump files contain the date and numeric format?

Posted by Thomas Mercer-Hursh on 14-Apr-2009 14:06

Well, then, the answer is the same as using an ISO date, i.e., pick a standard format for transmission and use it consistently, converting from and to native forms.  Tacky, perhaps, but certainly not uncommon in any transmission between systems, especially when sender and receiver aren't necessarily aware of each other, aren't cooperating, and can even be different technologies.

We have two very different contexts here.

If the procedure with the varying return type is local ... and there is nothing in the original post to suggest that it is not ... then by definition it is in the same context so it is going to format dates, decimals, etc. the same way as the receiving procedure.  All this flap about localization is irrelevant since it is the same locale, unless one is intentionally shooting oneself in the foot by doing something like setting the numeric-format to a different value in the called procedure.

If there is any kind of system boundary being crossed here, whether AppServer or Sonic, or socket, or whatever, then it is a very different situation.  To be sure, in the old days where one always assumed ABL at both ends, it was convenient to assume ABL datatypes and to keep things simple.  But, in these days where one is striving to be technology agnostic about the other end of a communication, the correct approach is to use a neutral standard format for transmission and to pack and unpack to and from that format at each end.  Presumably the datatype being returned is even a part of the message so that one can, for example, transmit a Java DOUBLE to an ABL DECIMAL via some agreed keyword and format.

Posted by Admin on 14-Apr-2009 14:28

And why should you worry about that if Progress does the job for you in almost any context?

I you don't need to build XML messages manually, the interfaces to and from the ABL (Sonic, Web Serivces, .NET Proxies, Java Proxies, ...) handles this for us. Isn't that one of the reasons we are using a 4GL?

Posted by Thomas Mercer-Hursh on 14-Apr-2009 14:46

If the OP is in a context where the tools handle the problem automatically, then the OP has no problem.

If the OP is in the context of a local session, then the localization issues don't matter and the various suggestions about using a string will handle the problem.

If the OP is in a sufficiently modern version, then overloading will handle the problem.

If the OP is in a context of crossing session or machine boundaries and the tools are not providing the needed help, then the OP should simply imitate what the tools do and use standard forms.

Posted by Admin on 15-Apr-2009 13:26

why not return value in a char type varibale always.  Since you have the information of the data type from a DB field mentioned in another parameter, so accrodingly convert the return value for the data type.

Posted by Admin on 15-Apr-2009 14:07

One better solution could be dynamic temp-table. As you already have data type in another variable so can create a temp-table with field of mentioned data type .

Posted by Thomas Mercer-Hursh on 15-Apr-2009 14:26

Creating a dynamic temp-table to pass a single value seems rather like using a sledge hammer to pound in a thumb tack.

Posted by rbf on 15-Apr-2009 15:06

tamhas wrote:

Creating a dynamic temp-table to pass a single value seems rather like using a sledge hammer to pound in a thumb tack.

On the contrary, I use this often. It is the best way I know to overcome date and decimal difference settings between client and appserver once and forever.

Posted by Admin on 15-Apr-2009 15:08

rbf schrieb:

On the contrary, I use this often. It is the best way I know to overcome date and decimal difference settings between client and appserver once and forever.

I'm glad, I get some support from Europe on passing original data types between client and appserver! Thanks Peter.

Posted by Thomas Mercer-Hursh on 15-Apr-2009 15:43

???? I'm all for passing original data types when the interface will support it.  In fact, I highly prefer it to any of this dynamic stuff because it is much more traceable.

I do object, however, to the idea of using a temp-table to contain a single value.  It is bad enough to have a temp-table with one row, but one row and one value ... you might as well define a class containing properties of all possible data types and pass that back.  Another sledge hammer, but at least you don't have all that dynamic code.

Who knows what the original poster thinks of all this ... probably been frightened off.  So, lets try to recap and put a little structure into this:

Frist, we have two very different contexts, one where one is within a single session and one where one has more than one session.

Within a single session one has no localization issues, unless self inflicted.

Thus, within a single session we have:

1) Define parameters of the needed datatypes and use as needed;

2) With sufficiently recent versions of ABL we can use method overloading;

3) Map everything to and from strings.

If we have more than one session we can still pass more values than are needed for any one answer and just use the appropriate one for this invocation.  I don't like this particularly because it makes the signature unclear.

We can still use the map to strings approach, but we need to be careful to use standard formats.

With multiple sessions it may be reasonable to pass XML which is a particularly formal version of mapping to string.

Anything else seems to me to be too heavyweight and/or complex.  Especially for the simple statement of requirements of the OP.

Posted by deb2001 on 29-Apr-2009 23:42

First of all Thank You Mike and Thank You to all of you - Tim, Thomas, Peter, Ruchi and Divya for giving these whole lot of ideas for my objective...

I'm sorry, unfortunately for some period of time I didn't receive any email from PSDN on my thread in my inbox and couldn't manage some time to come to the site and check for responses as was little too busy in my project delivery for some time. So I was thinking probably no one had time to look at it and reply, which was not the real case here...

Well at this moment I'm using the character data return only and it's running fine. it's a Local procedure so right now don't have the issue of handling cross platform format mapping issue while converting, but your inputs on that would be so much helpful for me in future also while building something on that structure. This is why Forums are SO GREAT to get ideas and opinions  - I just loved this thread!!!

on temp-table parameter -  I can use a dynamic temp-table with single field with a create-like on the db-field and pass it back to caller - but here you ahve the overhead of using dynamic temp-table for juts a single variable value and also the added effort of dynamic coding on the caller which i wanted to keep free from it. My called routine should have handled all the dynamic stuff and given the caller back required value in normal format , and caller should be able to just use it directly -

let me elaborate this fully here now -

this generic called routine is to show a browser help to different fields in different forms -

the caller would be a trigger on a fill-in to get help browser to show some given fields from a database table and wants a selected value back from the called routine to assign it to the fill-in attached variable.

The caller would provide the list of  field vaues to be displayed in browser, the return field value needed, the sorting field , the field value to be filtered on etc. etc.

So the caller is a normal piece of  code created by any one looking for getting a help browser on some db fields.

The called one is the generic dynamic one which handles everything dynamically and returns back the selected value as per instruction - now here I'm not being able to do much as returning Character string only, so the caller have to convert them to respective data type, which Ideally I didn't want...

lastly, never did development on Object oriented coding -  just have bookish knowledge so not very comfortable on class and overriding methods

Anyway thanks a lot for all the inputs... keep comng with more please!!!!

Posted by Thomas Mercer-Hursh on 30-Apr-2009 10:53

lastly, never did development on Object oriented coding -  just have bookish knowledge so not very comfortable on class and overriding methods

Never too late to learn!  There are a number of problems like this that are solved very elegantly in the object model.

Posted by deb2001 on 01-May-2009 14:46

Thomas,

              Can you please dierect  me to a documentation to start with for OOPS programming in Progress?

TIA

Debayan.

Posted by Thomas Mercer-Hursh on 01-May-2009 15:39

Much of what you need to understand is OO in general, not specific to ABL.  But, I don't know that I have a particular recommendation there, both because I haven't really looked at much, but also because such books tend to use illustrations from Java or C#, which may not be that helpful unless you already know those languages. Of course, as I say frequently, OO in ABL is similar to other OO, but not always the same because ABL is a 4GL, so we have different tools available.  You will see some of this reflected in whitepapers such as http://www.oehive.org/OERAStrategies and http://www.oehive.org/CollectionClasses .

Specific to ABL there is the Getting Started book in the documentation, which doesn't do much for telling you why, but does quickly cover how.  Scott Augé has a book out, but I haven't looked at it.  There are other white papers and sample code on OE Hive which might help.

But, one of the best sources are the forums here.  Specifically there is an OO forum and you would probably find it educational to read back discussions ... occasionally even entertaining.  It will become apparent that you need to choose your mentors since there is a diversity of opinion about what is "right".

Posted by Admin on 02-May-2009 02:20

It will become apparent that you need to choose your mentors since there is a diversity of opinion about what is "right".

Well said. One of the most confusing bits are the differences when reading different oppinions resulting from peoples backgrounds - if they started with OO in C#, Java, ... or more theoretically.

Don't expect to be able to code fully in OOABL in the near future. There will always remain areas where you need procedures for. PUBLISH/SUBSCRIBE is one thing, everything talking TO the AppServer is the other thing. The ABL does not ship with a rich OO framework or class library (like the .NET framework). You need to build your own building blocks. The article about collection classes Thomas has provided the link for is one sample, event handling may be another one.

Posted by Thomas Mercer-Hursh on 02-May-2009 11:27

Hopefully, this will become another source http://www.oehive.org/OERAOSI although there is no actual code there yet.

The other big difference in backgrounds, btw, are people who come from ABL and can't seem to quite get with the OO program.

This thread is closed