From: Sergey Volkov Date: 2006-05-11T16:17:41+09:00 Subject: Re: plz help with binding Ara, thanks for your kindness, but the whole idea was to make it simple, using same approach as with lambda, without need to create any instance variable; in fact I'd like to implement mix-in (Module) with method to be executed in class context as follows: class A include WithLocalsMixIn # ?or may be # class << self ; include WithLocalsMixIn ; end with_locals( :v1, :v2 ){ #??? initial bind for local vars :v1, :v2 # sample only, no any practical use define_method :get_vars { [v1,v2] } define_method :set_vars { |a,b| v1, v2 = a,b } } end It seems to me this is impossible in Ruby (or inappropriate?) Thanks, anyway, I got the trick in your solution: we have to create metaclass instance methods during instance initialization.. br-r-r.. I have to practice to start thinking this way :) And I still do not understand why def arr_fn creates binding, while def self.arr_meth does not. And why lambda does not work here: # class C def self.arr_meth( sym ) lambda{ arr = [] define_method sym.to_sym, lambda{ arr } }[] end arr_meth :arm end # my Lisp experience does help, Ruby is not functional enough and I'm missing Lisp macros :( --- Just received your second message with 'trickier way': now I'm wondering, why trickier way is required, when simple lexical closure works perfectly and, as I understand, it's available in Ruby. Is Ruby closure true closure? Or does instance context ruins it? Or I misunderstand it totally? I like Ruby very much, but so far I fail to understand very fundamental language features :( like this, for ex: # class StrWithPref < String ; def pref(n) self[0..n] end end p StrWithPref.new("ABCD").pref(2).class # prints StrWithPref, not String as I expected; well, as for now, I'm still leaning Ruby (and enjoy it a lot); thanks to all for great Ruby community, cheers Sergey ----- Original Message ----- From: To: "ruby-talk ML" Sent: Thursday, May 11, 2006 1:55 AM Subject: Re: plz help with binding > On Thu, 11 May 2006, Sergey Volkov wrote: > > >> Now I'm trying to create instance-var-less storage: >> # >> class C >> def self.arr_meth( sym ) >> arr = [] >> define_method sym.to_sym, lambda{ arr } >> end >> arr_meth :arm >> end >> ca = C.new; ca.arm << 10 >> cb = C.new; cb.arm << 20 >> p ca.arm #-> [10, 20] >> p cb.arm #-> [10, 20] >> p( ca.arm.eql?( cb.arm ) ) #-> true >> # >> Why ca.arm, cb.arm share same local variable? >> Is it bug or feature? > > because, in effect, this is what you've done > > class C > ARR = [] > def arm() lambda{ ARM } end > end > > there are a lot of ways to do this but you want something like: > > harp:~ > cat a.rb > class C > def self.arr_meth am = nil > @arr_meths ||= [] > @arr_meths << am.to_s if am > @arr_meths > end > arr_meth :arm > def initialize > klass = self.class > singleton_klass = class << self; self; end > klass.arr_meth.each do |m| > singleton_klass.module_eval do > arr = [] > define_method m, lambda{ arr } > end > end > end > end > > ca = C.new; ca.arm << 10 > cb = C.new; cb.arm << 20 > > p ca.arm #-> [10] > p cb.arm #-> [20] > p( ca.arm.eql?( cb.arm ) ) #-> false > > harp:~ > ruby a.rb > [10] > [20] > false > > neat idea btw. > > hth. > > -a > -- > be kind whenever possible... it is always possible. > - h.h. the 14th dali lama