The Inherited Hook Method in Ruby - and More Parenting Lessons
source link: https://blog.appsignal.com/2019/09/03/inherited-hook-method-and-parenting.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
Hello children and parents, ahem Rubyists. In an earlier article, we dove into the ancestry chain. In today’s post, we’ll dive deeper into parenting and inheritance. We will explore the inherited hook method and look into preventing inheritance.
When Kids Inherit 101: The Inherited Hook Method
Let’s start with a look at how parenthood is declared. Ruby provides a neat way of interacting with a class when it is declared as the parent of another class.
class Parent def self.inherited(subclass) puts "#{subclass} inherits from Parent" end end class Child < Parent end
Running this code prints out “Child inherits from Parent”, as the Parent.inherited
method is called when the Child
class inherits from Parent
. Note that this method takes the subclass as parameter—Child
, in our case. This mechanism allows you to interact with the Parent class to define a set of behaviors only if it is inherited. By behavior, in this context, we mean modifying, defining or deleting variables, methods and constants on the inheriting or the inherited class.
Now, let’s define the parent_name
method on-the-fly:
class Parent def self.inherited(subclass) subclass.define_method :parent_name do "Daddy" end end end class Child < Parent end Child.new.parent_name # => "Daddy"
Here, we define a method on the Child
class when it inherits from the Parent
class, but without adding that method directly to the Parent
class. Instead, it’s only defined when another class inherits from Parent
.
Alright, we’ve covered the theory, now let’s take a look at a more realistic example in the life of a Rubyist.
Prevent Class Inheritance
In Ruby on Rails, database migrations are handled by the ActiveRecord::Migration
class. Let’s try to directly inherit from this class.
class AddFirstnameToUsers < ActiveRecord::Migration end # => StandardError (Directly inheriting from ActiveRecord::Migration is not supported..)
This error is raised because Ruby on Rails provides a mechanism that prevents us from inheriting from this class. So why did Ruby on Rails implement this mechanism?
A migration is strongly coupled to a specific version of Ruby on Rails. Indeed, the API provided by this class can slightly change between 2 versions. So, to avoid breaking migrations when you upgrade Ruby on Rails, the framework forces you to choose a specific version of the ActiveRecord::Migration class. This ensures the smooth running of your migrations.
class AddFirstnameToUsers < ActiveRecord::Migration[4.2] end
In the example above, our migration is coupled to the ActiveRecord::Migration
API provided with version 4.2 of Ruby on Rails. So, even if we upgrade our application to version 5.0, our migrations will still run smoothly because they’ll still run with version 4.2 of the ActiveRecord::Migration
API.
How Preventing Inheritance Works
Now that we understand why inheritance is prevented here, let’s see how this ActiveRecord::Migration
prevents inheritance. All the logic is defined in the ActiveRecord::Migration.inherited
method.
class AddFirstnameToUsers < ActiveRecord::Migration[4.2] end
When our AddFirstnameToUsers
class inherits from ActiveRecord::Migration
, the ActiveRecord::Migration.inherited
hook method is called.
module ActiveRecord class Migration def self.inherited(subclass) #:nodoc: super if subclass.superclass == Migration raise StandardError, "Directly inheriting from ActiveRecord::Migration is not supported. " \ "Please specify the Rails release the migration was written for:\n" \ "\n" \ " class #{subclass} < ActiveRecord::Migration[4.2]" end end end end
As we can see, this hook method checks if the subclass (AddFirstnameToUsers
) directly inherits from ActiveRecord::Migration
. If it does, an error is raised. This is the perfect entry point for controlling inheritance.
Conclusion
Today, we covered the basics of inheritance and preventing inheritance. We covered the inherited hook method and saw how it can be very handy when interacting with the inheriting/inherited class on-the-fly.
In a real-world setting, watch out when playing with inheritance. Be very cautious when you remove or override an existing method or class. This could result in some unwanted side effects. Children may stop calling you daddy.
Et Voilà, this concludes our post for today!
Guest author Mehdi Farsi is the founder of www.rubycademy.com which will offer cool courses to learn Ruby and Ruby on Rails.
Recommend
-
44
-
61
When you’ve worked in the digital industry for long enough, eventually you’re going to have to work with code that you’ve inherited from someone else. Whether this is part of a handover process from another company, writt...
-
8
Android上的热修复框架 AndFix 想必已经是耳熟能详,它的原理实际上很简单:方法替换——Java层的每一个方法在虚拟机实现里面都对应着一个ArtMethod的结构体,只要把原方法的结构体内容替换成新的结构体的内容,在调用原方法的时候,真正执行的指令会是新方法的指...
-
13
Are static fields inherited? advertisements When static members are inherited, are they static for the entire hierarchy, or just that class, i...
-
5
Flutter: Creating your own Inherited WidgetsWhile we generally use Provider or GetIt to pass things around in Flutter, there are times when you don...
-
1
通过fishhook拦截方法的局限性我之前写了一个开源库TimeProfiler,监控所有的OC方法耗时。可以在开发App阶段,很方便的看到...
-
4
Chromium disregards the inherited "text-indent" on anonymous flex items
-
57
SqlAlchemy: converts the type inherited from one to another advertisements Let's say I have two different types both on the same database tabl...
-
3
CEO InsiderLESSONS FROM THE LIVING ROOM: Leadership Lessons Learned From ParentingJeremy Sirota CEO of MerlinI learned a few leader...
-
3
OverviewLet’s cut the BS and get down to brass tacks: interviewing sucks and so does the modern hiring process. That goes double for the UI/UX industry.What I’m gonna share with you today is a...
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK