Skip to content

Instantly share code, notes, and snippets.

@audionerd
Created October 31, 2008 03:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save audionerd/21209 to your computer and use it in GitHub Desktop.
Save audionerd/21209 to your computer and use it in GitHub Desktop.
# A demonstration of Ruby mixins, in response to:
# http://www.deftflux.net/blog/post/A-good-design-for-multiple-implementation-inheritance.aspx
module BarkingBehavior
def bark
puts "Bark!"
end
end
module MeowingBehavior
def meow
puts "Meow!"
end
end
class Dog
include BarkingBehavior
end
class Cat
include MeowingBehavior
end
class Human
include MeowingBehavior
include BarkingBehavior
end
class NoisyHuman
include MeowingBehavior
include BarkingBehavior
def meow
puts "MEOW! MEOW! MEOW!"
end
def bark
puts "BARK! BARK! BARK!"
end
end
puts <<HEREDOC
> Mixin example:
HEREDOC
human = Human.new
human.bark
human.meow
puts <<HEREDOC
> A behavior would be implicitly abstract in that it could not be directly instantiated.
HEREDOC
begin
new MeowingBehavior
rescue => error
puts "Can't create an instance of MeowingBehavior"
end
puts <<HEREDOC
> Polymorphism would not apply to behaviors. Meaning that an implementing
> class could not be referenced as an object of a behavior. As a result,
> variable types, parameter types, etc. could not be behaviors.
> This would prevent the poor designs multiple inheritance would normally enable.
HEREDOC
puts human.instance_of?(Human)
puts human.instance_of?(MeowingBehavior)
puts human.kind_of?(MeowingBehavior)
puts <<HEREDOC
> A behavior could implement interfaces and inherit other behaviors, but
> it cannot inherit a class.
HEREDOC
# This will work ...
module ImplementsAndInherits
include BarkingBehavior
include MeowingBehavior
def implementation
puts "I can implement stuff."
puts "Also, I can bark like a dog."
3.times { bark }
end
end
include ImplementsAndInherits
implementation
puts "(See source code for example of syntax error)"
# module ImplementsAndInheritsAndSubclasses < ImplementsAndInherits
# include TalkingBehavior
# def implementation
# puts "This won't work."
# end
# end
puts <<HEREDOC
> A behavior could specify a constraint similar to a generic constraint where
> the class that implements a behavior must inherit a given base class.
HEREDOC
module TalkingBehavior
def self.included(includer)
if includer.superclass == Human
puts "TalkingBehavior added to: #{includer}"
else
puts "TalkingBehavior must be included only by Humans"
end
end
def talk
puts "Hello, world!"
end
end
class TalkativeNonHuman
include TalkingBehavior
end
class TalkativeHuman < Human
include TalkingBehavior
end
puts "Creating a TalkativeHuman ..."
talky = TalkativeHuman.new
talky.talk
puts <<HEREDOC
> All protected and public members of a behavior must be overridable.
HEREDOC
noisy = NoisyHuman.new
noisy.bark
noisy.meow
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment