Calling a Method in a class dynamicly using dynamic-function

Posted by goo on 07-Aug-2017 05:29

11.3 --> 11.7

After converting to 11.7 the following statement seems to give an error:

User-defined function 'getMsgQueueProperty' invoked dynamically but could not be found. (5639) Procedure:"ProcessMessageReadyIn oomsg.msgQueue"

the statement is:

      dtzDocumentDate            = datetime-tz(dynamic-function("getMsgQueueProperty" in source-procedure,msgQueue.msgQueueGID,'DocumentDate'))

-------------

This is how it is called:

* msgQueue.cls has the Method getMsgQueueProperty.

in msgQueue there is another method that calls:

oDocument = NEW msgDocument(oMeasuringTicket,msgQueue.msgQueueGID).

in msgDocument I need to Call the method getMsgQueueProperty and untill now it has worked using dynamic-function(....

How would I do this now in 11.7 ? I want to Call a method in the Source-procedure (witch is a class).

All Replies

Posted by Mike Fechner on 07-Aug-2017 05:34

Please check out DYNAMIC-INVOKE for class methods.
 
 
Von: goo [mailto:bounce-goo@community.progress.com]
Gesendet: Montag, 7. August 2017 12:31
An: TU.OE.Development@community.progress.com
Betreff: [Technical Users - OE Development] Calling a Method in a class dynamicly using dynamic-function
 
Update from Progress Community
 

11.3 --> 11.7

After converting to 11.7 the following statement seems to give an error:

User-defined function 'getMsgQueueProperty' invoked dynamically but could not be found. (5639) Procedure:"ProcessMessageReadyIn oomsg.msgQueue"

the statement is:

      dtzDocumentDate            = datetime-tz(dynamic-function("getMsgQueueProperty" in source-procedure,msgQueue.msgQueueGID,'DocumentDate'))

-------------

This is how it is called:

* msgQueue.cls has the Method getMsgQueueProperty.

in msgQueue there is another method that calls:

oDocument = NEW msgDocument(oMeasuringTicket,msgQueue.msgQueueGID).

in msgDocument I need to Call the method getMsgQueueProperty and untill now it has worked using dynamic-function(....

How would I do this now in 11.7 ? I want to Call a method in the Source-procedure (witch is a class).

View online

 

You received this notification because you subscribed to the forum.  To stop receiving updates from only this thread, go here.

Flag this post as spam/abuse.

 

Posted by goo on 07-Aug-2017 05:52

I have looked at it, but how I am not sure how to Call the Source-procedure ... How do I refere to the Source-procedure's class? Is Source-procedure the handle to the class?

//Geir Otto

Posted by Mike Fechner on 07-Aug-2017 06:08

Source-procedure is a procedural construct and should not be used for classes ... when calling into a class method, you need to use a reference variable.

Posted by goo on 07-Aug-2017 06:24

So If I have two classes:

a.cls

b.cls

and in a.cls I call b.cls, how can I refere to class a? Too much vacation here....

Posted by marian.edu on 07-Aug-2017 06:28

Hmm, this seems to imply that source-procedure albeit a procedure handle did pointed to an object instance (class) before… probably not supported, still it does seems to confirm my thought of initial OO implementation being just an ‘abstraction’ over existent procedural constructs, namely functions. This not working anymore might mean something changed there so an object instance it’s just not a persistent procedure with a makeup :)


Anyway, source-procedure should not be there in the first place, whatever you do there should not depends on who made the call but maybe I’m biased here.
 
Marian Edu

Acorn IT 
+40 740 036 212

Posted by Mike Fechner on 07-Aug-2017 06:31

In a:
 
b:MethodName (THIS-OBEJECT) .
 
In b:
 
METHOD PUBLIC VOID MEthodName (referenceToA AS <suitableType>):
 
The suitableType should be an Interface implemented by a that defines the callback-methods required.
 
Or – bad style – Progress.Lang.Object and you use DYNAMIC-INVOKE from b to call back into a
 

Posted by goo on 07-Aug-2017 06:40

Thanks Mike :-) I allways forget this statement...

Posted by goo on 07-Aug-2017 08:11

If I add THIS-OBJECT as a parameter, it gives me an error : Invalid handle. Not initialized or Points to a deleted Object.... How can that be?

Posted by goo on 07-Aug-2017 08:45

ooo, by the way Mike, I want to Call a Method in A.cls FROM B.cls.....

I tried in A.cls

oB = New b (this-object).

and in b.cls:

constructor ....(oA as class a):

test = oA:theMethod('something,222).

I get the error saying that oA is invalid....

Posted by Mike Fechner on 07-Aug-2017 08:54

Do you do this
 

test = oA:theMethod('something,222).

 
In the constructor? Or in a method?
 
Constructor parameters are no longer available in methods, so you need to assign that reference value to a variable or property to use this in a method.

Posted by goo on 07-Aug-2017 09:53

yes the test = oA:method(....) is done within the constructor of B. So, I have to define a variable x as class A ?.

something like this?

constructor of b (oA as class A):

x = oA.

x:method(....).  // seems a bit strange to do it like this....

end constructor.

Posted by jankeir on 07-Aug-2017 10:06

I have no idea what you are doing wrong, but this works in 11.3 both from a constructor and a method in a I can instantiate b and run a method in a from it's constructor. I tested it because we had this-object bugs in the past (but that was in 10.2B):

class a:

 constructor a ():

   new b(this-object, "from constructor").

 end constructor.

method public void test(input icMessage as character  ):

   message icMessage

     view-as alert-box info buttons ok.  

end method.

method public void newbFromMethod():

 new b(this-object, "from method").

 end method.

end class.

class b:

 constructor b(input oa as a, input icMessage as character):

   oa:test(icMessage).

 end constructor.

end class.

define variable oa as a no-undo.

oa = new a().

oa:newbFromMethod().

Posted by goo on 07-Aug-2017 10:13

It is a bit strange for me as well. It is a bit tricky to test it since it is in a live Production system running on Linux x64 bit OS, so I can't test it for the moment. I have fixed the problem by doing a workaround....

The only diff from what you sent is that New b is not running from the constructor of class A, but from a Method in class A....

Posted by jankeir on 07-Aug-2017 10:17

> The only diff from what you sent is that New b is not running from the constructor of class A, but from a Method in class A....

That's what oa:newbFromMethod() does.

I also tried making newbFromMethod static since then I would expect THIS-OBJECT to be valid, but then it doesn't even compile so that can't be what you're doing (or something changed in 11.7.)

Posted by Laura Stern on 07-Aug-2017 10:32

You need to post some code.  I no longer know what you're doing.

Posted by goo on 07-Aug-2017 15:54

Here it is:

Two classes, A and B.

Class A:

def property AGuid as char ....

constructor ()

Method Public logical doStuff ():

:

: some stuff that sets the AGUID property....

:

oB = New B (THIS-OBJECT).

 Return somestuff.

END.

Method Public character getStuff (input icGID as char, input icName as char):

 :

 Return theReturn.

END.

Class B:

constructur (input oA as class A):

 find somestuff where iID = oA:AGuid...... no-lock ....

 aVariable = oA:getStuff('Something',aintegerfromthefind).

end.

I am not sure if this made it more informativ....:-) but I need to Reference the class A from within class B.

Posted by Thomas Mercer-Hursh on 07-Aug-2017 16:42

Obviously, there is SomeStuff missing, but one of the questions was the scope of oB, which I don't see defined anywhere.

Personally, I avoid doing things in constructors that could possibly fail, e.g., newing another class.  If the constructor fails, you are left with an undefined reference.  You might try moving such things to an Initialize method, both for this reason and because it might making it more clear.

Is somestuff a temp-table or DB table or what?  What is it's scope?  (I encapsulate TTs within a class).

Posted by aren on 07-Aug-2017 18:59

In fact, I meet the same issues here, dynamic-function not work for the source-procedure of a class,

Posted by aren on 07-Aug-2017 19:07

I meet the same issue here. We use the source-procedure handle for a class, Dynamic-function(method name, sour-procedure for a class). This works before 11.7, but it fails in 11.7. Could anyone give me some advice? Otherwise, we might change too many codes in our application

Posted by goo on 08-Aug-2017 02:22

Sorry Thomas, there is a lot of stuff going on, and the class A is started from another program with

CLASS A INHERITS Ahelper  USE-WIDGET-POOL:.....

   FINALLY:

     DELETE OBJECT B  NO-ERROR.

   END FINALLY.

The same is within class B, everything is deleted.

The somestuff is a Find that sends back the result to B. I have done a workaround by putting the same method in B so that it will work, but I would like to have that method in A....

Posted by aren on 08-Aug-2017 02:29

..Just want to know, has the original issue that dynamic-function not work for a source-procedure of a class been resolved..

Thanks!

Posted by Mike Fechner on 08-Aug-2017 02:30

Where is that finally block?
 
In A’s constructor, a method, the destructor?
Von: goo [mailto:bounce-goo@community.progress.com]
Gesendet: Dienstag, 8. August 2017 09:24
An: TU.OE.Development@community.progress.com
Betreff: RE: [Technical Users - OE Development] Calling a Method in a class dynamicly using dynamic-function
 
Update from Progress Community
 

Sorry Thomas, there is a lot of stuff going on, and the class A is started from another program with

CLASS A INHERITS Ahelper  USE-WIDGET-POOL:.....

   FINALLY:

     DELETE OBJECT B  NO-ERROR.

   END FINALLY.

The same is within class B, everything is deleted.

The somestuff is a Find that sends back the result to B. I have done a workaround by putting the same method in B so that it will work, but I would like to have that method in A....

View online

 

You received this notification because you subscribed to the forum.  To unsubscribe from only this thread, go here.

Flag this post as spam/abuse.

 

Posted by aren on 08-Aug-2017 02:32

a

Posted by goo on 08-Aug-2017 03:08

Ups... sorry Mike, the FINALLY Block is done in the Method...

Posted by Laura Stern on 08-Aug-2017 07:58

OK.  Still confused as there are too many moving parts coming and going here.  I hope you realize that a FINALLY block is NOT a destructor block.  It will run immediately after the main body of the block completes.  Could that be your problem?

You could try actually debugging this!  Step through each statement and watch the value of your variables.  Or use the Dynamic Object monitor and look to see what objects are coming and going at each statement.  I'm pretty convinced it is something in your code that is causing the problem, and not a bug.

Posted by goo on 08-Aug-2017 08:32

I do realize that finally will do that, but if you all mean that THIS-OBJECT will be past correctly, it has to be something else.. 

I see another question on the same topic has been added to the forum... others that has used dyn-func in source-procedure .. I am not alone :-)

Sendt fra min iPhone

Den 8. aug. 2017 kl. 14.59 skrev Laura Stern <bounce-stern@community.progress.com>:

Update from Progress Community
Laura Stern

OK.  Still confused as there are too many moving parts coming and going here.  I hope you realize that a FINALLY block is NOT a destructor block.  It will run immediately after the main body of the block completes.  Could that be your problem?

You could try actually debugging this!  Step through each statement and watch the value of your variables.  Or use the Dynamic Object monitor and look to see what objects are coming and going at each statement.  I'm pretty convinced it is something in your code that is causing the problem, and not a bug.

View online

 

You received this notification because you subscribed to the forum.  To unsubscribe from only this thread, go here.

Flag this post as spam/abuse.

Posted by Peter Judge on 08-Aug-2017 08:44

You should NOT use SOURCE-PROCEDURE for classes. You should not use it to determine what the instantiating class is. It may do what you want today, but it is not intended to do that.
 
If you want to know what class instantiated/NEW’ed this class, then pass that value in via a property  or constructor.
 
If you want to publish something to the whole session, do a PUBLISH “event” IN a session super-procedure.
 

Posted by goo on 08-Aug-2017 09:01

Seems like this has been misunderstood. I understand that we should not use source-procedure... I am only saying....

Just forget it, I have found a workaround 

Sendt fra min iPhone

Den 8. aug. 2017 kl. 15.46 skrev Peter Judge <bounce-pjudge@community.progress.com>:

 Update from Progress Community
<4TW97ZQFKRYJ-jpg_2D00_70x70x2-jpg>
Peter Judge

You should NOT use SOURCE-PROCEDURE for classes. You should not use it to determine what the instantiating class is. It may do what you want today, but it is not intended to do that.
 
If you want to know what class instantiated/NEW’ed this class, then pass that value in via a property  or constructor.
 
If you want to publish something to the whole session, do a PUBLISH “event” IN a session super-procedure.
 

View online

 

You received this notification because you subscribed to the forum.  To unsubscribe from only this thread, go here.

Flag this post as spam/abuse.

Posted by aren on 08-Aug-2017 18:17

It seems that in the 11.7 progress, source-procedure for class is not supported. Our codes works well before 11.7 progress, we use the Dynamic-Function(method name, source-procedure for a class) in all our codes... Passing the instance will be a big trouble to change our codes... Source-procedure is only changed in 11,7, I am not sure whether progress is intended to change the  Source-procedure in 11.7 or only by mistakes during the 11.7

Posted by Evan Bleicher on 14-Aug-2017 08:40

This Community post has discussed several aspects of your issue and has identified an object-oriented approach for resolving it.  However, to your question as to whether the ABL supports the use of source-procedure for classes the answer is, no it does not.

During the initial design of the object-oriented extensions to the ABL, the development team discussed whether the invocation syntax should work for both the procedural ABL and the object-oriented ABL.  This approach was rejected.  It was for that reason that an ABL application RUNs an external procedure and NEWs a class and invokes an internal procedure via the “RUN IN” syntax and invokes a method via object-reference: method () syntax.  The intent was to allow both coding models to work seamlessly together but with different syntax.

Your approach of using SOURCE-PROCEDURE to get access to the procedure handle underlying our implementation of an object instance took advantage of a bug in our implementation.  It was never our intent to support for such a facility.    The regression you observed was caused by a performance related change we made in 11.7.0.

The OpenEdge development team needs to investigate this issue to close this loop hole in the invocation logic ensuring that an application cannot invoke a method using procedural constructs.

This thread is closed