On Oct 17, 2008, at 11:42 AM, Stephen E. wrote:
So… Wait. Is the implication here that Ruby is too static? Or
just the way people are using Ruby, including RSpec?
Depends on what you want to do. Honestly, I find it much easier to
manipulate methods in javascript rather then ruby.
Here’s the essential complexity of a stub framework:
- Store the original method definition (if there is one).
- Replace the method definition with a new method, this time
returning nil/undefined, or a set value.
after(:each) =>
- Restore the original method definition
- Cleanup any mess you’ve made
In Ruby, the first two steps ends up more or less like this:
(class << my_obj; self; end).instance_eval <<-HERE
alias_method :my_#{original_method}, #{my_method}
def #{my_method}
#{my_return_value}
end
HERE
In Javascript, it might look more or less like this:
var old_method = obj[my_method];
my_obj[my_method] = my_return_value;
The point is not that ruby is more static, but that it’s just a lot
more typing and metaprogramming hoops that you’ll need to jump
through. Also - notice that javascript, a prototype based language,
you can deal with the metaclass/singleton class seamlessly (since
there is no class). In Ruby you’ll want to be safe and not redefine
the method for the whole class (i.e., all instances of the class), but
only for the particular object you’re stubbing.
As for the mocking part, this too seems to be an issue of language. I
suppose it would depend on how sophisticated you want to get. Here’s
what appears to be essential for a mock:
- the ability to stub methods on it
- An “empty” object - one with no predefined methods.
- complaining when a method is called on it which hasn’t explicitly
been defined.
#2 seems to be a shoe-in for Javascript - since a regular old object
is an “empty” object. In Ruby, you’ll need something more or less
like BlankSlate, which undef’s all it’s methods. As for #3, I’m
pretty sure that Ruby’s method_missing allows one to raise an
exception easily. Not sure what a Javascript mocking framework would
do in this case.
Scott