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.