From: Stefano Crocco Date: 2008-06-21T04:59:52+09:00 Subject: Re: Problem with while loop. On Friday 20 June 2008, rumpy@mrbitter.org wrote: > Hi, > > > I'd greatly appreciate feedback on the following code. > > > def create_files > names_array = self.read_names #another method in my class > > while names_array.length != 0 > name = names_array.pop > File.open( name, "w" ) { |f| f.puts "File is no longer empty" } > end > > x.create_files > > > Which results in: > > C:/Scripts/Ruby/file_gen.rb:34:in `initialize': Invalid argument - echo > (Errno > > ::EINVAL) > > from C:/Scripts/Ruby/file_gen.rb:34:in `open' > from C:/Scripts/Ruby/file_gen.rb:34:in `create_files' > from C:/Scripts/Ruby/file_gen.rb:42 > > The array contains the strings 'alpha' through 'foxtrot' and before > producing the error above the file 'foxtrot' is created. So the logic > works once before failing. > > When I pull this code out of the class definition it works perfectly > and creates > a file for every name in the array. What noob mistakes am I making? > > > Thanks, > > S. To understand what's going on, one should understand what the error Errno::EINVAL means. Unfortunately, the only explaination a very quick search returned is this: "Invalid argument. This is used to indicate various kinds of problems with passing the wrong argument to a library function." I don't know what can be causing it. I tried passing non-string arguments to File.open, but I always got TypeError s, except when I tried passing an integer, which gave me an Errno::EBADF exception (I'm on linux, though, so maybe on windows that can give you another kind of error). At any rate, the first thing I'd try (maybe you've already done it) is to check that indeed the contents of names_array is what you think it is, putting a p names_array just after creating it. If that doesn't give you a clue, you can rewrite the code in a more rubysh way. If I understand correctly, you're simply iterating on all the elements of the array and the while loop and calls to pop are simply there to know when to stop the loop. In this case, the whole while loop can be replaced by this: array_names.each do |n| File.open(n, "w"){|f| f.puts "File is no longer empty"} end The substance of the code shouldn't change (well, aside from the fact that the array won't be empty at the end), but this should ensure there is no mistake in the logic of the loop (I can't see any, but you never know). Other than this, I don't know what else to suggest. I hope this helps Stefano