From: Kenosis Date: 2007-01-03T08:00:05+09:00 Subject: Re: Methods validating their arguments: good or bad? Michael Judge wrote: > Hi, > > On Dec 30, 2006, at 2:50 PM, dblack@wobblini.net wrote: > > > Hi -- > > > > On Sat, 30 Dec 2006, Michael Judge wrote: > > > >> > >> Code Complete* recommends that methods validate the arguments they > >> receive. The author went on to say that in a 1984 study, > >> researchers discovered that miscommunication between routines > >> caused 39% of the programming errors observed. The idea is that, > >> if we check our arguments before using them, bad data won't flow > >> through undetected, causing even vaguer problems later on. Lucky > >> for us, Ruby checks the number of arguments received against the > >> method definition -- finding many of these problems at the time > >> they're written. > > > > The checking doesn't happen until the method is called, though. > > You're right. That's an important distinction. > > >> Plus it would probably need a few helper methods just to remain > >> readable. But it would also prevent programmers from wasting huge > >> amounts of time hunting for why their browser rendered a bad select > >> box. The argument for adding validation is really strong for any > >> non-trivial project, but does it ruin Ruby's elegance? > >> > >> What do you think? Do you usually validate your arguments? > > > > It depends a bit on what you mean by validate. It's definitely good > > for methods to handle bad data gracefully, but sometimes just letting > > Ruby fail and raise an exception is more graceful than trying to > > figure out in a hands-on way what's going to go wrong and then raising > > the exception yourself. > > > > David > > I very much agree with you. I love when Ruby fails. The stack trace > and error message are all I need to get back on track after a snafu. > But what about when Ruby doesn't fail? I'm not talking about syntax > problems, but just general programmer stupidity, like when I > blatantly assign the wrong object to a temporary variable and then > send it off somewhere. That's the part I want to trap. Actually, I > want to trap it, strip it naked, and parade it up and down the street. > > # > # Example of Argument Validation > # > > require 'validate_arguments' > > def print_report(record) > > validate do > hash_role record, :keys => [:id, :status] > numeric_role record[:id], :values => [0..100] > symbol_role record[:status], :values => [:failed, :passed] > end > > puts <<-END > Report #{record[:id]} > Status: #{record[:status]} > ----- > END > end > > # The :id key should be a number, but that would make for a crappy > example. > print_report :id => [1,2], :status => :passed > > # Let's try sending it a different key than :id too. > print_report :number => 2, :status => :failed > > # > # Finish > # > > Without argument validation, it would print this. (Egads!) > > Report 12 > Status: passed > ------ > > Report > Status: failed > ------ > > But with the validate block in place, it fails: > > ArgumentError: Object should be a number-like object > from (irb):7:in `print_report' > from ./validate_arguments.rb:3:in `validate' > from (irb):5:in `print_report' > from (irb):18 > from :0 > > ArgumentError: Hash-like object is missing key :id > from (irb):6:in `print_report' > from ./validate_arguments.rb:3:in `validate' > from (irb):5:in `print_report' > from (irb):19 > from :0 > > That's better than a broken report, right? > > There's probably a better solution to this (like, drinking less > tequila.) But I feel pretty good about putting little > straightjackets on my variables. I think they feel loved. > > Kind regards, > > Michael Judge I think the first reply to your post hits the nail on the head: in the book Object Oriented Software Construction and its presentation of Design by Contract, the level of pre, post, and invariant condition checking really tends to be a matter of the reliability requirements your working with. And with Ruby there are many creative ways to accomplish this (DbC) but by and large they are still all "on your honor" techniques. The author (Meyer) also argues that one needs support intrinsic to the programming language to really get the full benefit of DbC but in my personal experience a LOT of benefit can be had even by on your honor techniques, like the some of the ones mentioned above. Ken