# Accessing Class Variables in mixed in define\_method

**URL:** <https://www.ruby-forum.com/t/accessing-class-variables-in-mixed-in-define-method/190383>\
**Category:** Ruby\
**Created:** [June 18, 2010, 10:08pm UTC](https://www.ruby-forum.com/t/accessing-class-variables-in-mixed-in-define-method/190383 "2010-06-18T22:08:43Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![jamiequint](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/22d042/32.png) [@jamiequint](https://www.ruby-forum.com/u/jamiequint)\
**Post date:** [June 18, 2010, 10:08pm UTC](https://www.ruby-forum.com/t/accessing-class-variables-in-mixed-in-define-method/190383/1 "2010-06-18T22:08:43Z")

</div>

I am using define\_method inside a module to dynamically create a class  
after the module is mixed in. The module is writing out class variables  
for the class it is mixed into (yes I am aware that class variables are  
generally frowned upon but they are necessary in this instance) and then  
subsequently trying to access them through the method being created with  
define\_method.

The problem here is that define method is not able to access the class  
variables through class\_variable\_get or through accessing them directly.  
In the first case it fails because ‘class\_variable\_get’ is not a method  
on the class (oMethodError: undefined method â€˜class\_variable\_getâ€™ for  
#Foo:0x100124638) In the second instance it fails because it thinks  
the class variable is uninitialized (NameError: uninitialized class  
variable @@c in M)

It seems to be evaluating the ‘@@c’ call in the context of the module  
and the class\_variable\_get call in the context of the class in which  
define\_method is being called after it is mixed in. Does anyone know how  
I can get at the class variable here in define\_method? Sample code  
below:

Best,  
Jamie

module M  
def cv(methodname)  
if class\_variable\_defined?(:@@c)  
classvar = class\_variable\_get(:@@c)  
classvar[rand(10000)] = “random”  
class\_variable\_set(:@cc,classvar)  
else  
class\_variable\_set(:@@c,{})  
end  
define\_method(methodname.to\_sym) do  
# need to be able to get class variables for this class  
# @@c does not work because it tries to get the variable for the  
module and it exists only in the class  
#class\_variable\_get(:@@c) #does not work because its an invalid  
class method  
#@cc and class\_variable\_get(:@@c) are getting evaluated in  
different contexts which is strange  
end  
end  
end

class Foo  
extend M  
cv(“mfoo”)  
end

f = Foo.new  
f.mfoo # want this to be able to access and operate on class variables

---

<div class="post-metadata">

**Author:** ![jamiequint](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/22d042/32.png) [@jamiequint](https://www.ruby-forum.com/u/jamiequint)\
**Post date:** [June 21, 2010, 10:01am UTC](https://www.ruby-forum.com/t/accessing-class-variables-in-mixed-in-define-method/190383/2 "2010-06-21T10:01:44Z")

</div>

On Fri, Jun 18, 2010 at 10:08 PM, Jamie Q. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
wrote:

> on the class (oMethodError: undefined method ‘class\_variable\_get’ for  
> Best,  
> Jamie
> 
> module M  
> def cv(methodname)  
> if class\_variable\_defined?(:@@c)  
> classvar = class\_variable\_get(:@@c)  
> classvar[rand(10000)] = “random”  
> class\_variable\_set(:@cc,classvar)

There’s a typo here: it should be :@@c

This “works” for me:

module M  
def cv(methodname)  
if class\_variable\_defined?(:@@c)  
classvar = class\_variable\_get(:@@c)  
classvar[rand(10000)] = “random”  
class\_variable\_set(:@@c,classvar)  
else  
class\_variable\_set(:@@c,{})  
end  
define\_method(methodname.to\_sym) do  
self.class.send(:class\_variable\_get,:@@c)  
end  
end  
end

class Foo  
extend M  
cv(“mfoo”)  
end

I say “works” because the first time, @@c is initialized to {} but no  
value is set. You need to call cv again inside class Foo in order to  
create a value in the hash:

irb(main):021:0\* f = Foo.new  
=\> #Foo:0xb74aeb30  
irb(main):022:0\> f.mfoo  
=\> {}

if you call it again:

irb(main):024:0\> class Foo  
irb(main):025:1\> cv(“mfoo”)  
irb(main):026:1\> end  
=\> #Proc:0xb74bb8d0@:10(irb)  
irb(main):027:0\> f.mfoo  
=\> {9035=\>“random”}

Then it creates an entry in the hash, and then accessing it through  
mfoo retrieves it.

Hope this helps,

Jesus.
