On Aug 3, 4:53 pm, Keith Rarick <k... / essembly.com> wrote: > I've been using ruby for about 8 months now and I've come to appreciate > its powerful features. But I misspython'sdecorators, so I made > something similar. > > The code is attached; here are some examples. It's really easy to use a > decorator: > > class C > memoized > def tak(x, y, z) > return z if x <= y > tak(tak(x - 1, y, z), tak(y - 1, z, x), tak(z - 1, x, y)) > end > end > > And really easy to write one: > > class Module > decorator > def memoized(name, f) > lambda do |*args| > ((@__memo_cache ||= {})[[name, args]] ||= > [f.bind(self).call(*args)])[0] > end > end > end > > You can use this to do all of the usual decorator things, like > memoization, method call tracing, synchronization, currying, type > checking, basic profiling, print warnings for deprecated methods, or > anything else you can think of. > > One important limitation of this implementation is that you cannot > "stack" decorators like you can inpython. That's fixable, and hopefully > I'll have time to make another version of this library with stackable > decorators. But until then, maybe someone will find this useful. > > I'd love to hear feedback about this library! If you have any comments > or questions, please let me know. > > kr > > Attachments:http://www.ruby-forum.com/attachment/52/deco.rb This is quite interesting. I'm not sure how I feel about the use of declarative style. I'm not a big fan of public, private, protected to begin with b/c of this. It also complicates the code dealing with method_added and wrapping methods... I wonder how robust it is. (This is another good example of where some built in AOP functionality could improve things.) Though it's a bit less convenient, it might be better to just name the method: class C def tak(x, y, z) return z if x <= y tak(tak(x - 1, y, z), tak(y - 1, z, x), tak(z - 1, x, y)) end memoized :tak end Unfortunately, not as nice, but the underlying code would certainly get simplified. Dreaming a little. I wonder, if there were a callback for when a class/ module closes, then maybe you do do it lazily? Also, I wonder if this corresponds to Matz' idea of ":"-notation he used for pre and post. So, class C def tak:memoized(x, y, z) return z if x <= y tak(tak(x - 1, y, z), tak(y - 1, z, x), tak(z - 1, x, y)) end end Of course we could always do: class C def_memoized :tak do |x, y, z| return z if x <= y tak(tak(x - 1, y, z), tak(y - 1, z, x), tak(z - 1, x, y)) end end Though the lack of block support and closed scope make that not quite the same. Oh, one last thing. Could you give some other examples? Memoization perhaps isn't the best, since most times it is as easy as: class C def initialize @_tak = {} end def tak(x,y,z) @_tak[x,y,z]] ||= ( return z if x <= y tak(tak(x - 1, y, z), tak(y - 1, z, x), tak(z - 1, x, y)) ) end end T.