Java Forum / General / July 2005
Toward Terser Java
Roedy Green - 05 Jul 2005 09:42 GMT I find this pattern occurs repeatedly:
String quotation = accumulatedQuotation.toFinalString(); if ( quotation.length() > 0 ) { addToken( new StringLiteralToken( quotation ) ); }
String comment = accumulatedComment.toFinalString(); if ( coment.length() > 0 ) { addToken( new CommentLiteralToken( comment ) ); } Note how only the source and the name of the constructor changes. I can't figure out an elegant way to encapsulate the length test in addToken.
I woud like to wring something terse like this:
addToken( accumulatedQuotation, StringLiteralToken ); addToken( accumulatedComment, CommentToken );
Any hints on getting this code shorter?
My best idea so far is to pass CommentToken.class as a parameter, use newInstance, cast to an interface, then give my tokes all default no parm constructor and setters fill in the information after construction with the setters.
Is there any more direct way?
Maybe there is a way by giving it a example object to clone.
Maybe I am just being too stingy. I should create the object whether it has 0 length or not, then discard it later. That offends me since the constructors have asserts to prevent creation of bad objects.
 Signature Bush crime family lost/embezzled $3 trillion from Pentagon. Complicit Bush-friendly media keeps mum. Rumsfeld confesses on video. http://www.infowars.com/articles/us/mckinney_grills_rumsfeld.htm
Canadian Mind Products, Roedy Green. See http://mindprod.com/iraq.html photos of Bush's war crimes
Andrea Desole - 05 Jul 2005 09:48 GMT > My best idea so far is to pass CommentToken.class as a parameter, use > newInstance, cast to an interface, then give my tokes all default no > parm constructor and setters fill in the information after > construction with the setters. > > Is there any more direct way? a factory class as parameter?
Roedy Green - 05 Jul 2005 11:55 GMT >> My best idea so far is to pass CommentToken.class as a parameter, use >> newInstance, cast to an interface, then give my tokes all default no [quoted text clipped - 4 lines] > >a factory class as parameter? I think that would work well when you had a small and known number of possible Token classes to manage. Don't I then have to write a factory method for every Token class? Then I write many more lines of code than I saved. I did not want to write a central make-anything factory method since I want to be able to dynamically add new Parsers and Tokens. If there is a way I can do it without propagating a lot of code, great.
Sometimes I just long for C preprocessor macro ability for when Java won't let you encapsulate patterns without a fight.
 Signature Bush crime family lost/embezzled $3 trillion from Pentagon. Complicit Bush-friendly media keeps mum. Rumsfeld confesses on video. http://www.infowars.com/articles/us/mckinney_grills_rumsfeld.htm
Canadian Mind Products, Roedy Green. See http://mindprod.com/iraq.html photos of Bush's war crimes
Andrea Desole - 05 Jul 2005 12:57 GMT > I think that would work well when you had a small and known number of > possible Token classes to manage. > > Don't I then have to write a factory method for every Token class? I would rather say a class for every Token class.
> Then I write many more lines of code than I saved. I did not want to > write a central make-anything factory method since I want to be able > to dynamically add new Parsers and Tokens. I understand. On the other side it is necessary to implement somehow the creation logic somewhere
> > If there is a way I can do it without propagating a lot of code, > great. mmm, the only solution I can think of are generics, supposing you are using 1.5. I never used generics in Java (still using 1.4.2), so I can't go any further, but I think that with C++ templates it should be possible. Something like a template factory class, or a template addToken method.
Boudewijn Dijkstra - 05 Jul 2005 17:38 GMT >> If there is a way I can do it without propagating a lot of code, >> great. > > mmm, the only solution I can think of are generics, supposing you are using > 1.5. I never used generics in Java [...] But I have. Generics are not very useful, because of the so-called type erasure feature. You would still need two parameters and reflection. Although you can make it type-safe by appending <? extends Token> or <? extends LiteralToken> to the Class parameter in Tor's example.
Roedy Green - 05 Jul 2005 20:08 GMT >I understand. On the other side it is necessary to implement somehow the >creation logic somewhere The way I see it the Token constructor has the right to check the parameters and abort the construction process with an exception in order to prevent the creation of a malformed Token.
That is the business of the Token and, by nesting your token classes, you only have to write such code once and invoke it in only one place.
Think of it as like a walled city with many guarded gates surrounding the king's palace with only one gate. To protect your king, it is best to put your effort on the gate in the inner wall. You might forget to man one of the outer gates.
On the other hand the Token has no business knowing anything about what collections it is added to. That sort of logic does not belong in the Token, and in my case I have need of keeping the Tokens as lightweight as possible since I export them, the decision whether to add belongs in the code controlling what goes into the container. It is the one making the decision to avoid creating Tokens with empty strings. In a few cases it IS ok. This is not an error, so I don't think it should be handled by an exception.
Just what is it about his pattern that makes it so resistant to simple encapsulation in a method of the caller or the container?
if ( s.length() != 0 ) { add ( new X ( s ) ) }
Naively you might think you could write something like this:
addOnlyNonEmpty( StringLiteralToken, s ); or
addOnlyNonEmpty( StringLiteralToken.class, s ); or
addOnlyNonEmpty( class StringLiteralToken, s );
and implement it with:
addOnlyNonEmpty( class SimpleToken X , s ) { if ( s.length() != 0 ) { add new X( s ); } }
Where SimpleToken is a subclass of the Tokens that take a single string argument constructor.
The problem arises because you can't pass classes as parameters, only a generic class reference without subtypes which is all but useless without run-time dynamic reflection.
Because you can't specify the facts Which class to construct, you can't delegate the construction to the callee.
I wonder how difficult it would be for some future Java to permit this. It may have many more uses that just saving me writing an if sandwich around every call invocation.
 Signature Bush crime family lost/embezzled $3 trillion from Pentagon. Complicit Bush-friendly media keeps mum. Rumsfeld confesses on video. http://www.infowars.com/articles/us/mckinney_grills_rumsfeld.htm
Canadian Mind Products, Roedy Green. See http://mindprod.com/iraq.html photos of Bush's war crimes
Roedy Green - 05 Jul 2005 21:14 GMT >The problem arises because you can't pass classes as parameters, only >a generic class reference without subtypes which is all but useless >without run-time dynamic reflection. If Java were a person, here would be its political opinion.
Child abandonment ( dropping all references to objects you create) is perfectly ok.
A fetus (partly constructed object) has the right to abort itself prior to birth (throw an exception), but not to commit suicide, (delete itself). It has no say in whether it is conceived in the first place. (It cannot be interrogated prior to construction.)
Parents may not delegate the process of child creation by sperm or egg donation. There is no way to get a method to create an object for you where you supply the class as a parameter)
You cannot know ahead of time if your fetus will live to term. (There are no constructor preconditions).
 Signature Bush crime family lost/embezzled $3 trillion from Pentagon. Complicit Bush-friendly media keeps mum. Rumsfeld confesses on video. http://www.infowars.com/articles/us/mckinney_grills_rumsfeld.htm
Canadian Mind Products, Roedy Green. See http://mindprod.com/iraq.html photos of Bush's war crimes
Lasse Reichstein Nielsen - 05 Jul 2005 22:13 GMT > Parents may not delegate the process of child creation by sperm or egg > donation. There is no way to get a method to create an object for you > where you supply the class as a parameter) As Java grew old, it became pragmatic and compromised its political opinion, hence Class#newInstance().
/L
 Signature Lasse Reichstein Nielsen - lrn@hotpop.com DHTML Death Colors: <URL:http://www.infimum.dk/HTML/rasterTriangleDOM.html> 'Faith without judgement merely degrades the spirit divine.'
Andrea Desole - 06 Jul 2005 09:44 GMT > As Java grew old, it became pragmatic and compromised its political > opinion, hence Class#newInstance(). that's correct, specially if you accept runtime errors. I would rather find errors at compile time, but that doesn't seem possible without writing some extra code.
Tim Tyler - 09 Jul 2005 14:38 GMT Roedy Green <look-on@mindprod.com.invalid> wrote or quoted:
> Sometimes I just long for C preprocessor macro ability for when Java > won't let you encapsulate patterns without a fight. That really was bad, though. At least these days machines can read and write source code - and do some editing tasks for us.
The preprocessor was one of the things that made that *very* challenging to do properly in C/C++.
 Signature __________ |im |yler http://timtyler.org/ tim@tt1lock.org Remove lock to reply.
Roedy Green - 10 Jul 2005 06:22 GMT >That really was bad, though. At least these days machines can >read and write source code - and do some editing tasks for us. > >The preprocessor was one of the things that made that *very* >challenging to do properly in C/C++. I don't want it back, just the ability to encapsulate any sort of repetitive pattern. I can write "stompers" - code generators and skeleton generators written in Java to get you started, but they are not so hot for maintenance.
 Signature Bush crime family lost/embezzled $3 trillion from Pentagon. Complicit Bush-friendly media keeps mum. Rumsfeld confesses on video. http://www.infowars.com/articles/us/mckinney_grills_rumsfeld.htm
Canadian Mind Products, Roedy Green. See http://mindprod.com/iraq.html photos of Bush's war crimes
Dale King - 15 Jul 2005 04:41 GMT >>That really was bad, though. At least these days machines can >>read and write source code - and do some editing tasks for us. [quoted text clipped - 6 lines] > skeleton generators written in Java to get you started, but they are > not so hot for maintenance. You might want to check out OpenJava (http://www.csg.is.titech.ac.jp/openjava/) which would be able to do what you want. It takes some study to wrap your head around it, but it is pretty cool.
 Signature Dale King
Stefan Ram - 09 Jul 2005 16:48 GMT >Sometimes I just long for C preprocessor macro ability for when >Java won't let you encapsulate patterns without a fight. I could not resist that temptation.
I have a very early version of such an experimental preprocessor, which I develope just for fun.
It is written in Java and called "Metava". To simplify the implementation, it uses a package that can read extended S-expressions in a language, which I call "Unotal".
My first goal is to have Metava to be able to pre-process itself to Java, so that I can write Metava in Metava.
This is not yet finished; what works so far is that the following input (which is the very start of the preprocessor source code only) is translated to Java.
< import = < de.dclj.ram.notation.unotal.RoomSource de.dclj.ram.notation.unotal.StringValue de.dclj.ram.notation.unotal.SetValue de.dclj.ram.notation.unotal.FileRoomModule.fileRoom >
Hello = < verbose = < from=String < &ePrint it >> error = < from=String < &ePrint it >> warning = < from=String < &ePrint it >> emit = < from=String < &write it >> emitLine = < < &line > < &emitIndentation >> quit = < < &verbose ["quitting"] >< &System.exit 99 >> indentation = < type=int > indent = << &increment indentation by=2 >> outdent = << &decrement indentation by=2 >> emitIndentation = < < &repeat times=indentation < &write [" "] > >> emitLine = < from=int < &repeat < &line >>< &emitIndentation >> emitOpen = < < &emitLine >< &emit ["{ "] >< &indent >> emitLeft = < from=boolean < &emitLine >< &emit ["("] >< &if <&emit [" "]>> <&indent> > emitClose = < from=boolean < &if <&emit [" "]>>< &emit ["}"]>< &outdent >> emitRight = < from=boolean < &if <&emit [" "]>>< &emit [")"]>< &outdent >> < mainClass = < type=String value=["Hello"] > source = < type=RoomSource > < &verbose ["OK 555E6k: main"] >>>>>
The last three lines are supposed to become the body of the main-method, but I see from the output, that a bug still prevents it to be generated from them.
There are some fixed ad-hoc abbreviations for names used often, like "ePrint" for "java.lang.System.err.printLn", but I try to keep their number small.
The point is that I can implement whatever notation I would like to have in that preprocessor. When I write a program with it and miss a notation, I can add it to the preprocessor and use it.
To explain a procedure definition in more detail as an example:
emitLine = < from=int < &repeat < &line >>< &emitIndentation >>
defines a procedure "emitLine". The name of the int-Parameter defaults to "it". The "&repeat" keyword generates a loop to repeat something a number of times, which - if unspecified - also defaults to "it". So this gives "emitLine" as it can be seen in the following Java-source-code that was generated from the Metava-Source-code above:
import de.dclj.ram.notation.unotal.RoomSource; import de.dclj.ram.notation.unotal.StringValue; import de.dclj.ram.notation.unotal.SetValue; import static de.dclj.ram.notation.unotal.FileRoomModule.fileRoom;
public class Hello { public static void emitClose ( final boolean it ) { if ( it ) { emit ( " " ); } emit ( "}" ); outdent (); } public static void emitIndentation () { for ( int i = indentation; i-- > 0; )java.lang.System.out.print ( " " ); } public static void outdent () { indentation -= 2; } public static void emitLeft ( final boolean it ) { emitLine (); emit ( "(" ); if ( it ) { emit ( " " ); } indent (); } public static int indentation; public static void error ( final String it ) { java.lang.System.err.println ( it ); } public static void quit () { verbose ( "quitting" ); System.exit ( 99 ); } public static void emit ( final String it ) { java.lang.System.out.print ( it ); } public static void main ( final java.lang.String[] it ) { } public static void warning ( final String it ) { java.lang.System.err.println ( it ); } public static void emitRight ( final boolean it ) { if ( it ) { emit ( " " ); } emit ( ")" ); outdent (); } public static void verbose ( final String it ) { java.lang.System.err.println ( it ); } public static void emitLine ( final int it ) { for ( int i = it; i-- > 0; )line (); emitIndentation (); } public static void emitLine () { line (); emitIndentation (); } public static void indent () { indentation += 2; } public static void emitOpen () { emitLine (); emit ( "{ " ); indent (); }}
Owen Jacobson - 09 Jul 2005 23:41 GMT > Sometimes I just long for C preprocessor macro ability for when Java won't > let you encapsulate patterns without a fight. Nothing's particularly stopping you from making m4 or even cpp part of your build process. It won't play nice with javac's automatic dependency resolution, but that's not impossible to work around (just run m4 on the whole source tree before doing any compilation).
Make sure you really need that before implementing such a beast.
-O
Tim Tyler - 10 Jul 2005 09:05 GMT Owen Jacobson <ojacobson@example.com> wrote or quoted:
> > Sometimes I just long for C preprocessor macro ability for when Java won't > > let you encapsulate patterns without a fight. [quoted text clipped - 3 lines] > resolution, but that's not impossible to work around (just run m4 on the > whole source tree before doing any compilation). Stuff like that would probably stop Eclipse's check-as-you-type, from working, stop its "quick fixes" from working, would probably prevent its refactoring tools from working and might well play havoc with tools like Checkstyle.
> Make sure you really need that before implementing such a beast. Indeed.
 Signature __________ |im |yler http://timtyler.org/ tim@tt1lock.org Remove lock to reply.
Thomas Weidenfeller - 05 Jul 2005 10:27 GMT > I find this pattern occurs repeatedly: > [quoted text clipped - 13 lines] > I can't figure out an elegant way to encapsulate the length test in > addToken. Well, if accumulatedQuotation and accumulatedComment are of different types, then something like this could do:
------------------------------------------------------------------- public abstract class BaseAccumulator {
public void addAsTokenTo(SomeClass caller) { String s = toFinalString(); if(s.length() > 0) { caller.addToken(createToken(s)); } }
protected abstract BaseToken createToken(String s);
public String toFinalString() { ... } }
public class QuotationAccumulator extends BaseAccumulator { // create matching token protected BaseToken createToken(s) { return new StringLiteralToken(s); } }
public class CommentAccumulator extends BaseAccumulator { // create matching token protected BaseToken createToken(s) { return new CommentLiteralToken(s); } }
public class SomeClass { public void addToken(BaseToken t) { ... }
public void someMethod() {
accumulatedQuotation.addAsTokenTo(this); accumulatedComment.addAsTokenTo(this); } } -------------------------------------------------------------------
If this is not the case, you could try something like this, which is still ugly:
------------------------------------------------------------------- public class TokenAdder /* what a stupid class name ... */ {
public static void addStringLiteralToken(String s , SomeClass caller) { if(s.length() > 0) { caller.addToken(new StringLiteralToken(s)); } }
public static void addCommentLiteralToken(String s , SomeClass caller) { if(s.length() > 0) { caller.addToken(new CommentLiteralToken(s)); } } }
public class SomeClass { public void addToken(BaseTokenClass t) { ... }
public void someMethod() { String quotation = accumulatedQuotation.toFinalString(); TokenAdder.addStringLiteralToken(quotation, this);
String comment = accumulatedComment.toFinalString(); TokenAdder.addCommentLiteralToken(comment, this); } } -------------------------------------------------------------------
/Thomas
 Signature The comp.lang.java.gui FAQ: ftp://ftp.cs.uu.nl/pub/NEWS.ANSWERS/computer-lang/java/gui/faq http://www.uni-giessen.de/faq/archiv/computer-lang.java.gui.faq/
Tor Iver Wilhelmsen - 05 Jul 2005 16:37 GMT > addToken( accumulatedQuotation, StringLiteralToken ); > addToken( accumulatedComment, CommentToken ); Use reflection for the constructor:
public void addToken(IAccumulated object, Class clazz) { String quotation = object.toFinalString(); // Interface method if ( quotation.length() > 0 ) // Interface method { addToken( clazz.getConstructor(new Class[] { String.class }) .invoke(new Object[] { quotation }) ); }
}
addToken( accumulatedQuotation, StringLiteralToken.class ); addToken( accumulatedComment, CommentToken.class );
Or use a factory method instead of reflection perhaps.
One of the strengths of the JavaBean model is that you always know there is a no-parameters constructor, so you can use newInstance(), which can (retroactively) be thought of as a shortcut for
getConstructor(new Class[0]).invoke(new Object[0])
Raymond DeCampo - 05 Jul 2005 20:50 GMT > I find this pattern occurs repeatedly: > [quoted text clipped - 33 lines] > it has 0 length or not, then discard it later. That offends me since > the constructors have asserts to prevent creation of bad objects. Roedy,
You don't give us a lot of context here. Perhaps the problem is that you have specialized too soon. That is, if you could have a generic accumulator that spits back strings, then check the length of the string, abort if 0, now determine which token to instantiate. But perhaps this doesn't fit, we do not have enough information to know.
HTH, Ray
 Signature XML is the programmer's duct tape.
Roedy Green - 05 Jul 2005 22:23 GMT >You don't give us a lot of context here. Perhaps the problem is that >you have specialized too soon. That is, if you could have a generic >accumulator that spits back strings, then check the length of the >string, abort if 0, now determine which token to instantiate. But >perhaps this doesn't fit, we do not have enough information to know. I am not looking for a solution just to this particular question. I wanted to explore this class of problem where you want encapsulate the creation of objects. I run into it all the time. This was just a simple example.
But to explain the context. I am redesigning my Tokens and Parsers used for JDisplay. see http://mindprod.com/projects/javapresenter.html for the big picture.
My token is for rendering petty text. You might look on at as compiled HTML. A token typically contains some text to render. It has methods for rendering raw, as CSS HTML, or using my Token rendering Applet. The tokens themselves have almost no data but some text. All the rendering information is in the Class static and instance methods which don't get serialised along the data.
Tokens know nothing about parsing, only about rendering. They know fonts, CSS classes, point sizes, colours, font families preferences etc.
A Tokenizer is a sort of crude Java or Bat compile that breaks the text of a bat file or a Java source code file into word-sized chunks, and identifies them well enough to colourise them. The Java parser is smart enough to tell constants from vars from methods from package names, from definitions and references. It uses a very crude scheme that work even on incomplete or erroneous programs.
A parser's job is to create an array of tokens out of some text so that it can be rendered by HTML, or by my mindless rendering applet that understands no syntax at all. It just renders each token by calling its methods.
For example a StringLiteral Token, used in displaying Java source code, contains the characters between "..." not including the end " marker. It regenerates them on demand. When parsingo "" is legit. so the text inside could be 0 length.
However say a VarName token, contains the name of a java variable. It is not allowed to have 0 length. The parser wants to avoid creating such tokens. It just comes out in the wash that the finite state automaton from time to time might say "we now have a complete variable name". Unfortunately, it might have zero length, e.g. a programmer error or just an artifact of my parser. It is not a bug. I just have to check before adding the Token.
I could create such useless tokens, then prune the list later of ones that would not render anything.
For example, implement a method isUseless() that each token implements to tell if rendered that nothing would happen. You could then remove pointess tokens at the end or just after they had been created before being added. I just can't find an easy way to short circuit before construction.
That may be the cleanest way to handle my current particular problem since the Token, more than the parser knows if it is pointless.
It could also be more general than check checking the string for zero length.
 Signature Bush crime family lost/embezzled $3 trillion from Pentagon. Complicit Bush-friendly media keeps mum. Rumsfeld confesses on video. http://www.infowars.com/articles/us/mckinney_grills_rumsfeld.htm
Canadian Mind Products, Roedy Green. See http://mindprod.com/iraq.html photos of Bush's war crimes
Stefan Schulz - 06 Jul 2005 10:05 GMT > I find this pattern occurs repeatedly: > [quoted text clipped - 18 lines] > addToken( accumulatedQuotation, StringLiteralToken ); > addToken( accumulatedComment, CommentToken ); Why not just do something like this:
interface TokenCreator { Token create(); }
TokenCreator stringMaker = new StringLiteralCreator(); TokenCreator commentMaker = new CommentCreator(); // both implement TokenCreator
addToken(accumulatedComment, commentMaker);
where addToken performs the check, and calls the TokenCreators create method?
 Signature You can't run away forever, But there's nothing wrong with getting a good head start. --- Jim Steinman, "Rock and Roll Dreams Come Through"
Roedy Green - 06 Jul 2005 11:16 GMT >TokenCreator stringMaker = new StringLiteralCreator(); >TokenCreator commentMaker = new CommentCreator(); >// both implement TokenCreator > >addToken(accumulatedComment, commentMaker); I see it works, but I think I am somewhat further behind in terseness. Recall I was just trying to save one line of code adding the token.
To avoid this, it looks as if I have had to write a dozen more lines per token class.
What if Interfaces were extended to permit the specification of constructors and static methods?
you could the use constructors and static methods given only the interface reference.
then you might be able to write code like this using an example object that implements the interface:
void adder ( AnyTokenInterfaceExexemplar a , String value ) { if ( value != 0 ) { AnyTokenInterface b = a.new ( value ); add ( b ); } }
Perhaps the same code could work passing either the name of an class implementing the interface or an example object implementing that interface.
The basic idea is you should be able to pass class objects around with the same sort of inheritance as you pass objects around as parameters.
Static methods would then override in much the same way instance methods do.
The class object should give you access to the class features of the base class, same way objects work. The distinction between objects and classes would blur. new should be not be treated so specially, and be accessible easily once you have a class object.
 Signature Bush crime family lost/embezzled $3 trillion from Pentagon. Complicit Bush-friendly media keeps mum. Rumsfeld confesses on video. http://www.infowars.com/articles/us/mckinney_grills_rumsfeld.htm
Canadian Mind Products, Roedy Green. See http://mindprod.com/iraq.html photos of Bush's war crimes
Kevin McMurtrie - 07 Jul 2005 06:37 GMT > I find this pattern occurs repeatedly: > [quoted text clipped - 33 lines] > it has 0 length or not, then discard it later. That offends me since > the constructors have asserts to prevent creation of bad objects. It sounds like your code is suffering from cumbersome objects. Smarten them up so they're easier to use.
public interface IAccumulatedQuotation { public int length(); public StringLiteralToken toStringLiteralToken(); }
public interface IAccumulatedComment { public int length(); public CommentLiteralToken toCommentLiteralToken(); }
. . .
addToken (IAccumulatedQuotation aq) { addToken(aq.toStringLiteralToken()); }
addToken (IAccumulatedComment ac) { addToken(ac.toCommentLiteralToken()); }
. . .
IAccumulatedQuotation accumulatedQuotation= ... IAccumulatedComment accumulatedComment= ...
if (accumulatedQuotation.length() > 0) addToken(accumulatedQuotation);
if (accumulatedComment.length() > 0) addToken(accumulatedComment);
Roedy Green - 07 Jul 2005 13:39 GMT >IAccumulatedQuotation accumulatedQuotation= ... >IAccumulatedComment accumulatedComment= ... > >if (accumulatedQuotation.length() > 0) > addToken(accumulatedQuotation); That does not make any sense. I have added more code to each of the dozens of Token classes to have one line in the calling. In the end I write more code. It would only make sense if I used these objects in many different contexts that could make use of those smarts.
 Signature Bush crime family lost/embezzled $3 trillion from Pentagon. Complicit Bush-friendly media keeps mum. Rumsfeld confesses on video. http://www.infowars.com/articles/us/mckinney_grills_rumsfeld.htm
Canadian Mind Products, Roedy Green. See http://mindprod.com/iraq.html photos of Bush's war crimes
Kevin McMurtrie - 09 Jul 2005 05:26 GMT > >IAccumulatedQuotation accumulatedQuotation= ... > >IAccumulatedComment accumulatedComment= ... [quoted text clipped - 8 lines] > It would only make sense if I used these objects in many different > contexts that could make use of those smarts. Is there a base class for the tokenizers? That's where generic convenience methods would go.
Roedy Green - 09 Jul 2005 09:50 GMT >Is there a base class for the tokenizers? That's where generic >convenience methods would go. Exactly. The catch in that code can't do any sort of generic construction, even for subclasses that all implement that same constructor.
this is what blocks putting the code where it belongs with only one copy of it.
 Signature Bush crime family lost/embezzled $3 trillion from Pentagon. Complicit Bush-friendly media keeps mum. Rumsfeld confesses on video. http://www.infowars.com/articles/us/mckinney_grills_rumsfeld.htm
Canadian Mind Products, Roedy Green. See http://mindprod.com/iraq.html photos of Bush's war crimes
Free MagazinesGet these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...
|
|
|