From: Martin Hansen Date: 2010-04-20T17:18:41+09:00 Subject: Re: Writing a parser > a) Implementation of parsing which I changed from using gets() with a > delimiter because I found that approach too fragile (think of files on > different platforms with different line delimiters, in this case the > defined delimiter does not always work). I admit that you implementation will be more robust and more efficient. However, this parser is meant to be run in a *NIX command line environment so I can connect scripts with pipes (I should perhaps have stated this in the "specs"). Actually, I have some more text on this whole affair: www.biopieces.org and http://code.google.com/p/biopieces/wiki/Introduction#Getting_started > > b) Embedding that in code that follows usual Ruby iterator patterns > and integrates seamless with Enumerable. > >> �def each >> � �loop { yield self.next } >> �end >> end > > This implementation has flaws: > > 1. The loop does not terminate properly. But I think it does?!? From the Ruby book: "External iterators are quite simple to use: just call next each time you want another element. When there are no more elements left, next will raise a StopIteration excep- tion. This may seem unusual—an exception is raised for an expected termination condition rather than an unexpected and exceptional event. (StopIteration is a de- scendant of StandardError and IndexError; note that it is one of the only exception classes that does not have the word “error” in its name.) Ruby follows Python in this external iteration technique. By treating loop termination as an exception, it makes your looping logic extremely simple; there is no need to check the return value of next for a special end-of-iteration value, and there is no need to call some kind of next? predicate before calling next." Not that I have been able to get the syntax right and make this work ... > 2. It does not return "self" which is convention for #each > implementations. I have heard of this convention before, but I seem to have missed it in the Ruby book. I shall see if I can find it. > 3. Worst: there is a design issue here. An #each method of a Record > is expected to iterate through items _within_ (or contained in) the > Record. But what you are actually attempting here is to have > something that during iteration returns records (regardless of their > type). Since your method #each does not have arguments member > variables are needed to determine where to fetch records from. But > since you call this module "Record" you have a weird situation that > you need to create something Recordish (i.e. something with record > state) which also has non record state (for example an IO object) to > start returning other records from somewhere else. This is highly > confusing and hence something I would not let pass if I were doing the > code review on your code. :-) I was going to forget about the "silly" class Record and stick to hashes of strings. So modifying the behavior of each to something like this: include 'my_record' File.open('my_file', 'r').each do |record| puts record.class # => Hash end Or is this completely nuts? Thanks, M -- Posted via http://www.ruby-forum.com/.