You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@commons.apache.org by Henri Yandell <fl...@gmail.com> on 2010/03/05 10:32:38 UTC

[lang] LANG-510

Thinking further on moving StringUtils to CharSequence, I'd like to
take the String left(String, int) method as an example. It depends on
substring(int, int), so is entirely possibly to move over to
subSequence(int, int).

Hypothetical new method:

    CharSequence left(CharSequence, int)

The downside here is that users currently storing this in a String are
going to have to cast. Generics to the rescue.

    <T extends CharSequence> T left(T, int)

This hits two problems:

1) EMPTY is returned when the int is less than 0; EMPTY is a String and not T.
2) subSequence returns CharSequence and not T.

I could add a wrapper method to make Strings nicer:

    public static String left(String str, int len) {
        if (str == null) {
            return null;
        }
        return left( (CharSequence) str, len).toString();
    }

But that doesn't help the StringBuffer/StrBuilder/StringBuilder user;
they still get a sucky API.

Am I missing anything obvious here, or should I give up the ghost on
trying to take these methods to CharSequence APIs?

Hen

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
For additional commands, e-mail: dev-help@commons.apache.org


RE: [lang] LANG-510

Posted by Gary Gregory <GG...@seagullsoftware.com>.
Here is another issue that I find confusing at first glance with Generics. I redefined defaultIfEmpty in my sandbox as follows:

    public static <T extends CharSequence> T defaultIfEmpty(T str, T defaultStr) {
        return StringUtils.isEmpty(str) ? defaultStr : str;
    }

This is simple enough but I was surprised that this compiled:

assertEquals("abc", StringUtils.defaultIfEmpty(new StringBuilder("abc"), "NULL"));

I thought that all T's should match, but they do not, the compiler works its type inference magic to match up the call site to the method, such that both arguments are of type CharSequence. The API as coded can return both a String and a StringBuilder depending on the value of the input. That's the confusing part.

The question is: Is it worth this potential confusion to allow any CharSequence to be used?

In this case, the "<T extends CharSequence>" version is the same as:

    public static CharSequence defaultIfEmpty(CharSequence str, CharSequence defaultStr) {
        return StringUtils.isEmpty(str) ? defaultStr : str;
    }

Are there cases where the "<T extends CharSequence>" version is needed?

Gary 

> -----Original Message-----
> From: Henri Yandell [mailto:flamefew@gmail.com]
> Sent: Friday, March 05, 2010 01:33
> To: Commons Developers List
> Subject: [lang] LANG-510
> 
> Thinking further on moving StringUtils to CharSequence, I'd like to
> take the String left(String, int) method as an example. It depends on
> substring(int, int), so is entirely possibly to move over to
> subSequence(int, int).
> 
> Hypothetical new method:
> 
>     CharSequence left(CharSequence, int)
> 
> The downside here is that users currently storing this in a String are
> going to have to cast. Generics to the rescue.
> 
>     <T extends CharSequence> T left(T, int)
> 
> This hits two problems:
> 
> 1) EMPTY is returned when the int is less than 0; EMPTY is a String and not T.
> 2) subSequence returns CharSequence and not T.
> 
> I could add a wrapper method to make Strings nicer:
> 
>     public static String left(String str, int len) {
>         if (str == null) {
>             return null;
>         }
>         return left( (CharSequence) str, len).toString();
>     }
> 
> But that doesn't help the StringBuffer/StrBuilder/StringBuilder user;
> they still get a sucky API.
> 
> Am I missing anything obvious here, or should I give up the ghost on
> trying to take these methods to CharSequence APIs?
> 
> Hen
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
> For additional commands, e-mail: dev-help@commons.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
For additional commands, e-mail: dev-help@commons.apache.org


Re: [lang] v3.0 @since

Posted by Paul Benedict <pb...@apache.org>.
Even if the package names are different and thus binary compatibility
is not preserved, the @since tags are still important to delineate new
functionality before 3.0. It can help people with migrating.

On Mon, Apr 5, 2010 at 12:26 PM, Gary Gregory
<GG...@seagullsoftware.com> wrote:
>> -----Original Message-----
>> From: sebb [mailto:sebbaz@gmail.com]
>> Sent: Saturday, March 27, 2010 16:19
>> To: Commons Developers List
>> Subject: Re: [lang] v3.0 @since
>>
>> On 27/03/2010, Gary Gregory <GG...@seagullsoftware.com> wrote:
>> > Since multiple @since tags are allowed and are treated like multiple @author
>> tags, what about making use of that? For example:
>> >
>> >  ...
>> >      * @since 2.0
>> >      * @since 3.0
>>
>> -1, very confusing - what does it mean?
>>
>> >      */
>> >     public static String capitalize(CharSequence cs) {
>> >  ...
>> >
>> >  Or maybe:
>> >
>> >      * @since 2.0
>> >      * @since 3.0 changed from capitalize(String) to
>> capitalize(CharSequence)
>>
>> +1
>
> I added @since 3.0 tag in this format for StringUtils.
>
> Gary
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
> For additional commands, e-mail: dev-help@commons.apache.org
>
>

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
For additional commands, e-mail: dev-help@commons.apache.org


RE: [lang] v3.0 @since

Posted by Gary Gregory <GG...@seagullsoftware.com>.
> -----Original Message-----
> From: sebb [mailto:sebbaz@gmail.com]
> Sent: Saturday, March 27, 2010 16:19
> To: Commons Developers List
> Subject: Re: [lang] v3.0 @since
> 
> On 27/03/2010, Gary Gregory <GG...@seagullsoftware.com> wrote:
> > Since multiple @since tags are allowed and are treated like multiple @author
> tags, what about making use of that? For example:
> >
> >  ...
> >      * @since 2.0
> >      * @since 3.0
> 
> -1, very confusing - what does it mean?
> 
> >      */
> >     public static String capitalize(CharSequence cs) {
> >  ...
> >
> >  Or maybe:
> >
> >      * @since 2.0
> >      * @since 3.0 changed from capitalize(String) to
> capitalize(CharSequence)
> 
> +1

I added @since 3.0 tag in this format for StringUtils.

Gary


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
For additional commands, e-mail: dev-help@commons.apache.org


Re: [lang] v3.0 @since

Posted by sebb <se...@gmail.com>.
On 27/03/2010, Gary Gregory <GG...@seagullsoftware.com> wrote:
> Since multiple @since tags are allowed and are treated like multiple @author tags, what about making use of that? For example:
>
>  ...
>      * @since 2.0
>      * @since 3.0

-1, very confusing - what does it mean?

>      */
>     public static String capitalize(CharSequence cs) {
>  ...
>
>  Or maybe:
>
>      * @since 2.0
>      * @since 3.0 changed from capitalize(String) to capitalize(CharSequence)

+1

>  Or something like that, since the @since text is free form.
>
>
>  Gary Gregory
>  Senior Software Engineer
>  Seagull Software
>  email: ggregory@seagullsoftware.com
>  email: ggregory@apache.org
>  www.seagullsoftware.com
>
>
>
>
> > -----Original Message-----
>  > From: Henri Yandell [mailto:flamefew@gmail.com]
>
> > Sent: Saturday, March 27, 2010 14:49
>  > To: Commons Developers List
>  > Subject: Re: [lang] v3.0 @since
>  >
>  > I think so. If a recompile would make it work, then no need to update
>  > the @since. It would be lovely to say @improved 3.0; but at the end of
>  > the day I think we'll have to rely on separate documentation to handle
>  > that.
>  >
>  > On Sun, Mar 7, 2010 at 12:22 AM, Gary Gregory
>  > <GG...@seagullsoftware.com> wrote:
>  > > Fair enough.
>  > >
>  > > What about APIs that change from, for example, String to
>  > CharSequence, should these stay with the same @since tags, even if the
>  > Java version for the project of the @since version did not include the
>  > class CharSequence.
>  > >
>  > > Gary
>  > >
>  > >> -----Original Message-----
>  > >> From: Henri Yandell [mailto:flamefew@gmail.com]
>  > >> Sent: Saturday, March 06, 2010 19:23
>  > >> To: Commons Developers List
>  > >> Subject: Re: [lang] v3.0 @since
>  > >>
>  > >> I think it does.
>  > >>
>  > >> The choice of a new package name was a workaround rather than a
>  > >> declaration of a different package, so the @since's still have
>  > value.
>  > >>
>  > >> Hen
>  > >>
>  > >> On Sat, Mar 6, 2010 at 5:13 PM, Gary Gregory
>  > >> <GG...@seagullsoftware.com> wrote:
>  > >> > Looking at trunk I see that the @since tags are still there. Since
>  > the
>  > >> package o.a.c.lang3 is new, does it make sense to have @since tags
>  > OTHER than
>  > >> 3.0 if any?
>  > >> >
>  > >> > Gary Gregory
>  > >> > Senior Software Engineer
>  > >> > Seagull Software
>  > >> > email: ggregory@seagullsoftware.com
>  > >> > email: ggregory@apache.org
>  > >> > www.seagullsoftware.com
>  > >> >
>  > >> >
>  > >> > ------------------------------------------------------------------
>  > ---
>  > >> > To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
>  > >> > For additional commands, e-mail: dev-help@commons.apache.org
>  > >> >
>  > >> >
>  > >>
>  > >> --------------------------------------------------------------------
>  > -
>  > >> To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
>  > >> For additional commands, e-mail: dev-help@commons.apache.org
>  > >
>  > >
>  > > ---------------------------------------------------------------------
>  > > To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
>  > > For additional commands, e-mail: dev-help@commons.apache.org
>  > >
>  > >
>  >
>  > ---------------------------------------------------------------------
>  > To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
>  > For additional commands, e-mail: dev-help@commons.apache.org
>
>
>  ---------------------------------------------------------------------
>  To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
>  For additional commands, e-mail: dev-help@commons.apache.org
>
>

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
For additional commands, e-mail: dev-help@commons.apache.org


RE: [lang] v3.0 @since

Posted by Gary Gregory <GG...@seagullsoftware.com>.
Since multiple @since tags are allowed and are treated like multiple @author tags, what about making use of that? For example:

...
     * @since 2.0
     * @since 3.0 
     */
    public static String capitalize(CharSequence cs) {
...

Or maybe:

     * @since 2.0
     * @since 3.0 changed from capitalize(String) to capitalize(CharSequence)

Or something like that, since the @since text is free form.

Gary Gregory
Senior Software Engineer
Seagull Software
email: ggregory@seagullsoftware.com
email: ggregory@apache.org
www.seagullsoftware.com 



> -----Original Message-----
> From: Henri Yandell [mailto:flamefew@gmail.com]
> Sent: Saturday, March 27, 2010 14:49
> To: Commons Developers List
> Subject: Re: [lang] v3.0 @since
> 
> I think so. If a recompile would make it work, then no need to update
> the @since. It would be lovely to say @improved 3.0; but at the end of
> the day I think we'll have to rely on separate documentation to handle
> that.
> 
> On Sun, Mar 7, 2010 at 12:22 AM, Gary Gregory
> <GG...@seagullsoftware.com> wrote:
> > Fair enough.
> >
> > What about APIs that change from, for example, String to
> CharSequence, should these stay with the same @since tags, even if the
> Java version for the project of the @since version did not include the
> class CharSequence.
> >
> > Gary
> >
> >> -----Original Message-----
> >> From: Henri Yandell [mailto:flamefew@gmail.com]
> >> Sent: Saturday, March 06, 2010 19:23
> >> To: Commons Developers List
> >> Subject: Re: [lang] v3.0 @since
> >>
> >> I think it does.
> >>
> >> The choice of a new package name was a workaround rather than a
> >> declaration of a different package, so the @since's still have
> value.
> >>
> >> Hen
> >>
> >> On Sat, Mar 6, 2010 at 5:13 PM, Gary Gregory
> >> <GG...@seagullsoftware.com> wrote:
> >> > Looking at trunk I see that the @since tags are still there. Since
> the
> >> package o.a.c.lang3 is new, does it make sense to have @since tags
> OTHER than
> >> 3.0 if any?
> >> >
> >> > Gary Gregory
> >> > Senior Software Engineer
> >> > Seagull Software
> >> > email: ggregory@seagullsoftware.com
> >> > email: ggregory@apache.org
> >> > www.seagullsoftware.com
> >> >
> >> >
> >> > ------------------------------------------------------------------
> ---
> >> > To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
> >> > For additional commands, e-mail: dev-help@commons.apache.org
> >> >
> >> >
> >>
> >> --------------------------------------------------------------------
> -
> >> To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
> >> For additional commands, e-mail: dev-help@commons.apache.org
> >
> >
> > ---------------------------------------------------------------------
> > To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
> > For additional commands, e-mail: dev-help@commons.apache.org
> >
> >
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
> For additional commands, e-mail: dev-help@commons.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
For additional commands, e-mail: dev-help@commons.apache.org


Re: [lang] v3.0 @since

Posted by Henri Yandell <fl...@gmail.com>.
I think so. If a recompile would make it work, then no need to update
the @since. It would be lovely to say @improved 3.0; but at the end of
the day I think we'll have to rely on separate documentation to handle
that.

On Sun, Mar 7, 2010 at 12:22 AM, Gary Gregory
<GG...@seagullsoftware.com> wrote:
> Fair enough.
>
> What about APIs that change from, for example, String to CharSequence, should these stay with the same @since tags, even if the Java version for the project of the @since version did not include the class CharSequence.
>
> Gary
>
>> -----Original Message-----
>> From: Henri Yandell [mailto:flamefew@gmail.com]
>> Sent: Saturday, March 06, 2010 19:23
>> To: Commons Developers List
>> Subject: Re: [lang] v3.0 @since
>>
>> I think it does.
>>
>> The choice of a new package name was a workaround rather than a
>> declaration of a different package, so the @since's still have value.
>>
>> Hen
>>
>> On Sat, Mar 6, 2010 at 5:13 PM, Gary Gregory
>> <GG...@seagullsoftware.com> wrote:
>> > Looking at trunk I see that the @since tags are still there. Since the
>> package o.a.c.lang3 is new, does it make sense to have @since tags OTHER than
>> 3.0 if any?
>> >
>> > Gary Gregory
>> > Senior Software Engineer
>> > Seagull Software
>> > email: ggregory@seagullsoftware.com
>> > email: ggregory@apache.org
>> > www.seagullsoftware.com
>> >
>> >
>> > ---------------------------------------------------------------------
>> > To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
>> > For additional commands, e-mail: dev-help@commons.apache.org
>> >
>> >
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
>> For additional commands, e-mail: dev-help@commons.apache.org
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
> For additional commands, e-mail: dev-help@commons.apache.org
>
>

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
For additional commands, e-mail: dev-help@commons.apache.org


RE: [lang] v3.0 @since

Posted by Gary Gregory <GG...@seagullsoftware.com>.
Fair enough. 

What about APIs that change from, for example, String to CharSequence, should these stay with the same @since tags, even if the Java version for the project of the @since version did not include the class CharSequence.

Gary 

> -----Original Message-----
> From: Henri Yandell [mailto:flamefew@gmail.com]
> Sent: Saturday, March 06, 2010 19:23
> To: Commons Developers List
> Subject: Re: [lang] v3.0 @since
> 
> I think it does.
> 
> The choice of a new package name was a workaround rather than a
> declaration of a different package, so the @since's still have value.
> 
> Hen
> 
> On Sat, Mar 6, 2010 at 5:13 PM, Gary Gregory
> <GG...@seagullsoftware.com> wrote:
> > Looking at trunk I see that the @since tags are still there. Since the
> package o.a.c.lang3 is new, does it make sense to have @since tags OTHER than
> 3.0 if any?
> >
> > Gary Gregory
> > Senior Software Engineer
> > Seagull Software
> > email: ggregory@seagullsoftware.com
> > email: ggregory@apache.org
> > www.seagullsoftware.com
> >
> >
> > ---------------------------------------------------------------------
> > To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
> > For additional commands, e-mail: dev-help@commons.apache.org
> >
> >
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
> For additional commands, e-mail: dev-help@commons.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
For additional commands, e-mail: dev-help@commons.apache.org


Re: [lang] v3.0 @since

Posted by Henri Yandell <fl...@gmail.com>.
I think it does.

The choice of a new package name was a workaround rather than a
declaration of a different package, so the @since's still have value.

Hen

On Sat, Mar 6, 2010 at 5:13 PM, Gary Gregory
<GG...@seagullsoftware.com> wrote:
> Looking at trunk I see that the @since tags are still there. Since the package o.a.c.lang3 is new, does it make sense to have @since tags OTHER than 3.0 if any?
>
> Gary Gregory
> Senior Software Engineer
> Seagull Software
> email: ggregory@seagullsoftware.com
> email: ggregory@apache.org
> www.seagullsoftware.com
>
>
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
> For additional commands, e-mail: dev-help@commons.apache.org
>
>

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
For additional commands, e-mail: dev-help@commons.apache.org


[lang] v3.0 @since

Posted by Gary Gregory <GG...@seagullsoftware.com>.
Looking at trunk I see that the @since tags are still there. Since the package o.a.c.lang3 is new, does it make sense to have @since tags OTHER than 3.0 if any?

Gary Gregory
Senior Software Engineer
Seagull Software
email: ggregory@seagullsoftware.com
email: ggregory@apache.org
www.seagullsoftware.com 


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
For additional commands, e-mail: dev-help@commons.apache.org


RE: [lang] LANG-510

Posted by Gary Gregory <GG...@seagullsoftware.com>.
Here is another low hanging fruit:

    public static int length(CharSequence str) {
        return str == null ? 0 : str.length();
    }

I committed that one since it is trivial and matches the is*(CharSequence) methods already there.

Gary 

> -----Original Message-----
> From: Henri Yandell [mailto:flamefew@gmail.com]
> Sent: Friday, March 05, 2010 01:33
> To: Commons Developers List
> Subject: [lang] LANG-510
> 
> Thinking further on moving StringUtils to CharSequence, I'd like to
> take the String left(String, int) method as an example. It depends on
> substring(int, int), so is entirely possibly to move over to
> subSequence(int, int).
> 
> Hypothetical new method:
> 
>     CharSequence left(CharSequence, int)
> 
> The downside here is that users currently storing this in a String are
> going to have to cast. Generics to the rescue.
> 
>     <T extends CharSequence> T left(T, int)
> 
> This hits two problems:
> 
> 1) EMPTY is returned when the int is less than 0; EMPTY is a String and not T.
> 2) subSequence returns CharSequence and not T.
> 
> I could add a wrapper method to make Strings nicer:
> 
>     public static String left(String str, int len) {
>         if (str == null) {
>             return null;
>         }
>         return left( (CharSequence) str, len).toString();
>     }
> 
> But that doesn't help the StringBuffer/StrBuilder/StringBuilder user;
> they still get a sucky API.
> 
> Am I missing anything obvious here, or should I give up the ghost on
> trying to take these methods to CharSequence APIs?
> 
> Hen
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
> For additional commands, e-mail: dev-help@commons.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
For additional commands, e-mail: dev-help@commons.apache.org


Re: [lang] LANG-510

Posted by Jörg Schaible <jo...@gmx.de>.
Paul Benedict wrote:

> On Fri, Mar 5, 2010 at 6:17 AM, Niall Pemberton
> <ni...@gmail.com> wrote:
>> Hmmm - I expected/assumed it would return the same type.
> 
> Type T means exactly that: one type. It wouldn't be type-safe if the
> types were changed between input and output.

??  There is no generic type anymore

- Jörg


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
For additional commands, e-mail: dev-help@commons.apache.org


Re: [lang] LANG-510

Posted by Paul Benedict <pb...@apache.org>.
On Fri, Mar 5, 2010 at 6:17 AM, Niall Pemberton
<ni...@gmail.com> wrote:
> Hmmm - I expected/assumed it would return the same type.

Type T means exactly that: one type. It wouldn't be type-safe if the
types were changed between input and output.

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
For additional commands, e-mail: dev-help@commons.apache.org


Re: [lang] LANG-510

Posted by Niall Pemberton <ni...@gmail.com>.
On Fri, Mar 5, 2010 at 11:12 AM, Jörg Schaible <jo...@gmx.de> wrote:
> Henri Yandell wrote at Freitag, 5. März 2010 10:32:
>
>> Thinking further on moving StringUtils to CharSequence, I'd like to
>> take the String left(String, int) method as an example. It depends on
>> substring(int, int), so is entirely possibly to move over to
>> subSequence(int, int).
>>
>> Hypothetical new method:
>>
>>     CharSequence left(CharSequence, int)
>>
>> The downside here is that users currently storing this in a String are
>> going to have to cast. Generics to the rescue.
>>
>>     <T extends CharSequence> T left(T, int)
>>
>> This hits two problems:
>>
>> 1) EMPTY is returned when the int is less than 0; EMPTY is a String and
>> not T.
>> 2) subSequence returns CharSequence and not T.
>
> Because you do not necessarily get the same type. The API gives room for
> optimized types.
>
>> I could add a wrapper method to make Strings nicer:
>>
>>     public static String left(String str, int len) {
>>         if (str == null) {
>>             return null;
>>         }
>>         return left( (CharSequence) str, len).toString();
>>     }
>>
>> But that doesn't help the StringBuffer/StrBuilder/StringBuilder user;
>> they still get a sucky API.
>>
>> Am I missing anything obvious here, or should I give up the ghost on
>> trying to take these methods to CharSequence APIs?
>
> Since the most important implementations (String/StringBuilder/StringBuffer)
> all return effectively a String,

Hmmm - I expected/assumed it would return the same type.

Niall

> you may actually return one also:
>
>     public static String left(CharSequence str, int len) {
>         if (str == null) {
>             return null;
>         }
>         return str.subSequence(0, len).toString();
>     }
>
> Opinions?
>
> - Jörg
>

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
For additional commands, e-mail: dev-help@commons.apache.org


Re: [lang] LANG-510

Posted by Jörg Schaible <jo...@gmx.de>.
Henri Yandell wrote at Freitag, 5. März 2010 10:32:

> Thinking further on moving StringUtils to CharSequence, I'd like to
> take the String left(String, int) method as an example. It depends on
> substring(int, int), so is entirely possibly to move over to
> subSequence(int, int).
> 
> Hypothetical new method:
> 
>     CharSequence left(CharSequence, int)
> 
> The downside here is that users currently storing this in a String are
> going to have to cast. Generics to the rescue.
> 
>     <T extends CharSequence> T left(T, int)
> 
> This hits two problems:
> 
> 1) EMPTY is returned when the int is less than 0; EMPTY is a String and
> not T. 
> 2) subSequence returns CharSequence and not T.

Because you do not necessarily get the same type. The API gives room for 
optimized types.

> I could add a wrapper method to make Strings nicer:
> 
>     public static String left(String str, int len) {
>         if (str == null) {
>             return null;
>         }
>         return left( (CharSequence) str, len).toString();
>     }
> 
> But that doesn't help the StringBuffer/StrBuilder/StringBuilder user;
> they still get a sucky API.
> 
> Am I missing anything obvious here, or should I give up the ghost on
> trying to take these methods to CharSequence APIs?

Since the most important implementations (String/StringBuilder/StringBuffer) 
all return effectively a String, you may actually return one also:

     public static String left(CharSequence str, int len) {
         if (str == null) {
             return null;
         }
         return str.subSequence(0, len).toString();
     }

Opinions?

- Jörg


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
For additional commands, e-mail: dev-help@commons.apache.org


RE: Spaves vs. tabs (was: [lang] LANG-510)

Posted by Gary Gregory <GG...@seagullsoftware.com>.
Absolutely, that was not my intention. Thank you for letting me know.

Gary Gregory
Senior Software Engineer
Seagull Software
email: ggregory@seagullsoftware.com
email: ggregory@apache.org
www.seagullsoftware.com 



> -----Original Message-----
> From: Jörg Schaible [mailto:joerg.schaible@gmx.de]
> Sent: Monday, March 15, 2010 00:10
> To: dev@commons.apache.org
> Subject: OT: Spaves vs. tabs (was: [lang] LANG-510)
> 
> Hi Gary,
> 
> looking at your last commits I can see that a lot of lines have been
> changes
> simply because the lines now start with tabs instead of spaces. Can you
> turn
> off this seeting in your editor please?
> 
> - Jörg
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
> For additional commands, e-mail: dev-help@commons.apache.org


OT: Spaves vs. tabs (was: [lang] LANG-510)

Posted by Jörg Schaible <jo...@gmx.de>.
Hi Gary,

looking at your last commits I can see that a lot of lines have been changes 
simply because the lines now start with tabs instead of spaces. Can you turn 
off this seeting in your editor please?

- Jörg


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
For additional commands, e-mail: dev-help@commons.apache.org


RE: [lang] LANG-510

Posted by Gary Gregory <GG...@seagullsoftware.com>.
> -----Original Message-----
> From: Stephen Colebourne [mailto:scolebourne@btopenworld.com]
> Sent: Sunday, March 14, 2010 06:44
> To: Commons Developers List
> Subject: Re: [lang] LANG-510
> 
> I do fear that this discussion may be over-thinking. Most users will, I
> believe, be working with String and want a String back. Many of these
> calls may be in time-critical code, so the conversion from a
> CharSequence (even though trivial) may be a small overhead.

Hi Stephen,

Thank you for your feedback. At the risk of continuing to over think... :)

I think I may be misunderstanding your comment but... Here is an example where I do not see any overhead changes: changing methods like isEmpty from isEmpty(String) to isEmpty(CharSequence) is "free" I claim. 

For StringUtils methods where the return type is not a String and the input is a String that happens to only use the CharSequence API, changing the parameter signature from String to CharSequence seems painless.

For the other conversions, it might be too much to chew off until customers ask for it.

> 
> We also have StrBuilder for those cases where a user needs a kind of
> builder approach. Personally, I use StrBuilder instead of
> StringBuffer/StringBuilder whenever I can.
> 
> With CharSequence you need to ask if it makes sense for the operation
> to
> be called on an input stream or similar - because that is, as much as
> anything, what the interface was designed for.
> 
> In summary, I don't overly object to the methods being changed to take
> a
> CharSequence, although I do think its a waste. StringUtils should never
> return CharSequence. 

Yes, good catch. This signature of the method defaultIfEmpty is a bug:

CharSequence defaultIfEmpty(CharSequence str, CharSequence defaultStr)

It is a bug because the following does not compile without casting the result value:

String s = StringUtils.defaultIfEmpty("abc", "NULL");

But this compiles and tests pass:

<T extends CharSequence> T defaultIfEmpty(T str, T defaultStr)

There are currently no StringUtils APIs that return CharSequence only.

I also have string doubts over the utilty of a
> CharSequenceUtils.

I have backed out some code from CSU. I am going to keep working on this locally.

Gary

> 
> Stephen
> 
> 
> Gary Gregory wrote:
> > Working with (trunk) StringUtils (SU) I see the following emerge:
> >
> > - In SVN already and continuing: Change StringUtils arguments from
> String to CharSequence (CS).
> >
> > - This leads to replacing calls to String.substring(int[,int]) with
> calls to CharSequence.subSequence(int)
> >
> > - This leads to creating a CharSequenceUtils class (in SVN now, more
> on this new class below) and
> CharSequenceUtils.subSequence(CharSequence,int) to avoid changing
> "str.substring(start)" over and over to "str.subSequence(start,
> str.length())". For examples, see new versions of capitalize and
> uncapitalize.
> >
> > - We end up using a toString() on CharSequence to return a String
> from StringUtil when working with a CharSequence.
> >
> > So we have StringUtils using CharSequence inputs as much as possible
> instead of String, which is nice.
> >
> > The CharSequence method subSequence returns a CharSequence; though
> the Javadoc states "Returns a new CharSequence that is a subsequence of
> this sequence.", this does not guaranteed the return value to be the
> same kind of CharSequence as the receiver). Since we are after all in a
> class called StringUtil, calling toString() is a must.
> >
> > I propose that we create when possible the methods that are now
> StringUtils CharSequence methods into CharSequenceUtils and let
> StringUtil call CharSequenceUtils and then do its toString() and other
> String specific logic. Later we could have other CharSequence type of
> utils (for CharBuffer, StringBuiler, StringBuffer, etc) that use the
> 'primitives' from CharSequenceUtils.
> > This means that for methods that are based solely on methods that are
> now in CharSequence, these can be moved to CharSequenceUtils without
> effort (all is* methods only call CharSequence#length() and charAt()
> for example and are now typed as CS, still in SU).
> >
> > We can leave @deprecateds method in SU as a nicety to avoid too much
> porting pain: First change the package to lang3 then you can 'optimize'
> by changing call sites from SU to CSU.
> >
> > As a start, I put in SVN a CharSequenceUtils (CSU) implementation for
> length() and subSequence().
> >
> > Thoughts?
> >
> > Gary
> >> -----Original Message-----
> >> From: Jörg Schaible [mailto:joerg.schaible@gmx.de]
> >> Sent: Sunday, March 07, 2010 05:54
> >> To: dev@commons.apache.org
> >> Subject: RE: [lang] LANG-510
> >>
> >> Gary Gregory wrote:
> >>
> >>> When I replaced the current implementation of
> StringUtils.left(String,int)
> >>> with:
> >>>
> >>>     @SuppressWarnings("unchecked")
> >>>     public static <T extends CharSequence> T left(T cs, int len) {
> >>>         if (cs == null) {
> >>>             return null;
> >>>         }
> >>>         if (len < 0) {
> >>>             return (T) cs.subSequence(0, 0);
> >>>         }
> >>>         if (cs.length() <= len) {
> >>>             return cs;
> >>>         }
> >>>         return (T) cs.subSequence(0, len);
> >>>     }
> >>>
> >>> Everything compiled, all tests passed, and no Unnecessary cast
> warnings
> >>> came up (as provided by Eclipse 3.6M5)
> >>>
> >>> The problem is what happens when you pass in a non-Strings, like a
> >>> StringBuilder. The implementation of subsequence for StringBuilder
> returns
> >>> a new String, not new StringBuilder.
> >> Then why not use already proposed:
> >>
> >>      public static String left(CharSequence str, int len) {
> >>          if (str == null) {
> >>              return null;
> >>          }
> >>          return str.subSequence(0, len).toString();
> >>      }
> >>
> >> ??
> >>
> >> - Jörg
> >>
> >>
> >> --------------------------------------------------------------------
> -
> >> To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
> >> For additional commands, e-mail: dev-help@commons.apache.org
> >
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
> For additional commands, e-mail: dev-help@commons.apache.org


Re: [lang] LANG-510

Posted by Stephen Colebourne <sc...@btopenworld.com>.
I do fear that this discussion may be over-thinking. Most users will, I 
believe, be working with String and want a String back. Many of these 
calls may be in time-critical code, so the conversion from a 
CharSequence (even though trivial) may be a small overhead.

We also have StrBuilder for those cases where a user needs a kind of 
builder approach. Personally, I use StrBuilder instead of 
StringBuffer/StringBuilder whenever I can.

With CharSequence you need to ask if it makes sense for the operation to 
be called on an input stream or similar - because that is, as much as 
anything, what the interface was designed for.

In summary, I don't overly object to the methods being changed to take a 
CharSequence, although I do think its a waste. StringUtils should never 
return CharSequence. I also have string doubts over the utilty of a 
CharSequenceUtils.

Stephen


Gary Gregory wrote:
> Working with (trunk) StringUtils (SU) I see the following emerge: 
> 
> - In SVN already and continuing: Change StringUtils arguments from String to CharSequence (CS).
> 
> - This leads to replacing calls to String.substring(int[,int]) with calls to CharSequence.subSequence(int)
> 
> - This leads to creating a CharSequenceUtils class (in SVN now, more on this new class below) and CharSequenceUtils.subSequence(CharSequence,int) to avoid changing "str.substring(start)" over and over to "str.subSequence(start, str.length())". For examples, see new versions of capitalize and uncapitalize.
> 
> - We end up using a toString() on CharSequence to return a String from StringUtil when working with a CharSequence.
> 
> So we have StringUtils using CharSequence inputs as much as possible instead of String, which is nice. 
> 
> The CharSequence method subSequence returns a CharSequence; though the Javadoc states "Returns a new CharSequence that is a subsequence of this sequence.", this does not guaranteed the return value to be the same kind of CharSequence as the receiver). Since we are after all in a class called StringUtil, calling toString() is a must.
> 
> I propose that we create when possible the methods that are now StringUtils CharSequence methods into CharSequenceUtils and let StringUtil call CharSequenceUtils and then do its toString() and other String specific logic. Later we could have other CharSequence type of utils (for CharBuffer, StringBuiler, StringBuffer, etc) that use the 'primitives' from CharSequenceUtils.
> This means that for methods that are based solely on methods that are now in CharSequence, these can be moved to CharSequenceUtils without effort (all is* methods only call CharSequence#length() and charAt() for example and are now typed as CS, still in SU). 
> 
> We can leave @deprecateds method in SU as a nicety to avoid too much porting pain: First change the package to lang3 then you can 'optimize' by changing call sites from SU to CSU.
> 
> As a start, I put in SVN a CharSequenceUtils (CSU) implementation for length() and subSequence().
> 
> Thoughts?
> 
> Gary 
>> -----Original Message-----
>> From: Jörg Schaible [mailto:joerg.schaible@gmx.de]
>> Sent: Sunday, March 07, 2010 05:54
>> To: dev@commons.apache.org
>> Subject: RE: [lang] LANG-510
>>
>> Gary Gregory wrote:
>>
>>> When I replaced the current implementation of StringUtils.left(String,int)
>>> with:
>>>
>>>     @SuppressWarnings("unchecked")
>>>     public static <T extends CharSequence> T left(T cs, int len) {
>>>         if (cs == null) {
>>>             return null;
>>>         }
>>>         if (len < 0) {
>>>             return (T) cs.subSequence(0, 0);
>>>         }
>>>         if (cs.length() <= len) {
>>>             return cs;
>>>         }
>>>         return (T) cs.subSequence(0, len);
>>>     }
>>>
>>> Everything compiled, all tests passed, and no Unnecessary cast warnings
>>> came up (as provided by Eclipse 3.6M5)
>>>
>>> The problem is what happens when you pass in a non-Strings, like a
>>> StringBuilder. The implementation of subsequence for StringBuilder returns
>>> a new String, not new StringBuilder.
>> Then why not use already proposed:
>>
>>      public static String left(CharSequence str, int len) {
>>          if (str == null) {
>>              return null;
>>          }
>>          return str.subSequence(0, len).toString();
>>      }
>>
>> ??
>>
>> - Jörg
>>
>>
>> ---------------------------------------------------------------------
>> To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
>> For additional commands, e-mail: dev-help@commons.apache.org
> 

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
For additional commands, e-mail: dev-help@commons.apache.org


[lang] LANG-607 StringUtils.containsAny methods incorrectly matches Unicode 2.0+ supplementary characters.

Posted by Gary Gregory <GG...@seagullsoftware.com>.
Hi All:

I just encountered an interesting issue while looking at the source for the JRE String class and our own StringUtils class. In one method at least we are not accounting for Unicode supplementary characters. 

For details, see https://issues.apache.org/jira/browse/LANG-607 StringUtils.containsAny methods incorrectly matches Unicode 2.0+ supplementary characters.

What I think this is fixed by [LANG-607] and is worth watching for in other methods and classes.

I am not sure if we need a ticket to cover a general survey for all of [lang] but at least we know about it.

Gary Gregory
Senior Software Engineer
Seagull Software
email: ggregory@seagullsoftware.com
email: ggregory@apache.org
www.seagullsoftware.com 


RE: [lang] LANG-510

Posted by Gary Gregory <GG...@seagullsoftware.com>.
Working with (trunk) StringUtils (SU) I see the following emerge: 

- In SVN already and continuing: Change StringUtils arguments from String to CharSequence (CS).

- This leads to replacing calls to String.substring(int[,int]) with calls to CharSequence.subSequence(int)

- This leads to creating a CharSequenceUtils class (in SVN now, more on this new class below) and CharSequenceUtils.subSequence(CharSequence,int) to avoid changing "str.substring(start)" over and over to "str.subSequence(start, str.length())". For examples, see new versions of capitalize and uncapitalize.

- We end up using a toString() on CharSequence to return a String from StringUtil when working with a CharSequence.

So we have StringUtils using CharSequence inputs as much as possible instead of String, which is nice. 

The CharSequence method subSequence returns a CharSequence; though the Javadoc states "Returns a new CharSequence that is a subsequence of this sequence.", this does not guaranteed the return value to be the same kind of CharSequence as the receiver). Since we are after all in a class called StringUtil, calling toString() is a must.

I propose that we create when possible the methods that are now StringUtils CharSequence methods into CharSequenceUtils and let StringUtil call CharSequenceUtils and then do its toString() and other String specific logic. Later we could have other CharSequence type of utils (for CharBuffer, StringBuiler, StringBuffer, etc) that use the 'primitives' from CharSequenceUtils.
This means that for methods that are based solely on methods that are now in CharSequence, these can be moved to CharSequenceUtils without effort (all is* methods only call CharSequence#length() and charAt() for example and are now typed as CS, still in SU). 

We can leave @deprecateds method in SU as a nicety to avoid too much porting pain: First change the package to lang3 then you can 'optimize' by changing call sites from SU to CSU.

As a start, I put in SVN a CharSequenceUtils (CSU) implementation for length() and subSequence().

Thoughts?

Gary 
> -----Original Message-----
> From: Jörg Schaible [mailto:joerg.schaible@gmx.de]
> Sent: Sunday, March 07, 2010 05:54
> To: dev@commons.apache.org
> Subject: RE: [lang] LANG-510
> 
> Gary Gregory wrote:
> 
> > When I replaced the current implementation of StringUtils.left(String,int)
> > with:
> >
> >     @SuppressWarnings("unchecked")
> >     public static <T extends CharSequence> T left(T cs, int len) {
> >         if (cs == null) {
> >             return null;
> >         }
> >         if (len < 0) {
> >             return (T) cs.subSequence(0, 0);
> >         }
> >         if (cs.length() <= len) {
> >             return cs;
> >         }
> >         return (T) cs.subSequence(0, len);
> >     }
> >
> > Everything compiled, all tests passed, and no Unnecessary cast warnings
> > came up (as provided by Eclipse 3.6M5)
> >
> > The problem is what happens when you pass in a non-Strings, like a
> > StringBuilder. The implementation of subsequence for StringBuilder returns
> > a new String, not new StringBuilder.
> 
> Then why not use already proposed:
> 
>      public static String left(CharSequence str, int len) {
>          if (str == null) {
>              return null;
>          }
>          return str.subSequence(0, len).toString();
>      }
> 
> ??
> 
> - Jörg
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
> For additional commands, e-mail: dev-help@commons.apache.org


RE: [lang] LANG-510

Posted by Gary Gregory <GG...@seagullsoftware.com>.
Well, sure, I was just hoping there was a way to make match input and output types.

Gary 

> -----Original Message-----
> From: Jörg Schaible [mailto:joerg.schaible@gmx.de]
> Sent: Sunday, March 07, 2010 05:54
> To: dev@commons.apache.org
> Subject: RE: [lang] LANG-510
> 
> Gary Gregory wrote:
> 
> > When I replaced the current implementation of StringUtils.left(String,int)
> > with:
> >
> >     @SuppressWarnings("unchecked")
> >     public static <T extends CharSequence> T left(T cs, int len) {
> >         if (cs == null) {
> >             return null;
> >         }
> >         if (len < 0) {
> >             return (T) cs.subSequence(0, 0);
> >         }
> >         if (cs.length() <= len) {
> >             return cs;
> >         }
> >         return (T) cs.subSequence(0, len);
> >     }
> >
> > Everything compiled, all tests passed, and no Unnecessary cast warnings
> > came up (as provided by Eclipse 3.6M5)
> >
> > The problem is what happens when you pass in a non-Strings, like a
> > StringBuilder. The implementation of subsequence for StringBuilder returns
> > a new String, not new StringBuilder.
> 
> Then why not use already proposed:
> 
>      public static String left(CharSequence str, int len) {
>          if (str == null) {
>              return null;
>          }
>          return str.subSequence(0, len).toString();
>      }
> 
> ??
> 
> - Jörg
> 
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
> For additional commands, e-mail: dev-help@commons.apache.org


RE: [lang] LANG-510

Posted by Jörg Schaible <jo...@gmx.de>.
Gary Gregory wrote:

> When I replaced the current implementation of StringUtils.left(String,int)
> with:
> 
>     @SuppressWarnings("unchecked")
>     public static <T extends CharSequence> T left(T cs, int len) {
>         if (cs == null) {
>             return null;
>         }
>         if (len < 0) {
>             return (T) cs.subSequence(0, 0);
>         }
>         if (cs.length() <= len) {
>             return cs;
>         }
>         return (T) cs.subSequence(0, len);
>     }
> 
> Everything compiled, all tests passed, and no Unnecessary cast warnings
> came up (as provided by Eclipse 3.6M5)
> 
> The problem is what happens when you pass in a non-Strings, like a
> StringBuilder. The implementation of subsequence for StringBuilder returns
> a new String, not new StringBuilder.

Then why not use already proposed:

     public static String left(CharSequence str, int len) {
         if (str == null) {
             return null;
         }
         return str.subSequence(0, len).toString();
     }

??

- Jörg


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
For additional commands, e-mail: dev-help@commons.apache.org


RE: [lang] LANG-510

Posted by Gary Gregory <GG...@seagullsoftware.com>.
When I replaced the current implementation of StringUtils.left(String,int) with:

    @SuppressWarnings("unchecked")
    public static <T extends CharSequence> T left(T cs, int len) {
        if (cs == null) {
            return null;
        }
        if (len < 0) {
            return (T) cs.subSequence(0, 0);
        }
        if (cs.length() <= len) {
            return cs;
        }
        return (T) cs.subSequence(0, len);
    }

Everything compiled, all tests passed, and no Unnecessary cast warnings came up (as provided by Eclipse 3.6M5)

The problem is what happens when you pass in a non-Strings, like a StringBuilder. The implementation of subsequence for StringBuilder returns a new String, not new StringBuilder.

So it looks like StringUtils APIs need to be considered one at a time, and tested with more than one CharSequence implementation (String, StringBuilder, StringBuffer at least)

Gary Gregory
Senior Software Engineer
Seagull Software
email: ggregory@seagullsoftware.com
email: ggregory@apache.org
www.seagullsoftware.com 



> -----Original Message-----
> From: Niall Pemberton [mailto:niall.pemberton@gmail.com]
> Sent: Friday, March 05, 2010 02:41
> To: Commons Developers List
> Subject: Re: [lang] LANG-510
> 
> On Fri, Mar 5, 2010 at 9:32 AM, Henri Yandell <fl...@gmail.com> wrote:
> > Thinking further on moving StringUtils to CharSequence, I'd like to
> > take the String left(String, int) method as an example. It depends on
> > substring(int, int), so is entirely possibly to move over to
> > subSequence(int, int).
> >
> > Hypothetical new method:
> >
> >    CharSequence left(CharSequence, int)
> >
> > The downside here is that users currently storing this in a String are
> > going to have to cast. Generics to the rescue.
> >
> >    <T extends CharSequence> T left(T, int)
> >
> > This hits two problems:
> >
> > 1) EMPTY is returned when the int is less than 0; EMPTY is a String and not
> T.
> 
> From CharSequence's subSequence() javadoc "if start == end  then an
> empty sequence is returned". So you could do:
> 
>      return (T)str.subSequence(0, 0);
> 
> Niall
> 
> 
> > 2) subSequence returns CharSequence and not T.
> >
> > I could add a wrapper method to make Strings nicer:
> >
> >    public static String left(String str, int len) {
> >        if (str == null) {
> >            return null;
> >        }
> >        return left( (CharSequence) str, len).toString();
> >    }
> >
> > But that doesn't help the StringBuffer/StrBuilder/StringBuilder user;
> > they still get a sucky API.
> >
> > Am I missing anything obvious here, or should I give up the ghost on
> > trying to take these methods to CharSequence APIs?
> >
> > Hen
> 
> ---------------------------------------------------------------------
> To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
> For additional commands, e-mail: dev-help@commons.apache.org


---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
For additional commands, e-mail: dev-help@commons.apache.org


Re: [lang] LANG-510

Posted by Niall Pemberton <ni...@gmail.com>.
On Fri, Mar 5, 2010 at 9:32 AM, Henri Yandell <fl...@gmail.com> wrote:
> Thinking further on moving StringUtils to CharSequence, I'd like to
> take the String left(String, int) method as an example. It depends on
> substring(int, int), so is entirely possibly to move over to
> subSequence(int, int).
>
> Hypothetical new method:
>
>    CharSequence left(CharSequence, int)
>
> The downside here is that users currently storing this in a String are
> going to have to cast. Generics to the rescue.
>
>    <T extends CharSequence> T left(T, int)
>
> This hits two problems:
>
> 1) EMPTY is returned when the int is less than 0; EMPTY is a String and not T.

>From CharSequence's subSequence() javadoc "if start == end  then an
empty sequence is returned". So you could do:

     return (T)str.subSequence(0, 0);

Niall


> 2) subSequence returns CharSequence and not T.
>
> I could add a wrapper method to make Strings nicer:
>
>    public static String left(String str, int len) {
>        if (str == null) {
>            return null;
>        }
>        return left( (CharSequence) str, len).toString();
>    }
>
> But that doesn't help the StringBuffer/StrBuilder/StringBuilder user;
> they still get a sucky API.
>
> Am I missing anything obvious here, or should I give up the ghost on
> trying to take these methods to CharSequence APIs?
>
> Hen

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@commons.apache.org
For additional commands, e-mail: dev-help@commons.apache.org