From: Robert Klemme Date: 2004-08-02T05:51:37+09:00 Subject: Re: Forward references? "Lloyd Zusman" schrieb im Newsbeitrag news:m3fz7711m6.fsf@asfast.com... > > [ ... ] I like especially the documentation. Some remarks from cursory > > glancing though: > > > > require 'monitor' > > # My list of threads. > > $fileThreads = [].extend MonitorMixin > > # later > > $fileThreads.synchronize do > > # do stuff with $fileThreads > > end > > Why not just use the 'sync' module that is already being utilized in > the program? i.e. ... > > $fileThreads = [].extend(Sync_m) Oh, I overlooked that. Is that std Ruby? (Monitor and Mutex are) > > - You are using exit a bit too much IMHO, especially since you have > > "exit(rtail)" but rtail invokes exit, too. Usage of exit reduces > > reusability of code and thus I would limit it to the to level of the script, > > something like > > > > begin > > # do MAIN stuff > > exit 0 > > rescue Exception => e > > $stderr.puts e > > exit 1 > > end > > Thanks. But how about this slight variation? Since I had exit(rtail), > I could just do it this way ... > > # at the bottom of the script ... > begin > rtail > result = 0 > # or if I want: result = rtail > rescue Exception => e > $stderr.puts("!!! #{e}") > result = 1 > end > exit(result) I prefer this: # at the bottom of the script ... begin exit rtail rescue Exception => e $stderr.puts("!!! #{e}") exit 1 end because it's more robust if you change your mind and want to do different things (like not exiting). It keeps information more local. Maybe this is a habit I got from Java because compilers can warn you if you put the exit (or return for methods) into their respective neighborhood and forget one of them. > .. and then raise exceptions every other place where I was using 'exit'. Yes, definitely. > > And within the rest of the script I'd use exceptions. Patterns like this > > are inferior > > > > begin > > block = self.read(testsize) > > rescue > > return false > > end > > # further code that works with block > > > > Instead put all the code for the clean case into the block or leave the > > rescue completely out here and handle the exception on a higher level. That > > makes things much easier. > > Yes, that's a good approach in many cases, and I will do so in those > instances. However, in a few places, I have different kinds of 'rescue' > responses for different steps within the flow of control. Look at > $fileReadProc in my program, for example. I want my error message to > distinguish between "unable to open", "unable to stat", "invalid > device", etc., and I want to use my own error message text for each of > these instances. I don't see how to avoid a series of short > begin/rescue/end blocks in this case. > > Hmm ... well, I could do this, but I don't like it: > > $errorMessage = 'unknown error' > begin > $errorMessage = 'unable to open' > # open the file > $errorMessage = 'invalid device' > # do stuff that fails if the item is not a file > $errorMessage = 'unable to stat' > # do stat-related stuff > $errorMessage = 'message for next likely exception to be raised' > # ... etc. ... > rescue > begin > f.close > rescue > # file may or may not be open when exception occurs > end > output([nil, "!!! #{$errorMessage}: #{item}]") > abortMyself() > end > > In the case I have shown here, I prefer the smaller begin/rescue/end > blocks, even though that's more verbose. It will be clearer to future > maintainers. It will be even clearer if you break this code up into multiple method invocations. Then you'll have methods like: begin File.open("foo.txt") do |io| # IO is open here # do more stuff end rescue Errno::Enoent => e $stderr.puts "ERROR: ..." rescue OtherError => e ... end Reusing a global (!) for the current error message looks irritating to me. A global is not really needed here. And having a single rescue clause for multiple errors doesn't look good to me either. > > - There is File.split: > > > > # old: $program = $0.sub(/^.*\//, '') > > $dir, $program = File.split $0 > > Yes. I'm just in the habit of doing this myself, especially when I > don't want the '$dir' part. Then you can do $prog = File.split($0)[1] Advantage of File.split is that it's platform independend. Only introduce platform dependencies that are really necessary - that might make your life much easier in the future. Kind regards robert