ARM Blocks: ease of use and for loops

Howard Lovatt howard.lovatt at iee.org
Mon Nov 23 05:14:59 PST 2009


If you have interfaces I think you can add a Closeable version of a for-each
loop; without the "RandomAccess hell", e.g.:

interface SafeCloseable { void close(); }

interface SafeCloseableIterator<E> extends Iterator<E>, SafeCloseable {}

interface SafeCloseableIterable<E> extends Iterable<E>
{ SafeCloseableIterator safeCloseableIterator(); }

class Source implements SafeCloseableIterable<String> {
  public SafeCloseableIterator safeCloseableIterator() { return new
SourceIterator(); }

  public Iterator iterator() { return new SourceIterator(); }
}

class SourceIterator implements SafeCloseableIterator<String> {
  private static final String[] out = { "Hello", "Hello", "World", "World"
};

  private int index = 0;

  public boolean hasNext() { return ( index >= 0 ) && ( index < out.length
); }

  public String next() { return out[ index++ ]; }

  public void remove() { throw new UnsupportedOperationException( "Not
supported." ); }

  public void close() { index = -1; }
}

class FilterIterator implements SafeCloseableIterator<String> {
  private final SafeCloseableIterator<String> source;

  public FilterIterator( final Source source ) { this.source =
source.safeCloseableIterator(); }

  public boolean hasNext() {
    if ( source.hasNext() ) { source.next(); }
    return source.hasNext();
  }

  public String next() { return source.next(); }

  public void remove() { source.remove(); }

  public void close() { source.close(); }
}

class Filter implements SafeCloseableIterable<String> {
  private final Source source;

  public Filter( final Source source ) { this.source = source; }

  public SafeCloseableIterator safeCloseableIterator() { return new
FilterIterator( source ); }

  public Iterator iterator() { return new FilterIterator( source ); }
}

public class Main {
  public static void main( final String[] notUsed ) {
    final Filter filter = new Filter( new Source() );
    for ( final String s : filter ) { System.out.println( s ); }
    final SafeCloseableIterator<String> i = filter.safeCloseableIterator();
    try {
      while ( i.hasNext() ) {
        final String s = i.next();
        System.out.println( s );
      }
    } finally { i.close(); }
  }
}


2009/11/12 Howard Lovatt <howard.lovatt at iee.org>

> Reinier has raised a good point that you start with a CloseableIterable and
> end up with just an Iterable, this loosing of the Cloaseable type hasn't
> happened in my code (because I am looking for the problem). I can see that
> it would happen in other peoples code and also by mistake. I think this
> problem is solved by using:
>
> try(final String line : iterableFile) {
>    ...
> }
>
> The above try-for-each block will fail at compile time if iterableFile
> isn't of type CloseableIterable.
>
> Secondly, and more controversially, the for-each loop could fail at compile
> time if given a CloseableIteratable as opposed to a normal Iterable.
>
> 2009/11/11 Reinier Zwitserloot <reinier at zwitserloot.com>
>
>> The problem is: If you forget to retrofit a filter, or you're just using
>> one written with java6 or below in mind, then there's no obvious sign that
>> your resource is not being closed. No compiler error or warning. Not even a
>> pattern in the code you can detect. You'll notice a month later, when you've
>> released your product to your customers, who are starting to call in with
>> strange errors involving full DB pools and such. The fix is to write up a
>> custom findbugs plugin, or something similar. Given the way findbugs is not
>> even close to universally used, let alone used with custom plugins, that is
>> not at all a satisfactory answer.
>>
>> That's a very serious problem.
>>
>> --Reinier Zwitserloot
>>
>>
>>
>>
>> On Wed, Nov 11, 2009 at 10:30 PM, Neal Gafter <neal at gafter.com> wrote:
>>
>>> On Wed, Nov 11, 2009 at 1:21 PM, Reinier Zwitserloot <
>>> reinier at zwitserloot.com> wrote:
>>>
>>>> Unless all existing filters are rewritten to support Closeable, and
>>>> their close methods do an instanceof check on the contained Iterator and
>>>> pass on the close call if they are also ClosableIterators, I don't see how
>>>> that's going to work.
>>>
>>>
>>> That sounds like a workable approach.
>>>
>>>
>>
>> ______________________________________________________________________
>> This email has been scanned by the MessageLabs Email Security System.
>> For more information please visit http://www.messagelabs.com/email
>> ______________________________________________________________________
>>
>
>
>
> --
>  -- Howard.
>



-- 
 -- Howard.



More information about the coin-dev mailing list