On 3 Sep 2009, at 23:47, Nick Green wrote:
> I see the idea, and it is tempting.  For code written for me to be  
> used
> by me it is in fact ideal.  However, I guess I have two follow up
> questions, both about failing gracefully:
>
> What is the "right" way to make sure the errors these functions report
> are nice to people who may use the functions/libraries I code?   
> "Foo.bar
> takes a Duck, not a Cow" would be a very helpful error message.   
> object
> of type Cow does not have method of type quack, is also not a bad  
> error
> message, but it would be nice to let the user know which type of  
> object
> in fact does have the method "quack" (presumably it would not always  
> be
> as obvious as "quack"==>"duck").  Or is the ruby way, since its an
> interpereted language, for a user of my library to crack open the ruby
> or rdoc/ri and look?

The Ruby way isn't to try and defend against behaviour which is out of  
your control. By publishing an API for your library you provide a  
contract and it is the responsibility of the programmer using your  
library to respect and conform to that contract. Whilst this can seem  
quite daunting if you come from a language such as Java, you'll find  
that it soon becomes a great liberator - not least because all objects  
that respond to a particular message can be used interchangeably.

Likewise exception handling allows you to define clean error recovery  
based on scope.

> What is the "right" way to make sure that, if my libraries or  
> functions
> are misused by someone (possibly me :p), the user of the script/ 
> program
> receives a non-programmer-targeted friendly error message like  
> "Whoops,
> we sent a Cow to do a Ducks job.  Feel free to report the bug to
> cows.and.ducks.sorting.co / notarealemail.com.  Make sure to include the
> following: <normal error dump>"?


In the general case there is no way to know the full set of objects  
which can respond to a given message at a given time: a duck may  
quack, but so for that matter might a duck hunter or a tape recorder.  
This holds in Ruby because the runtime behaviour of objects is mutable  
- methods might be added and removed at any time during program  
execution. This is why it's much more useful to rescue runtime  
exceptions and handle them elegantly than to worry about the class of  
an object.

So just relax and let duck typing happen, you'll find those tight  
controls your brain's learned with other languages really are  
irrelevant in Ruby.


Ellie

Eleanor McHugh
Games With Brains
http://slides.games-with-brains.net
----
raise ArgumentError unless @reality.responds_to? :reason