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 methodTiger#update
as they are not relevant to the question. - I've removed
self.
fromself.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, asAnimal.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:
When you call
RoadBike.new
runtime checks if there is aninitialize
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 stillRoadBike
instance)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. DoesRoadBike
have its own implementation ofdefault_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
Dynamically Set Local Variables in Ruby
Change the Binding of a Proc in Ruby
How to Debug in Rubymine 4.5 Using Ruby 1.9.3
Using Ruby Convert Numbers to Words
Missing Symbol When Installing Ruby-2.3.0 on Os X 10.11.6 by Rvm
What's the Point of Unary Plus Operator in Ruby
Ruby SQLite3 Installation SQLite3_Libversion_Number() MACos Sierra
Typing 'Rails Console' Doesn't Start
Irb History Not Working with Ruby 2.3.0
Mocha Mock Carries to Another Test
3 Equals or Case Equality Operator
Nokogiri Was Built Against Libxml Version 2.7.7, But Has Dynamically Loaded 2.7.3
Google Maps, Ruby on Rails, Zoom Level with One Marker
How to Dynamically Create a Local Variable in Ruby
Store the Day of the Week and Time
What Does the "$" Character Mean in Ruby
Redefining a Single Ruby Method on a Single Instance with a Lambda