From: stephen.hill@... (Steve Hill) Date: 2001-08-16T00:12:28+09:00 Subject: [ruby-talk:19785] Re: "new" returning nil: how to report the failure of object creation Hi, surely an appropriate way to handle this problem would be using a Factory design pattern. so (writing off the top of my head - this is not a tested piece of code) you would have something like this; class DataFactory # initialize etc... def getData(file) ret_data=nil line=file.gets("data_end") md=/data_start(.*)data_end/.match(line) ret_data=Data.new(md[1]) unless md==nil return ret_data end end class Data def initialize(str) #... end end The basic idea is that Data is initialized from a string (in the example above the data_start and data_end markups are not part of the string, but it doesn't have to be this way. The DataFactory#getData method reads in a line from file terminated by the end of the next data object (or the end of the file), then uses a regexp to extract the data fields in that line, which it uses to build a Data object. Best regards Steve > Eli Green wrote in message news:<20010814235952.A8247@codedogs.ca>... > > Why not raise an exception? > > > > from Ryo Furue on 2001-08-15 at 12:51:00: > > > Hi there, > > > > > > How do you report the failure of object creation, that is, if you find > > > it impossible to properly initialize the object in the "initialize" > > > method? Raising an exception is clearly an option. But, what if the > > > "failure" is a normal part of the flow of the program?[...] > > Why not raise an exception? Because "Whenever reasonable, one should > stick to the `exception handling is an error handling' view" > (Stroustrup, B., 1997, _The C++ Programming Language_, 3rd ed., > p.375). I agree to this opinion. (Though the quoted statement is > about C++, I think it almost equally applies to Ruby.) > > Why doesn't IO#gets raise an exception when end of file is reached? > Because we usually expect an end of file so that handling it is a > normal part of the program flow: > > while line = gets > .... > end > > You wouldn't write > > begin > loop { > line = gets > .... > } > rescue EndOfFileError # Assume gets raises this exceptsion > # when EOF is reached. > end > > My current problem is similar to this case. My class constructs an > object depending on data in a file. The datafile is in this form: > > non-data > ... > data begin > data > data > .... > data end > non-data > ... > data begin > ... > > Only the class knows what constitutes data and which part of the file > to ignore. So, only by calling "new" of that class can we know > whether the remaining part of the file contains enough data. But, we > also know that the file is bound to reach its end, so that handling > that condition is truly a normal part of our program: > > while s = MyClass.new(file) > arr.push(s) > end > # use arr > > The following > > begin > loop { > s = MyClass.new(file) > arr.push(s) > } > rescue NoMoreData > end > > doesn't make sense to me because I prepare to see the condition > NoMoreData to occur (as end of file for IO#gets): it's not an error. > > Cheers, > Ryo