Traits are somewhat like Abstract Classes in PHP. They’re almost like taping on additional methods onto a class.
Meows trait will add the meowing capability to any class that uses the trait. Let’s remove the
meow method from our
Cat instance and let the
Meows trait do that work:
Now other classes can use that meowing functionality without having to extend an abstract class:
Like Abstract Classes they cannot be instantiated on their own:
What’s the difference between Traits and Abstract Classes?
However the biggest difference between Traits and Abstract Classes is that a regular PHP class cannot extend from multiple Abstract Classes:
However you can use multiple traits without a problem. Imagine we had another trait,
Now we can use both
Purrs in the same class:
Traits in Ruby
Ruby has this same concept built right into the language. However a Ruby “trait” it’s not a dedicated “type” that you can attach to full classes.
Back in the namespacing section of this series I hinted that Modules were like Traits. It’s true, they’re very much like Traits:
- They cannot be instantiated on their own
- They can have methods defined for public or private use
- They can extend classes
- A class can have multiple traits (or modules) attached
With that said, let’s create our first Trait:
module Meows def meows puts 'meows' end end
Now to use it on our Ruby class, we’ll need to use the keyword
include instead of PHP’s
class Cat include Meows end cat = Cat.new cat.meows => 'meows'
It’s just that simple. The
include keyword essentially tapes all of the methods available in a Module and attaches them to the class.
Multiple Modules in a Class
Just like PHP’s Traits, we can use multiple Modules in a Class. Let’s make a Ruby equivalent of
module Purrs def purrs puts 'purrrrrr' end end
Now we can attach both
Meows modules to our
class Cat include Purrs, Meows end cat = Cat.new cat.purr cat.meow => 'purrrrrr' => 'meow'
And there you have it. PHP Trait like functionality in Ruby by using Modules.