2010/8/23 Intransition <transfire / gmail.com>:
> 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
> 
>  ¨Βεζ νεν都βμογλ©
>  ¨Βεω εφα쨧ίίνετθοδίί§¬ βμογλ©
>  ¨Βαμ βμογλ®γαμμ
>  ¨Βιξημετοξίγμασσ ¨γμασσ ΌΌ σεμζσεμζεξδ©
>  ¨Βιξημετοξίγμασσ®ίίσεξδίί¨Ίδεζιξείνετθοδλεω©φα>  ¨Βαμ
>  ¨Βξδ

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
=> #<ME:0x10049a74>
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 `<main>'
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/