Sergey Volkov schrieb:
> 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?

Sergey, your code creates the local variable "arr" and the corresponding 
lexical closure once for the class "C", so all instances of "C" share 
the local variable. If you want to have a local variable per instance 
without using instance variables, you have to define a closure per instance:

  1  class C
  2    def self.arr_meth( sym )
  3      define_method sym.to_sym, lambda{
  4        arr = []
  5        class << self; self; end.instance_eval {
  6          define_method sym.to_sym, lambda{ arr }
  7        }
  8        arr
  9      }
10    end
11    arr_meth :arm
12  end

When you call "arr_meth" in line 11, the instance method is defined for 
class "C", containing the code in lines 4..8. As in your original 
implementation, this code is shared for all instances of "C".

Now, when you call this method for an instance for the first time, the 
local variable is created in line 4. Lines 5..7 create the lexical 
closure for this instance only by defining the method in the singleton 
class of this instance.

Line 5 gets the singleton class of "self", returns it, and calls 
"instance_eval" on it, which finally calls "define_method" in line 6. 
You can't call "define_method" directly on the singleton class, because 
it's a private method.

Regards,
Pit