On 10/25/2010 05:19 PM, Leslie Viljoen wrote:
> The @@variables are shared among subclasses, not superclasses. So you
> could define the variable in the superclass:
>
> class TestSuperClass
>  @@testmethod = 1


Yes but if i have 2 subclasses with 2 methods in each then i will need
to define 4 variables in the superclass.

@@method0 = @@method1 = @@method2 = @@method3 = 1

And every time i want to add a method in a subclass i will need to go to
the superclass code and add another one. That's the sort of duplication
i would like to avoid.


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


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


If you put something in initialize then when you change the code and
reload it in a running program (or running irb) you need to recreate all
existing objects. With class variables there is no need to.


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


I know it's nothing useful but this is how i learn. I want to make an
alternative to the def keyword. For example, i want to have a way of
defining methods which take arguments in reverse.

defbackward(:mymethod) do |x,y,z|
  [x,y,z]
end
irb(main):004:0> mymethod(1,2,3)
=> [3, 2, 1]

I thought i would use method_missing and this leads to the problem i
showed in the first post.


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


Right, this explains a lot. I ended up with:

class TestSuperClass
  def self.testdefhash
    @testdefhash
  end
  def self.testdef(name, &block)
    (@testdefhash ||= {})[name] = block
  end
  def method_missing(name, *args)
    self.class.testdefhash[name].call(*args)
  end
end
class TestSubClassA < TestSuperClass
  testdef(:testmethod) { puts "inside testmethod a" }
  testdef(:anothermethod) { puts "inside anothermethod a" }
end
class TestSubClassB < TestSuperClass
  testdef(:testmethod) { puts "inside testmethod b" }
  testdef(:anothermethod) { puts "inside anothermethod b" }
end

irb(main):002:0> TestSubClassA.new.testmethod
inside testmethod a
irb(main):003:0> TestSubClassB.new.anothermethod
inside anothermethod b

So far it works. Thanks for help.

-- 
Posted via http://www.ruby-forum.com/.