From: Robert Klemme Date: 2010-08-24T00:37:54+09:00 Subject: Re: Your thoughts on #memo ? 2010/8/23 Intransition : > Like to get some thoughts on the following technique for memoization: > >  # Memoize a method. >  # >  #   class MemoExample >  #     attr_accessor :a >  #     def m >  #       memo{ @a } >  #     end >  #   end >  # >  #   ex = MemoExample.new >  # >  #   ex.a = 10 >  #   ex.m  #=> 10 >  # >  #   ex.a = 20 >  #   ex.m  #=> 10 >  # >  def memo(&block) >    key = eval('__method__', block) >    val = block.call >    singleton_class = (class << self; self; end) >    singleton_class.__send__(:define_method, key){ val } >    val >  end I could not get that to work on 1.9.1: 17:33:49 ~$ irb19 Ruby version 1.9.1 irb(main):001:0> def memo(&block) key = eval('__method__', block) val = block.call singleton_class = (class << self; self; end) singleton_class.__send__(:define_method, key){ vairb(main):002:1> l } key = eval('__method__', block) irb(main):003:1> val = block.call irb(main):004:1> singleton_class = (class << self; self; end) irb(main):005:1> singleton_class.__send__(:define_method, key){ val } irb(main):006:1> val irb(main):007:1> end => nil irb(main):008:0> class ME irb(main):009:1> attr_accessor :a irb(main):010:1> def m;memo { @a }; end irb(main):011:1> end => nil irb(main):012:0> ex=ME.new => # irb(main):013:0> ex.a=10 => 10 irb(main):014:0> ex.m TypeError: wrong argument type Proc (expected Binding) from (irb):2:in `eval' from (irb):2:in `memo' from (irb):10:in `m' from (irb):14 from /opt/bin/irb19:12:in `
' irb(main):015:0> Also I believe the results would not be like your comments suggest since you redefine the method all the time. Am I missing something? > Downside / upsides to the approach? Any suggestions for improvement? > Or is this just an altogether bad idea? I do not see the advantage over plain definition of def ex.m; 10; end since you are storing a single value anyway. It seems your approach is only advantageous if you need to access instance variables because then it spares some ugly syntax. But since you have to call #memo explicitly you can even pass the value to bind to the method as well, e.g. def memo(name, val) (class << self; self; end).define_method(name){ val } end ex.memo :a, 10 As long as you have to invoke the method setting the value explicitly you do not gain anything, do you? Somehow I must be missing something but I can't see it right now. Kind regards robert -- remember.guy do |as, often| as.you_can - without end http://blog.rubybestpractices.com/