<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
  <meta content="text/html;charset=ISO-8859-1" http-equiv="Content-Type">
</head>
<body bgcolor="#ffffff" text="#000000">
<br>
<blockquote
 cite="mid765a2c230702192014j7a365acfg3563a61301413815@mail.gmail.com"
 type="cite">
  <pre wrap="">(not to mention I don't understand the need for #with to mangle it's args as it does).</pre>
</blockquote>
Ah, now you're asking.&nbsp; <br>
<br>
<tt>#with</tt> needs to cope with a number of different types of
arguments.&nbsp; It could do this by using a case statement or just if/else&nbsp;
If there were only two options which could be passed in, that might
have been the best way to do it.&nbsp; But actually, the interface for #with
is really quite complex, taking different types of arguments that need
different treatment.&nbsp; However, although the arguments are different,
the things that need to be done to/with them are the same. <br>
<br>
Since, we're using an object oriented language, it's considered good
practice to implement this form of polymorphism<sup>[1]</sup> by
delegation - we leave the details of implementation to someone else!&nbsp;&nbsp;&nbsp;
Essentially, we're defining an API and implementing a different class (<tt>LiteralArgConstraint,</tt>
<tt>NumericArgConstraint,</tt> <tt>RegexArgConstraint</tt>, etc) for
each possibility (a.k.a. duck-typing<sup>[2]</sup>)<i> </i>.&nbsp; <br>
<br>
This simplifies the handling code immensely - all it does is iterate
over the arguments and ask the correct constraint handler to do the
right thing.&nbsp; Regretably the way it does this iteration has the
unfortunate side effect we are seeing.&nbsp; This would probably happen even
if David hadn't chosen to 'mangle the args' as he does.&nbsp; It's a
side-effect of <tt>Hash#each</tt>.<br>
<br>
Polymorphic delegation also makes the code more scalable (we only have
to implement a new constraint handler when someone comes up with a
super new idea (e.g. <tt>DuckTypeArgConstraint</tt>); and easier to
maintain (code is localised and hopefully it's easier to find and fix
bugs).&nbsp; There is an argument that the extra layer introduced adds
complexity, but IMHO once you understand the paradigm, its
interpretation is obvious and the tradeoffs are appropriate.&nbsp; Spaghetti
code is a nightmare to maintain!<br>
<br>
Rgds,<br>
&nbsp; Jerry<br>
<br>
[1] Polymorphic - having more than one form.&nbsp; So polymorphism in a
method is the ability to deal with arguments of different types.&nbsp;
Polymorphism in a class (well, classes) is the ability of different
classes to respond to the same method call, to do what is expected of
them each in their own distinctly different way.&nbsp; This is the posh term
for what every Ruby programmer instinctively knows because they see it
every time they use Enumerable#each on Hash, Array, or String for
example.<br>
<br>
[2] The term is a reference to the <u>duck test </u>&#8212; "If it walks
like a duck and quacks like a duck, it must be a duck".&nbsp; <br>
<br>
Check out Wikipedia on the subjects of polymorphism and duck-typing,
though the articles are a bit too academic for my taste - and I'm a
teacher!<br>
<br>
If you wanted to, you might submit a HashArgConstraint class as a
possible patch to <tt>lib/specs/mocks/argument_epectation.rb</tt>.&nbsp;
This would 'know' that it would receive an array of arrays and adjust
its expectation accordingly.&nbsp; Or have I just slipped into teaching mode
again?&nbsp; Sorry.<br>
</body>
</html>