"Lloyd Zusman" <ljz / asfast.com> schrieb im Newsbeitrag
news:m3fz7711m6.fsf / asfast.com...

<snip/>

> > [ ... ] 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