Broslavsky Oleg 
ISCD TSU
«Вы делаете include 
модуля, чтобы 
добавить методы 
экземпляра класса, и 
extend — чтобы 
добавить методы 
класса»
Для удобства будем 
называть объект класса, т.е. 
объект полученный при 
помощи 
ClassName.new 
экземпляром или объектом 
класса 
Сам же класс так и будем 
называть классом
Чтобы лучше понять 
различия между extend и 
include, необходимо 
разобраться во 
взаимосвязях классов и их 
экземпляров в руби 
Из-за особого назначения классов очень легко потерять из вида 
тот факт, что классы — это тоже объекты Ruby
От «обычных» объектов 
классы отличает два вещи: 
они служат образцом 
для создания новых 
объектов 
они являются частью 
иерархии классов 
Классом всех классов (как объектов) в Ruby является класс Class
Когда вы вызываете метод 
для какого-то объекта, 
сначала Ruby ищет этот 
метод в классе объекта, 
потом в его суперклассе и 
так далее по всей 
иерархии классов до 
самого первого класса 
Самым первым классом в 
Ruby 1.9 является BasicObject.
Путь поиска метода для 
классов работает также. 
Сначала будет просмотрен 
класс объекта, т.е. 
класс Class, затем поиск 
продолжится в 
суперклассе Module и так 
далее до BasicObject.
Основная функция 
классов — определять 
поведение своих 
экземпляров. Однако в 
Ruby мы можем 
добавлять уникальное 
поведение отдельным 
объектам. 
snoopy = Dog.new 
def snoopy.alter_ego 
Чаще всего такие методы называют 
синглтон-методами, потому что они 
принадлежат только одному 
единственному объекту. 
"Red Baron" 
end 
snoopy.alter_ego 
# => "Red Baron" 
fido.alter_ego 
# => NoMethodError: undefined method…
Общий путь поиска 
метода не нарушается! 
Создается анонимный 
класс, чтобы разместить в 
нем синглтон-методы 
объекта. Затем этот 
анонимный класс 
становится суперклассом 
объекта, а класс объекта 
становиться суперклассом 
анонимного класса. 
У этого динамически создаваемого анонимного класса много названий: 
метакласс, класс-ореол (ghost), синглтон-класс и айгенкласс (eigenclass)
snoopy = Dog.new 
def snoopy.alter_ego 
"Red Baron" 
end 
class << snoopy 
def alter_ego 
"Red Baron" 
end 
end 
Конструкция «class <<» 
открывает метакласс 
любого объекта, который 
вы укажите, и дает вам 
возможность работать 
непосредственно внутри 
области видимости этого 
метакласса.
class << Dog 
def closest_relative 
“wolf" 
end 
end 
Являясь объектами, 
классы тоже могут иметь 
синглтон-методы. 
Методы класса на самом 
деле является ничем 
иным как синглтон- 
методами. Как и любые 
синглтон-методы, они 
располагаются внутри 
Dog 
метакласса bark() 
Dog’s eigenclass 
closest_relative()
class Dog 
class << self 
def closest_relative 
“wolf" 
end 
end 
end 
class Dog 
def closest_relative 
“wolf" 
end 
end 
class Dog 
def self.closest_relative 
“wolf" 
end 
end 
def Dog.closest_relative 
“wolf" 
end
Вот так просто выглядит 
полный путь поиска 
метода объекта :) 
… …
Теперь, когда мы 
разобрались со 
структурой классов в 
Ruby, довольно просто 
понять в чем же всё-таки 
разница между extend и 
include
Когда мы 
делаем include модуля в 
объект, мы добавляем 
методы модуля в цепь 
наследования объекта 
… 
FunnyTail 
Dog 
bark() 
Dog’s eigenclass 
closest_relative() 
do_trick() 
Dog.ancestors 
# => [Dog, FunnyTail, Object, 
Kernel, BasicObject]
Dog 
bark() 
… 
FunnyTail 
do_trick() 
Dog’s eigenclass 
closest_relative() 
Extend — это тоже самое, 
что сделать include, но для 
синглтон-класса объекта 
Dog.singleton_class.ancestors 
# => [FunnyTail, Class, Module, 
Object, Kernel, BasicObject]
Каждый вызов include 
проверяет подключаемый 
модуль на наличие метода 
included. Этот метод 
исполняется, когда модуль 
подключается, используя 
include. Его можно 
использовать, когда нужно 
добавить сразу и методы 
класса и методы экземпляра 
класса 
module FunnyTail 
def self.included(base) 
base.extend( 
FunnyTail.singleton_class) 
end 
… 
end 
У extend для этих целей есть 
собственный метод — extended
include — добавляет методы модуля объекту. 
extend — вызывает include для синглтон-класса 
объекта. 
«Стоит понять 
реализацию лежащую в 
основе и все сразу 
обретает смысл»
Вникаем в метаклассы Ruby 
http://habrahabr.ru/post/143990/ 
Вникаем в include и extend 
http://habrahabr.ru/post/143483/
Oleg Broslavsky 
ovbroslavsky@gmail.com 
@yalegko

Include and extend in Ruby

  • 1.
  • 2.
    «Вы делаете include модуля, чтобы добавить методы экземпляра класса, и extend — чтобы добавить методы класса»
  • 3.
    Для удобства будем называть объект класса, т.е. объект полученный при помощи ClassName.new экземпляром или объектом класса Сам же класс так и будем называть классом
  • 4.
    Чтобы лучше понять различия между extend и include, необходимо разобраться во взаимосвязях классов и их экземпляров в руби Из-за особого назначения классов очень легко потерять из вида тот факт, что классы — это тоже объекты Ruby
  • 5.
    От «обычных» объектов классы отличает два вещи: они служат образцом для создания новых объектов они являются частью иерархии классов Классом всех классов (как объектов) в Ruby является класс Class
  • 6.
    Когда вы вызываетеметод для какого-то объекта, сначала Ruby ищет этот метод в классе объекта, потом в его суперклассе и так далее по всей иерархии классов до самого первого класса Самым первым классом в Ruby 1.9 является BasicObject.
  • 7.
    Путь поиска методадля классов работает также. Сначала будет просмотрен класс объекта, т.е. класс Class, затем поиск продолжится в суперклассе Module и так далее до BasicObject.
  • 8.
    Основная функция классов— определять поведение своих экземпляров. Однако в Ruby мы можем добавлять уникальное поведение отдельным объектам. snoopy = Dog.new def snoopy.alter_ego Чаще всего такие методы называют синглтон-методами, потому что они принадлежат только одному единственному объекту. "Red Baron" end snoopy.alter_ego # => "Red Baron" fido.alter_ego # => NoMethodError: undefined method…
  • 9.
    Общий путь поиска метода не нарушается! Создается анонимный класс, чтобы разместить в нем синглтон-методы объекта. Затем этот анонимный класс становится суперклассом объекта, а класс объекта становиться суперклассом анонимного класса. У этого динамически создаваемого анонимного класса много названий: метакласс, класс-ореол (ghost), синглтон-класс и айгенкласс (eigenclass)
  • 10.
    snoopy = Dog.new def snoopy.alter_ego "Red Baron" end class << snoopy def alter_ego "Red Baron" end end Конструкция «class <<» открывает метакласс любого объекта, который вы укажите, и дает вам возможность работать непосредственно внутри области видимости этого метакласса.
  • 11.
    class << Dog def closest_relative “wolf" end end Являясь объектами, классы тоже могут иметь синглтон-методы. Методы класса на самом деле является ничем иным как синглтон- методами. Как и любые синглтон-методы, они располагаются внутри Dog метакласса bark() Dog’s eigenclass closest_relative()
  • 12.
    class Dog class<< self def closest_relative “wolf" end end end class Dog def closest_relative “wolf" end end class Dog def self.closest_relative “wolf" end end def Dog.closest_relative “wolf" end
  • 13.
    Вот так простовыглядит полный путь поиска метода объекта :) … …
  • 14.
    Теперь, когда мы разобрались со структурой классов в Ruby, довольно просто понять в чем же всё-таки разница между extend и include
  • 15.
    Когда мы делаемinclude модуля в объект, мы добавляем методы модуля в цепь наследования объекта … FunnyTail Dog bark() Dog’s eigenclass closest_relative() do_trick() Dog.ancestors # => [Dog, FunnyTail, Object, Kernel, BasicObject]
  • 16.
    Dog bark() … FunnyTail do_trick() Dog’s eigenclass closest_relative() Extend — это тоже самое, что сделать include, но для синглтон-класса объекта Dog.singleton_class.ancestors # => [FunnyTail, Class, Module, Object, Kernel, BasicObject]
  • 17.
    Каждый вызов include проверяет подключаемый модуль на наличие метода included. Этот метод исполняется, когда модуль подключается, используя include. Его можно использовать, когда нужно добавить сразу и методы класса и методы экземпляра класса module FunnyTail def self.included(base) base.extend( FunnyTail.singleton_class) end … end У extend для этих целей есть собственный метод — extended
  • 18.
    include — добавляетметоды модуля объекту. extend — вызывает include для синглтон-класса объекта. «Стоит понять реализацию лежащую в основе и все сразу обретает смысл»
  • 19.
    Вникаем в метаклассыRuby http://habrahabr.ru/post/143990/ Вникаем в include и extend http://habrahabr.ru/post/143483/
  • 20.