Four Js Development Tools Forum

Discussions by product => Genero BDL => Topic started by: David H. on April 03, 2008, 03:31:24 pm



Title: Feature request, new method for StringTokenizer Class
Post by: David H. on April 03, 2008, 03:31:24 pm
I've never used the StringTokenizer class before until now. Since it has a CountTokens() method it would make sense to have a matching Token() method too, so you could code:-

 LET tok = base.StringTokenizer.create(mystr,";")
 FOR tpos = 1 TO tok.countTokens()
    DISPLAY tok.Token(tpos)
 END FOR

Cheers,

David


Title: Re: Feature request, new method for StringTokenizer Class
Post by: Reuben B. on April 03, 2008, 11:12:33 pm
I've never used the StringTokenizer class before until now. Since it has a CountTokens() method it would make sense to have a matching Token() method too, so you could code:-

 LET tok = base.StringTokenizer.create(mystr,";")
 FOR tpos = 1 TO tok.countTokens()
    DISPLAY tok.Token(tpos)
 END FOR

Cheers,

David


David,

Be aware that the countTokens() method returns the number of tokens "Returns the number of tokens left to be returned" which is not necessarily equal to the number of tokens.

Your example could be coded as...

Code
  1. LET tok = base.StringTokenizer.create(mystr,",")
  2. WHILE tok.hasMoreTokens()
  3.   DISPLAY tok.nextToken()
  4. END WHILE

However I see the point you're getting at.  A real life example might be to say, I am reading a .csv file and I am only interested in the 3rd, 4th, and 7th columns.  Currently this could be coded as something like

Code
  1. LET i = 0
  2. LET tok = base.StringTokenizer.create(mystr,",")
  3. WHILE tok.hasMoreTokens()
  4.   LET i = i + 1
  5.   CASE i
  6.      WHEN 3 LET l_third = tok.nextToken()
  7.      WHEN 4 LET l_fourth = tok.nextToken()
  8.      WHEN 7 LET l_seventh = tok.nextToken()
  9.      OTHERWISE
  10.         LET l_dummy = tok.nextToken()
  11.      END CASE
  12. END WHILE
  13.  
or
Code
  1. DEFINE l_arr DYNAMIC ARRAY OF STRING
  2. CALL l_arr.clear()
  3. LET tok = base.StringTokenizer.create(mystr,",")
  4. WHILE tok.hasMoreTokens()
  5.   CALL l_arr.appendElement()
  6.   LET l_arr[l_arr.getLength()] = tok.nextToken()
  7. END WHILE
  8. LET l_third = l_arr[3]
  9. LET l_fourth = l_arr[4]
  10. LET l_seventh = l_arr[7]
  11.  

(and for this example I suppose there is also a method along the lines of base.Channel.read[dummy,dummy,l_third, l_fourth,dummy,dummy,l_seventh,dummy])


...when it would be nice to be able to code this as ...

Code
  1. LET tok = base.StringTokenizer.create(mystr,",")
  2. LET l_third = tok.token(3)
  3. LET l_fourth = tok.token(4)
  4. LET l_seventh = tok.token(7)





   
















Title: Re: Feature request, new method for StringTokenizer Class
Post by: Rene S. on April 16, 2008, 01:43:18 pm
Not perfect yet, but this code will be possible with 2.20.
Notice, this is not a fake, this code is already working.

Code
  1. IMPORT java java.lang.String
  2. MAIN
  3.    DEFINE result ARRAY[] OF java.lang.String
  4.    DEFINE s java.lang.String
  5.    DEFINE r String
  6.    DEFINE x, n INT
  7.  
  8.    LET s = "this is a test"
  9.    LET result = s.split("\\s")
  10.    LET n = result.getLength()
  11.    FOR x = 1 TO n
  12.        LET r = result[x]
  13.        DISPLAY x, " ", r
  14.    END FOR
  15. END MAIN
  16.  

Code
  1. $fglcomp xx.4gl && fglrun xx.4gl
  2.          1 this
  3.          2 is
  4.          3 a
  5.          4 test
  6.  


Title: Re: Feature request, new method for StringTokenizer Class
Post by: David H. on April 16, 2008, 03:37:04 pm
Looks interesting! Hope to hear more on v2.20 in the near future...


Title: Re: Feature request, new method for StringTokenizer Class
Post by: Reuben B. on April 21, 2008, 07:22:53 am

I'd like to think that the proposed Java importing wouldn't be used for something you can easily do in 4GL.

Using the feature that dynamic arrays are passed by reference, I think this is a nicer solution.

Code
  1. TYPE stringArray DYNAMIC ARRAY OF STRING
  2.  
  3. MAIN
  4. DEFINE r stringArray
  5. DEFINE i INTEGER
  6.  
  7.   CALL string_split("This is a test"," ",r)
  8.   FOR i = 1 TO r.getLength()
  9.      DISPLAY i, " ",r[i]
  10.   END FOR
  11. END MAIN
  12.  
  13. FUNCTION string_split(string,delimiter,result)
  14. DEFINE string, delimiter STRING
  15. DEFINE result stringArray
  16. DEFINE tok base.StringTokenizer
  17.  
  18.   CALL result.clear()
  19.   LET tok = base.StringTokenizer.createExt(string,delimiter, "\\", TRUE)
  20.   WHILE tok.hasMoreTokens()
  21.      LET result[result.getLength()+1] = tok.nextToken()
  22.   END WHILE
  23. END FUNCTION


Title: Re: Feature request, new method for StringTokenizer Class
Post by: Rene S. on April 21, 2008, 09:13:51 am
Hello,
the history of 4gl-StringStokenizer: it's a "clone" of class java.util.StringTokenizer.

Why I a made the reply with the code-snippet showing IMPORT JAVA? With this coming feature programmers can use everything written in the Java language directly within a 4gl program. There is no need to argue here. Java proposes solutions for quite everything a programmer need in these days to write "3gl" programs. You need a mail api? Use the Java Mail API - still exists.
You want to write a simple http server? Use the class java.net.Socket - still exists. And so on.

Reuben, the question is not: add one more tiny feature, the question is "don't reinvent the wheel every day again". Many of the feature requests (I would like to say: any not GUI related request) have a solution in the Java API (across all platforms).

We build once the bridge to Java and open 4gl to standard solutions of standard problems. Use standards.
When the bridge is build, our company can focus on our main business...

Your young, well educated programmers will love this feature.
Rene


Title: Re: Feature request, new method for StringTokenizer Class
Post by: Scott N. on April 21, 2008, 10:27:52 am
Hi Rene

If Java is going to be the preferred way of "extending" Genero then a couple questions come to mind:
1. What happens to the existing base, om, math and path classes? Will they be dropped as there seems little point in keep them if they are not going to be extended and "use Java" is going to be the recommended way?
2. What happens to the existing ODI layer - will it be replaced with JDBC or will JDBC just become an alternative way to connect to the different databases?



Title: Re: Feature request, new method for StringTokenizer Class
Post by: Rene S. on April 21, 2008, 10:51:32 am
Hi Scott,
1. The existing extensions will be supported. No need to replace them in a fgl-source. Yes, from my point of view, Java will be the recommended way of extending 4gl.
2. The existing ODI layer will not be replaced. But two things are subject of development:
  • An ODI driver using JDBC: this allows to use any database providing a JDBC driver.
  • An JDBC driver using ODI: this allows to use from a Java program the ODI drivers.

BTW: part of the project is also accessing 4gl from java. Any 4gl-module looks like a Java class. Any FUNCTION is a public static  Method.   
Rene


Title: Re: Feature request, new method for StringTokenizer Class
Post by: David H. on April 21, 2008, 04:51:53 pm
Hi Rene,

I can only agree. Opening up the language is a good thing as far as I'm concerned... Of course as a Windows only developer, I'd like you to go further than just Java and implement something similar for COM and .NET on the Windows platform, as these are the standards supported by the majority of 3rd party components in the marketplace. I know you can access COM via GDC using F.E.E already, but the syntax is not great and it would be nice if it could be used naturally in BDL code as per your Java example...

David


Title: Re: Feature request, new method for StringTokenizer Class
Post by: Reuben B. on April 22, 2008, 02:08:46 am
Hello,
the history of 4gl-StringStokenizer: it's a "clone" of class java.util.StringTokenizer.

Why I a made the reply with the code-snippet showing IMPORT JAVA? With this coming feature programmers can use everything written in the Java language directly within a 4gl program. There is no need to argue here. Java proposes solutions for quite everything a programmer need in these days to write "3gl" programs. You need a mail api? Use the Java Mail API - still exists.
You want to write a simple http server? Use the class java.net.Socket - still exists. And so on.

Reuben, the question is not: add one more tiny feature, the question is "don't reinvent the wheel every day again". Many of the feature requests (I would like to say: any not GUI related request) have a solution in the Java API (across all platforms).

We build once the bridge to Java and open 4gl to standard solutions of standard problems. Use standards.
When the bridge is build, our company can focus on our main business...

Your young, well educated programmers will love this feature.
Rene


Rene,

I think the proposed IMPORT JAVA, sitting alongside the existing C extensions, makes perfect sense to allow interfacing with existing Java libraries rather than reinventing the wheel.  A better example being to use one of the existing Java (or C/Python/Perl/shell) routines for dealing with zip files, rather than 4Js spending time and effort creating a Genero class that only a very small percentage of Genero users would be likely to use.

If I was to take off my shiny new 4Js Asia Pacific employee hat and think back to when we migrated my old system to Genero, one of the great things was being able to replace the existing c routines for reading/writing to files with base.Channel methods.  It meant that our finished product had no c.  The distributed product had a few Python scripts but I am sure that if we put our minds to it the os.Path() methods could be used to replace those Python scripts with 4GL code.  From a development, deployment and support point of view, minimising the number of tools required was a good thing. 

Each Genero user would have different requirements as to which additional tool or tools they chose to use alongside Genero.  As David just posted as he is a Windows only developer, he would be more likely to go for a COM or .NET solution for something that couldn't be achieved in Genero.

I would hate to think that if someone requested that abs(), min(), max(), floor(), round(), ceil() functions be finally added to Genero that the answer would start, use the methods available in "IMPORT java java.lang.math"

So back to the original problem, a solution that starts "IMPORT java" may not be the ideal answer for all Genero users.  As I have shown there is a Genero solution that can be coded with a handful of lines, and I'd like to think that if we thought a significant proportion of users would use that function then adding a method  to base.String  (base.String.split) or base.StringTokenizer (base.StringTokenizer.token) would be considered so that each of these Genero developers was not reinventing the wheel.

Reuben