Construct an Iterator

Let's say you want to construct an Iterator that spits out File objects. What type of data do you usually provide to the constructor of such an Iterator?

  • an array of pre-constructed File objects, or
  • simply raw data (multidimensional array for instance), and let the Iterator create File objects on the fly when Iterated through?

Edit: Although my question was actually ment to be as general a possible, it seems my example is a bit to broad to tackle general, so I'll elaborate a bit more. The File objects I'm talking about are actually file references from a database. See these two tables:

folder
| id | folderId | name             |
------------------------------------
|  1 |     null | downloads        |

file
| id | folderId | name             |
------------------------------------
|  1 |        1 | instructions.pdf |

They reference actual folders and files on a filesystem.

Now, I created a FileManager object. This will be able to return a listing of folders and files. For instance:

FileManager::listFiles( Folder $folder );

... would return an Iterator of File objects (or, come to think of it, rather FileReference objects) from the database.

So what my question boils down to is: If the FileManager object constructs the Iterator in listFiles() would you do something like this (pseudo code):

listFiles( Folder $folder )
{
    // let's assume the following returns an multidimensional array of rows
    $filesData = $db->fetch( $sqlForFetchingFilesFromFolder );
    // let the Iterator take care of constructing the FileReference objects with each iteration
    return FileIterator( $filesData );

}

or (pseudo code):

listFiles( Folder $folder )
{
    // let's assume the following returns an multidimensional array of rows
    $filesData = $db->fetch( $sqlForFetchingFilesFromFolder );
    $files = array();
    for each( $filesData as $fileData )
    {
        $files.push ( new FileReference( $fileData ) );
    }
    // provide the Iterator with precomposed FileReference objects
    return FileIterator( $files );

}

Hope this clarifies things a bit.

Answers


What is your "File" object meant to be? An open handle to a file, or a representation of a file system path which can be opened in turn?

It would generally be a bad idea to open all the files at once - after all, part of the point of using an iterator is that you only access one object at a time. Your iterator could yield one open file at a time, and let the caller take responsibility for closing it, although again that might be slightly odd to use.

Your requirements aren't clear, to be honest - in my experience, most iterators which yield a series of files use something like Directory.GetFiles(pattern) - you don't pass them the raw data at all, you pass them something which they can use to find the data for you.

It's not obvious what you're trying to get at - it feels like you're trying to ask a general question, but you haven't provided enough information to let us advise you. It's like asking, "Do I want to use a string or an integer?" without giving any context.

EDIT: I would probably push all of that logic into FileIterator, personally. Otherwise it's hard to see what value it's really providing. In a language like C# or Python you wouldn't need a separate class in the first place - you'd just use a generator of some description. In that sense this question isn't language agnostic :(


What exactly is your iterator supposed to do? Write data to files? Create them?

An iterator is a pattern for iterating through data, which means providing sequential data in a uniformous way, not mutating them.


I find the question to be unclear.

Are we talking Iterator or Factory?

To me an Iterator is operating on a pre-existing collection of things and allows the caller to work on each thing in turn.

When you say "Spits Out" do you mean allows the client to work with one file from a pre-existing set of files or do you mean that you are iterating some data and intend to store that data in files you are generting. If we are geneating, then we've got a File factory.

My guess is that you are intending to process some files in a file sytstem. I think that your Iterator is akin to a Directory, it can give you the next file it knows about. So I construct the "Driectory" by passing enough data to allow it to know which files you mean (could be just an OS path, could be some kind of "find" enxpression, a list of ftp-like references, etc.) and expect it to give me the next File as I iterate.

----updated following question clarification

I think that the key question here is when the individual files should be opened. The Iterator itself will reasonably return a File object corresponding to an open file handle, the caller can then just work with the file. But iternally should the iterator be working against a list of pre-opened files or a list of file references, the files being opened as the iterator next() is used.

I think we should do the latter, because there is overhead in having an open file, hence we should open the files only when we need them.

That leads to one other point: who closes the file? We can't afford to keep them all open. Perhaps the iterator should close each file as next() is called. This implies that that the iterator itself needs a close() method to allow tidy up of the currently open file. Alterntaivelywe need to explictily document that closing is the client's responsibility.


Need Your Help

Best way to create an element resembling a fraction?

html css fractions

I have tried many ways, including the following:

Can you make Counter not write-out “Counter”

python counter

So when I print the Counter (from collections import Counter) to a file I always get this the literal "Counter ({'Foo': 12})"

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.