On Mon, Oct 25, 2010 at 3:58 PM, John Doe <bl4.929b / playker.info> wrote:
> Hi,
>
> Suppose i wrote something like this:
>
> class TestClass
> =A0@@testmethod =3D lambda { puts "inside testmethod" }
> =A0def method_missing(name, *args)
> =A0 =A0eval("@@#{name}").call(*args)
> =A0end
> end
>
> irb(main):002:0> TestClass.new.testmethod
> inside testmethod
>
> It works fine but if I have more classes i don't want to duplicate the
> same method_missing. I thought i could write this:
>
> class TestSuperClass
> =A0def method_missing(name, *args)
> =A0 =A0eval("@@#{name}").call(*args)
> =A0end
> end
> class TestSubClass < TestSuperClass
> =A0@@testmethod =3D lambda { puts "inside testmethod" }
> end
>
> but then i get this error:
>
> irb(main):003:0> TestSubClass.new.testmethod
> NameError: (eval):1:in `method_missing': uninitialized class variable
> @@testmethod in TestSuperClass
>
> Is there any way to get it to work?


The @@variables are shared among subclasses, not superclasses. So you
could define the variable in the superclass:

class TestSuperClass
 @@testmethod =3D 1
 def method_missing(name, *args)
   eval("@@#{name}").call(*args)
 end
end

class TestSubClass < TestSuperClass
@@testmethod =3D lambda { puts "inside testmethod" }
end

TestSubClass.new.testmethod


-----
or, you could use an instance variable, since I'm not sure class
variables are really useful in Ruby:
-----

class TestSuperClass
 def method_missing(name, *args)
   eval("@#{name}").call(*args)
 end
end

class TestSubClass < TestSuperClass
def initialize
@testmethod =3D lambda { puts "inside testmethod" }
end
end

TestSubClass.new.testmethod


-----
... but more importantly, why do you want to do this? There's likely
to be a better way.


More info on inheritance and class variables:
http://stackoverflow.com/questions/1251352/ruby-inherit-code-that-works-wit=
h-class-variables