Программирование на языке Ruby
Программирование на языке Ruby читать книгу онлайн
Внимание! Книга может содержать контент только для совершеннолетних. Для несовершеннолетних чтение данного контента СТРОГО ЗАПРЕЩЕНО! Если в книге присутствует наличие пропаганды ЛГБТ и другого, запрещенного контента - просьба написать на почту [email protected] для удаления материала
class Person
attr_accessor :name, :age, :phone
def initialize(n,a,p)
@name, @age, @phone = n, a, p
end
end
p1 = Person.new("John Smith",29,"555-1234")
p2 = Person.allocate
p p1.age # 29
p p2.age # nil
11.1.12. Модули
Для использования модулей в Ruby есть две основных причины. Первая — облегчить управление пространством имен; если поместить константы и методы в модули, то будет меньше конфликтов имен. Хранящийся таким образом метод (метод модуля) вызывается с указанием имени модуля, то есть без вызывающего объекта. Точно так же вызывается и метод класса. Увидев вызовы вида
File.ctime
FileTest.exist?
File
FileTest
Вторая причина более интересна: мы можем использовать модуль как примесь. Примеси — это способ реализации множественного наследования, при котором наследуется только интерфейс.
Мы уже говорили о методах модуля, а как насчет методов экземпляра? Модуль — это не класс, у него не может быть экземпляров, а к методу экземпляра нельзя обратиться, не указав вызывающий объект.
Но оказывается, модуль может иметь методы экземпляра. Они становятся частью класса, который включил модуль директивой
include
module MyMod
def meth1
puts "Это метод 1."
end
end
class MyClass
include MyMod
# ...
end
x = MyClass.new
x.meth1 # Это метод 1.
Здесь модуль
MyMod
MyClass
meth1
include
Object
А что происходит с методами модуля, если таковые определены? Если вы думаете, что они становятся методами класса, то ошибаетесь. Методы модуля не подмешиваются.
Но если такое поведение желательно, то его можно реализовать с помощью нехитрого трюка. Существует метод
append_features
module MyMod
def MyMod.append_features(someClass)
def someClass.modmeth
puts "Метод модуля (класса) "
end
super # Этот вызов обязателен!
end
def meth1
puts "Метод 1"
end
end
class MyClass
include MyMod
def MyClass.classmeth
puts "Метод класса"
end
def meth2
puts "Метод 2"
end
end
x = MyClass.new
# Выводится:
MyClass.classmeth # Метод класса
x.meth1 # Метод 1
MyClass.modmeth # Метод модуля (класса)
x.meth2 # Метод 2
Этот пример заслуживает детального рассмотрения. Во-первых, надо понимать, что метод
append_features
include
meth1
Отметим также, что внутри тела
append_features
Nested method error
Модуль мог бы захотеть узнать, кто был инициатором примеси. Для этого тоже можно воспользоваться методом
append_features
Можно также подмешивать методы экземпляра модуля как методы класса. В листинге 11.7 приведен соответствующий пример.
module MyMod
def meth3
puts "Метод экземпляра модуля meth3"
puts "может стать методом класса."
end
end
class MyClass