Subscribe for automatic updates: RSS icon RSS

Login icon Sign in for full access | Help icon Help
Advanced search

Pages: [1]
  Reply  |  Print  
Author Topic: Returning an Interface from a Function  (Read 5564 times)
Trent H.
Posts: 3


« on: October 09, 2023, 12:02:36 pm »

I'm busy looking into implementing the new Genero Methods into an application and was wondering how to return an Interface from a Function

I have two example Types set up as

Code
  1. TYPE TypeA RECORD
  2.    notUsed STRING
  3. END RECORD
  4.  
  5. FUNCTION (typeA TypeA) test()
  6.    DISPLAY "Is TypeA"
  7. END FUNCTION
  8.  

And

Code
  1. TYPE TypeB RECORD
  2.    notUsed STRING
  3. END RECORD
  4.  
  5. FUNCTION (typeB TypeB) test()
  6.    DISPLAY "Is TypeB"
  7. END FUNCTION
  8.  

Then an Interface to use them with as

Code
  1. TYPE IType INTERFACE
  2.    test()
  3. END INTERFACE
  4.  

It seems to work fine but how can they be used in a scenario like the below where I need to return an Interface depending on an argument

Code
  1. MAIN
  2.    DEFINE typeA TypeA
  3.  
  4.    CALL typeBuilder("typeA") RETURNING typeA.*
  5.    CALL polyTest(typeA)
  6. END MAIN
  7.  
  8. FUNCTION typeBuilder(request STRING)
  9.    DEFINE typeA TypeA, typeB TypeB
  10.  
  11.    IF request = "typeA" THEN
  12.        RETURN typeA.*
  13.    ELSE
  14.        RETURN typeB.*
  15.    END IF
  16. END FUNCTION
  17.  
  18. FUNCTION polyTest(itype IType)
  19.    CALL itype.test()
  20. END FUNCTION
  21.  

I'm trying to use in the code in MAIN as

Code
  1. MAIN
  2.    DEFINE itype IType
  3.  
  4.    CALL typeBuilder("typeA") RETURNING itype
  5.    CALL polyTest(itype)
  6. END MAIN
  7.  
Leo S.
Four Js
Posts: 126


« Reply #1 on: October 09, 2023, 03:10:05 pm »

Hi Trent, you need to make use of the optional RETURNS clause of the FUNCTION typeBuilder
Also , since 4.1.x you don't need to return record.* anymore.
Just do this
Code
  1. FUNCTION typeBuilder(request STRING) RETURNS IType
  2.   DEFINE typeA TypeA, typeB TypeB
  3.  
  4.   IF request = "typeA" THEN
  5.       RETURN typeA
  6.   ELSE
  7.       RETURN typeB
  8.   END IF
  9. END FUNCTION
  10.  
Regards , Leo
Trent H.
Posts: 3


« Reply #2 on: October 09, 2023, 04:08:29 pm »

Hello Leo, thanks so much for the response.

I've updated the code and it is compiling fine which is great but I am getting a "Null pointer exception" on the CALL itype.test() line in the polyTest FUNCTION.

Do I need to make any other changes for it to work with Genero 3.20? (I should have mentioned I'm not using 4.10 yet)
Leo S.
Four Js
Posts: 126


« Reply #3 on: October 09, 2023, 05:24:30 pm »

Hi Trent , I needed to fiddle a bit to make it working in 3.20,
the following code should compile and run at your side,
see the comments which explain a bit the difference to 4.x
Of course this code works also once you switch to 4.x
Code
  1. TYPE TypeA RECORD
  2.   notUsed STRING
  3. END RECORD
  4.  
  5. TYPE TypeB RECORD
  6.   notUsed STRING
  7. END RECORD
  8.  
  9. TYPE IType INTERFACE
  10.   test()
  11. END INTERFACE
  12.  
  13. --need module scope vars for the type builder in 3.20
  14. --and var names shouldn't be type names
  15. --(genero is still case insensitive)
  16. --DEFINE typeA TypeA won't work in 3.20
  17. --also type and var definitions can't be freely mixed
  18. --with function as its done in 4.x
  19. DEFINE tA TypeA
  20. DEFINE tB TypeB
  21.  
  22. FUNCTION typeBuilder(request STRING) RETURNS IType
  23.   DEFINE it IType
  24.  
  25.   IF request = "typeA" THEN
  26.       LET it=tA
  27.   ELSE
  28.       LET it=tB
  29.   END IF
  30.   RETURN it
  31. END FUNCTION
  32.  
  33. FUNCTION (typeA TypeA) test()
  34.   DISPLAY "Is TypeA"
  35. END FUNCTION
  36.  
  37. FUNCTION (typeB TypeB) test()
  38.   DISPLAY "Is TypeB"
  39. END FUNCTION
  40.  
Regards, Leo
Leo S.
Four Js
Posts: 126


« Reply #4 on: October 09, 2023, 05:55:10 pm »

Trent, I double checked against 4.x: also in 4.x you can't return an interface variable (which is a kinda pointer) from a variable which has function local scope.
The runtime does set it to NULL on return because the local scope of the typeBuilder was  left ...and there is no mechanism in Genero which allows to point to scopes which have been destroyed.
(It would be possible in theory by creating a temp variable and using a garbage collector).
So just use variables which have module scope for the builder and you are fine.
Regards, Leo
Trent H.
Posts: 3


« Reply #5 on: October 09, 2023, 09:29:23 pm »

Hello Leo, oh ok I see, a bit unexpected but I think I can work with this. Thanks so much for your help! I would never have figured that out, haha
Pages: [1]
  Reply  |  Print  
 
Jump to:  

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines