Test whether a Ruby class is a subclass of another class
Just use the <
operator
B < A # => true
A < A # => false
or use the <=
operator
B <= A # => true
A <= A # => true
How can I know whether a class is inherited from another one? Some methods like is_a?
You can use the <
operator:
B < A
will be true, if B is a subclass of A.
Check if subclass is instance of parent
Try:
@template.is_a?(MessengerTemplate)
As noted in the docs:
Returns true if class is the class of obj, or if class is one of the superclasses of obj or modules included in obj.
MessengerTemplate
is a superclass of @template
, therefore @template.is_a?(MessengerTemplate) => true
.
Ruby: How do we identify whether an object o has a class C as its ancestor in the class hierarchy?
Try obj.kind_of?(Klassname)
:
1.kind_of?(Fixnum) => true
1.kind_of?(Numeric) => true
....
1.kind_of?(Kernel) => true
The kind_of?
method has also an identical alternative is_a?
.
If you want to check only whether an object is (direct) instance of a class, use obj.instance_of?
:
1.instance_of?(Fixnum) => true
1.instance_of?(Numeric) => false
....
1.instance_of?(Kernel) => false
You can also list all ancestors of an object by calling the ancestors
method on its class
. For instance 1.class.ancestors
gives you [Fixnum, Integer, Precision, Numeric, Comparable, Object, PP::ObjectMixin, Kernel]
.
How do I check if a variable is an instance of a class?
It's almost exactly the same. You can use Object
's instance_of?
method:
"a".instance_of? String # => true
"a".instance_of? Object # => false
Ruby also has the is_a?
and kind_of?
methods (these 2 are aliases, and work exactly the same), which returns true
is one of the superclasses matches:
"a".is_a? String # => true
"a".is_a? Object # => true
How can I determine if a class A inherits from class B without instantiating an A object in Ruby?
Sure, just compare the two classes:
if Admin < ActiveRecord::Base
# ...
end
It is interesting to note that while Module#<
will return true
if Admin
inherits from AR::Base
, it will return false
or nil
if that's not the case. false
means that it is the otherway around, while nil
is for unrelated classes (e.g. String < Range
returns nil
).
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.
Look up all descendants of a class in Ruby
Here is an example:
class Parent
def self.descendants
ObjectSpace.each_object(Class).select { |klass| klass < self }
end
end
class Child < Parent
end
class GrandChild < Child
end
puts Parent.descendants
puts Child.descendants
puts Parent.descendants gives you:
GrandChild
Child
puts Child.descendants gives you:
GrandChild
Related Topics
Ruby Devise, Sessionscontroller.Create, JSON - Getting Nameerror: Undefined 'Build_Resource'
Render Erb from Database into View Problem Please Help!
Using Devise for More Than One Models in Rails App
Marshal (Ruby) Pipes: Sending Serialized Object to Child Processes
How to Print a Line Number in Ruby
Rails "Template Is Missing" Error
Rails Form_For Never Invokes the Create Controller Action to Use Redirect_To
Understanding Ruby Method Parameters Syntax
Why Won't Ternary Operator Work with Redirect
Cannot Require 'Nokogiri' in Rails (But Works in Irb)
Pageobject with Ruby - Set Text in a Text Field Only Works in the Main File
Custom Gem Execution Fails with Nomethoderror
How to Add "Access-Control-Allow-Origin" Headers to API Response in Ruby
Mongomapper Many to Many Issue with Array
How to Verify Pacts Against an API That Requires an Auth Token
Gem::Loaderror: When Trying to Deploy on Heroku - Rails 4