Calling Another Method in Super Class in Ruby

Calling method in parent class from subclass methods in Ruby

If the method is the same name, i.e. you're overriding a method you can simply use super. Otherwise you can use an alias_method or a binding.

class Parent
def method
end
end

class Child < Parent
alias_method :parent_method, :method
def method
super
end

def other_method
parent_method
#OR
Parent.instance_method(:method).bind(self).call
end
end

calling another method in super class in ruby

class B < A

alias :super_a :a

def a
b()
end
def b
super_a()
end
end

How do I call a super class method

In Ruby 2.2, you can use Method#super_method now

For example:

class B < A
def foo
super + " world"
end

def bar
method(:foo).super_method.call
end
end

Ref: https://bugs.ruby-lang.org/issues/9781#change-48164 and https://www.ruby-forum.com/topic/5356938

Ruby - Calling another Class method in super class

Only solution here is to use B.a.

class B < A
def self.b
a #=> self: B; superclass: A
end
end

Call subclass method from superclass - Design Pattern

Try this:

class Animals
def self.update
puts "self = #{self} in Animals::update"
if whatever == "Happy Days"
puts "The Fonz rules"
end
end
end

class Tiger < Animals
def self.whatever
"Happy Days"
end
end

Tiger.update
# self = Tiger in Animals::update
# The Fonz rules

Before discussing this, a few notes:

  • I've removed the module Zoo and the instance method Tiger#update as they are not relevant to the question.
  • I've removed self. from self.whatever, as it is not needed (self is assumed if there is no explicit receiver).
  • I've defined the class methods in the more conventional way (but there is nothing wrong with the way the OP defines them).
  • update is only to be invoked from subclasses, as Animal.update would raise a "there's no method or local variable 'whatever'" exception.

The important point here is that Tiger.update invokes the method Animal::update, just as though update had been defined in Tiger, rather than having been inherited from Animal. That's why:

Tiger.methods.include?(:update) #=> true

Therefore, "call a class method of a child class from a parent class" is not correct; Tiger::whatever is being called from the child class. Nothing is being called from the parent class because self never equals Animals when Tiger::update is invoked. This is not just semantics.

Calling super, super class method with parameters in Ruby

You can pass parameters directly to call like this:

class Child < Parent
def fun(word)
GrandParent.instance_method(:fun).bind(self).call(param1, param2)
end
end

Calling super from a class method

Super works for child classes inherited from a parent class.

In your case alias is the only way. Or you can use alias_method:

alias_method :old_hi, :hi

def self.hi
old_hi
puts "Oh!"
end

Ruby: Calling a method from another method that needs an attribute

Normally in object oriented design you encapsulate the data and methods that act on the data in an object. In Ruby you create properties of an object by using instance variables:

class CLI
def initialize(array = [])
@array = []
end

def method_2
method_1
end

def method_1
puts @array
end
end

cli = CLI.new(["Hello", "World"])
cli.method2

Instance variables use the sigil @. They are considered private since they are scoped to the instance even if Ruby does not use the private keyword for instance variables.

Classes can also have instance variables:

class CLI
@array = ["Hello", "World"]

def self.hello
puts @array.join(" ")
end

def you_cant_access_it_from_an_instance
@array
end
end

CLI.hello # Hello World
CLI.new.you_cant_access_it_from_an_instance # nil

This is an "class" instance variable which belongs to the class itself - its not shared with subclasses. This works since in Ruby classes are objects - instances of the Class class.

Ruby also has class variables which are shared between a class and all its decendents:

class Foo

@@array = ["Hello", "World"]

def self.hello
puts @@array.join(" ")
end

def self.array=(val)
@@array = val
end
end

class Bar < Foo; end
Bar.array = ['Oh', 'noes']
Foo.hello # Oh noes

They have serious issues with thread safety and are best avoided due to the unexpected behavior.

A common pattern for what I belive you are doing is a factory method that creates a new instance with its input and then calls its call method:

class CLI
def initialize(*args)
@args = args
end

def call
puts @args.inspect
# do something awesome
end

# factory method thats basically just a convenience
def self.call(*args)
new(args).call
end
end

CLI.call(*ARGV) # passes the command line arguments

Calling base class method from overloaded method in sub-class

Have you tried calling the base class's "authorize" method with just "super" instead of "super.authorize"?

Can I call a subclass' private method from its parent class?

You're getting it wrong - in your example, there is no such a thing as the parent class calling children methods.

Methods/constants name lookup in Ruby always works "bottom up": first we check if the method is defined in object's class, then in object's class's superclass and so on (this is a huge simplification because Ruby's object model is more complicated, more on this later). So, in your example things happen in roughly the following order:

  1. When you call RoadBike.new runtime checks if there is an initialize methods defined for the class RoadBike. There is no, so we use the implementation defined for its parent class - Bycicle (but the execution context stays the same - it is still RoadBike instance)

  2. When executing Bycicle#initialize runtime encounters another method call - default_chain. At this moment we start method name resolving in the very same manner - starting from the RoadBike context. Does RoadBike have its own implementation of default_chain? Yes, it does, so we simply call it.

The following baby example makes it crystal clear, hopefully:

class Parent
def initialize
puts "Parent Initializer is called"
a
b
end

def a
puts "Parent a is called"
end

def b
puts "Parent b is called"
end
end

class Child < Parent
def b
puts "Child b is called"
end
end

pry(main)> Child.new
Parent Initializer is called
Parent a is called
Child b is called

In reality the methods/constants resolution machinery is more complicated(includes so-called singleton classes). This is a bigger topic that will not fit nicely in SO answer, so I strongly recommend reading "Metaprogramming Ruby 2" by Paolo Perotta where this model is wery well explained in great details from the very practical point of view.



Related Topics



Leave a reply



Submit