Hacker Newsnew | past | comments | ask | show | jobs | submitlogin

I want to be able to write:

  cache(key_name, :ttl => 30.seconds, :dependent => ModelClass) do 
     model.expensive_operation
  end
and have that cache expire whenever any instance of ModelClass is updated.

With macros, every call to cache() can be expanded into:

  ModelClass.register_expiration_callback(keyname)
  do_cache(...)
Without macros, there's no way to catch deeply nested cache calls. I fake this by scanning the source for calls to cache() on startup right now.


I'm not following. Why does "ModelClass.register_expiration_callback(keyname)" have to be in a macro expansion, rather than just the first statement of the cache() method? It doesn't appear to use local scope at all. Can you flesh out the example a bit more?

FWIW, I believe that Ruby or (especially) Smalltalk-style syntax for method calls and closures covers such a large set of the things macros are used for that their complexity cost (esp when building tools) outweighs their benefit.


Sorry, re-reading that it wasn't totally clear. The ModelClass.register_expiration_callback(keyname) has to be run at parse time, because there's no guarantee that the cache statement will ever be executed before a ModelClass instance is updated. You can't run things at parse time in Ruby (without exotic extensions); that's the whole point of macros.

I completely agree that there are a large number of uses for macros that "SmallTalk style" syntax completely replace. It turns out that a lot of things don't really require you to run code at parse time. Take anaphoric-if for example, which is classically implemented as a macro; all you really need is the ability to manipulate the local variables of a closure from the outside. Parse-time execution is not required.




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: