Make :memoize more spec-able?

Hi there,
so I ported Memoizable into my app,
but I need a way to spec that certain methods have been memoized.

Is it a bad idea to add a :memoized_methods attribute to any memoized
class / object
so;

  class Abberation
    memoize :some_method
  end

will allow me to spec;

  Abberation.memoized_methods.should include(:some_method)

I'd prefer this rather than spec-ing

Abberation.instance_methods.should include("_unmemoized_some_method")

(I still don't get why it's not just an
"alias_method_chain :some_method, :memoization")

MrJ

class Abberation
   memoize :some_method
end

will allow me to spec;

Abberation.memoized_methods.should include(:some_method)

I'd prefer this rather than spec-ing

Abberation.instance_methods.should include("_unmemoized_some_method")

(I still don't get why it's not just an
"alias_method_chain :some_method, :memoization")

Isn't that testing the *implementation* rather than the intended
effect? I think it'd be better to test the memoization by ensuring
the method doesn't calculate the value twice, rather than asserting
(shoulding?) the thing is memoized?

Well,
I'd suggest the opposite.

the :memoize functionality is extensively tested in ActiveSupport
more extensively than I'm going to remember to do each time I test its
use in my app.

so if I can do a basic "consequences of being memoized" test, and also
say "as far as rails is concerned, this is memoized"
then I get primary confidence that it works,
i also get secondary confidence that its "memoized", and Rails has
promised me that "memoized" works.

  def something(n)
     return randomly(n)
  end
  memoize :something

  test "something is declared as memoized" do
    assert my_model.memoized_methods.include?(:something)
  end

  test "something is memoized" do
     my_model.stubs(:randomly).returns(1,2,3)
     assert_equal 1, my_model.something(7)
     assert_equal 1, my_model.something(7)
     assert_equal 2, my_model.something(100)
  end

  I can grab those edge cases into my tests without having to think
about them.

the :memoize functionality is extensively tested in ActiveSupport
more extensively than I'm going to remember to do each time I test its
use in my app.

OK, you've convinced me. Send a patch and I'll look it over . I
still think that you should include the implementation test, but I can
see where you're coming from and piggy backing on the AS tests is a
good idea.

If you have no confidence that "memoize :foo" does its job. How can
you have confidence in Foo.memoized_methods? For all you know its
lying to you as well.

If you think you need these silly DSL assertion tests, just grep your
source for extra "confidence".

File.open("foo.rb").read.grep(/memoize :foo/)

memoization *is* an implementation detail. The helper should not be
treated any different than

def foo
  @foo ||= 1 + 1
end

If you have no confidence that "memoize :foo" does its job. How can
you have confidence in Foo.memoized_methods?

Umm... I do have confidence in "memoize :foo" doing its job, Josh.
Which is precisely what I'm saying.

Grep-ing through source is plainly a crap way.
Having "memoize :foo" store the fact that :foo is :memoized will;
a) allow me to spec against it
b) stop the "unmemoize_all" code having to grep through
instance_methods

memoization *is* an implementation detail. The helper should not be
treated any different than

def foo
@foo ||= 1 + 1
end

Indeed,
except you get extra stuff in there for free, like reloading,
and it claims to take care of arguments.
(although I worry that any function like do_something(true) will
instead just unmemoize itself)

Will get my laptop out,
see what I can do to make a patch.

Have a good bank holiday (if you're in the UK WHOOP WHOOP)
:slight_smile:

http://rails.lighthouseapp.com/projects/8994-ruby-on-rails/tickets/897-patch-memoized-methods-are-stored-in-klass-memoized_methods

Grep-ing through source is plainly a crap way.

j/k :wink:

Having "memoize :foo" store the fact that :foo is :memoized will;
a) allow me to spec against it
b) stop the "unmemoize_all" code having to grep through
instance_methods

How does it stop unmemoize_all from looking for __memoized methods?
You've just delegated the responsibility.

> memoization *is* an implementation detail. The helper should not be
> treated any different than

> def foo
> @foo ||= 1 + 1
> end

Indeed,
except you get extra stuff in there for free, like reloading,
and it claims to take care of arguments.
(although I worry that any function like do_something(true) will
instead just unmemoize itself)

So how would you test this simple memoized method? However you answer,
that is how you should test it will the memoize helper.