Ruby/Language Basics/Mixins
Материал из Wiki.crossplatform.ru
Содержание |
Automatically Initializing Mixed-In Modules
class Class def included_modules @included_modules ||= [] end alias_method :old_new, :new def new(*args, &block) obj = old_new(*args, &block) self.included_modules.each do |mod| mod.initialize if mod.respond_to?(:initialize) end obj end end module Initializable def self.included(mod) mod.extend ClassMethods end module ClassMethods def included(mod) if mod.class != Module #in case Initializeable is mixed-into a class puts "Adding #{self} to #{mod}"s included_modules" if $DEBUG mod.included_modules << self end end end end module A include Initializable def self.initialize puts "A"s initialized." end end module B include Initializable def self.initialize puts "B"s initialized." end end class BothAAndB include A include B end both = BothAAndB.new # A"s initialized. # B"s initialized.
Creating Mixins
# Creating a mixin using a module includes the code in a module inside a class and # gives you a way of inheriting from multiple modules. module Adder def add(operand_one, operand_two) return operand_one + operand_two end end module Subtracter def subtract(operand_one, operand_two) return operand_one - operand_two end end class Calculator include Adder include Subtracter end calculator = Calculator.new() puts "2 + 3 = " + calculator.add(2, 3).to_s
Mixing in Class Methods.rb
module MyLib module ClassMethods def class_method puts "in MyLib::ClassMethods" end end end module MyLib def self.included(receiver) puts "MyLib is being included in #{receiver}!" receiver.extend(ClassMethods) end end class MyClass include MyLib end # MyLib is being included in MyClass! MyClass.class_method # This method was first defined in MyLib::ClassMethods
Simulating Multiple Inheritance with Mixins.rb
require "set" module Taggable attr_accessor :tags def taggable_setup @tags = Set.new end def add_tag(tag) @tags << tag end def remove_tag(tag) @tags.delete(tag) end end module Taggable2 def initialize(a,b,c) end end class TaggableString < String include Taggable def initialize(*args) super taggable_setup end end s = TaggableString.new("this is a test.") s.add_tag "A" s.add_tag "B" s.tags
The Making of a Man
class Person attr_accessor :name, :age, :gender end person_instance = Person.new person_instance.name = "Robert" person_instance.age = 52 person_instance.gender = "male" puts person_instance.name