

Magic Memcached - nleach
http://nleach.com/post/4664527538/magic-memcached

======
thwarted
Code samples and fixed width web sites don't mix, even if the code samples
have horizontal scroll bars, which everyone hates anyway. This nleach.com site
has a fixed width of 70em (which seems awfully low in general, and is measured
with the width of the non-fixed font in the outer container, so the effective
length of the fixed area is only 44 chars, at least on my system), and the
longest code line is 170 characters. If anything, the user should be able to
resize their browser window (rather than have to edit the CSS) to make it
wider to see the content.

(I also wish HN had a more dynamic width for fixed width content and/or had a
different way to specify fixed width font than just indentation, since people
also use indentation for bulleted lists, which makes them really hard to read,
especially on smaller screens).

~~~
nleach
You're absolutely right, it's a pretty awful layout for displaying code. I've
been meaning to fix it for a while, just haven't gotten around to it. Thanks
for stopping by though!

------
vog
This approach makes caching no longer invisible to the caller. Moreover, all
callers, rather than the class, have complete control over the cache
activation and expiration. Also, the caller needs to know which methods can
safely be cached at all.

So for the whole application, this approach will probably cause more brittle
code than caching "by hand", where caching was at least hidden behind well-
defined interfaces.

Nevertheless, I think that meta-class magic is the right way to abstract away
this caching code duplication. It just shouldn't change class interfaces.

For example, there could be a static attribute that contains the names of all
methods that should be cached. And there could be an additional method for
invalidating caches, probably with an array argument to facilitate
invalidation multiple method caches at once. And, of course, this cache
invalidation should mainly be used by the class itself, and ideally not be
available to the caller at all.

------
neilk
Perl has had this for 12 years or so, and Lisp way before that.

<http://perldoc.perl.org/Memoize.html>

I suggest you look into the design here. memoize() works on functions, which
is a lot more useful than catching missing methods. That way, the library
author can memoize functions, and so can the library user, if they are sure
the function they want is pure (i.e. no side effects).

I see problems with allowing callers to memoize methods of an object. You're
breaking encapsulation when the caller can suddenly decide how a method is to
be cached. In principle, every method of an object depends on the object's
private state, which could change at any time. So how are callers supposed to
know what is and isn't cacheable? Or when to expire a cache?

Also, the average object has methods for writing and reading. It would be
pretty silly to allow there to be cacheable writing methods. Again that
suggests control over what is cacheable should be in the class.

That said, you've got a good idea here -- just figure out how we can give the
class control over what is memoized. I am pretty sure this is doable; perhaps
you have a private method _get_memoized_methods() that tells the inherited
abstract class Memoizable what can be memoized. It can then make it appear as
if $object->fastQuery() exists, when it's just a wrapped around the private
method $object->slowQuery(). You can do this, I think, by catching missing
methods with a __call function in Memoizable, and, I think, you can throw
exactly the same exception as PHP would whenever a method that you don't want
to mess with is called.

