Calling a descendant's method

Hello,

is it possible in Ruby to make a method of a class calling another
method to always call the version of that method from the descendant?
I do not know how to put this more clear, so here is an example:

  class A
    def f
      g # what to put here?
    end

    def g
      "Haha"
    end
  end

  class B < A
    def g
      "Hoho"
    end
  end

  B.new.f # i want this to return "Hoho", but it will return "Haha"

Thanks.

Alexey

···

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

This returns "HoHo" for me.

···

On Thu, Aug 25, 2011 at 12:48 PM, Alexey Muranov < muranov@math.univ-toulouse.fr> wrote:

Hello,

is it possible in Ruby to make a method of a class calling another
method to always call the version of that method from the descendant?
I do not know how to put this more clear, so here is an example:

class A
   def f
     g # what to put here?
   end

   def g
     "Haha"
   end
end

class B < A
   def g
     "Hoho"
   end
end

B.new.f # i want this to return "Hoho", but it will return "Haha"

Thanks.

Alexey

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

No it returns "Hoho"!
Now i am confused...

···

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

In fact, i've got a problem in Rails with an abstract class

  class AbstractSmartModel < ActiveRecord::Base
    self.abstract_class = true
    ...
  end

I've got an error "Could not find table 'abstract_smarter_models' ".
I thought that one of descendants called a method of AbstractSmartModel
which called another method that only a non-abstract class could have,
but apparently i was wrong.
I'll try to debug this, sorry for bad question.

···

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

I think i've found an explanation: in fact i used a lambda and called a
class method in the body of the lambda, so probably `self` was bound to
the current self (the abstract class).
Sorry again for the bad question.

···

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

Just for the record, my problem was discussed on StackOverflow here:

···

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

@7stud thanks for a good example.
(The is a typo: the output is 1015.)

I was confused whether `self` was a method or a keyword, or a local
variable.
So, apparently it behaves like a local variable.

Also the difference between bounding to a variable and (not) to the
variable's value is tricky.

And i see that there is an essential difference between lambdas and
methods defined with `def`, as lambdas are bound to the current scope,
and methods are not.
This makes sense as lambdas are objects, and methods are called on
objects.

Thanks,

Alexey.

···

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

Alexey Muranov wrote in post #1018528:

No it returns "Hoho"!
Now i am confused...

ruby moves up the inheritance hierarchy until it finds f():

   def f
      g()
    end

f() executes and inside f() ruby finds the statement:

    g()

ruby must call all methods with an object, and if you don't specify the
object that is calling the method, then ruby uses self. So g() is
equivalent to:

   self.g()

What is self? self is the object that called the method. What object
called the method? An instance of B called f(), so inside f() self='the
B instance'. That means self.g is equivalent to:

  'the b instance'.g()

So ruby checks the B class for a method called g().

···

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

Alexey Muranov wrote in post #1018529:

In fact, i've got a problem in Rails with an abstract class

  class AbstractSmartModel < ActiveRecord::Base
    self.abstract_class = true
    ...
  end

Inside a class, but outside any method definitions, self equals the
class. So the line:

  self.abstract_class = true

is equivalent to:

  AbstractSmartModel.abstract_class = true

I've got an error "Could not find table 'abstract_smarter_models' ".

I don't know what that indicates.

···

I thought that one of the descendants called a method of
AbstractSmartModel
which called another method that only a non-abstract class could have,
but apparently i was wrong.
I'll try to debug this, sorry for bad question.

UPDATE: the error is raised by a call to
columns_hash inside of a class method of the abstract class.
Do not understand.

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

Alexey Muranov wrote in post #1018534:

I think i've found an explanation: in fact i used a lambda and called a
class method in the body of the lambda, so probably `self` was bound to
the current self (the abstract class).
Sorry again for the bad question.

class Dog
  def self.get_val
    10
  end

  def self.do_stuff
    #self = Dog

    x = 5
    my_lambda = lambda { get_val() + x} #self.get_val()

    x += 1000
    return my_lambda
  end

end

class Cat
  def self.get_val
    0
  end

  def self.execute_lambda(callable)
    #self = Cat

    x = 0
    puts callable.call #{get_val() + x}.call()
  end
end

a_lambda = Dog.do_stuff
Cat.execute_lambda(a_lambda)

--output:--
115

···

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