Метапрограммирование - это область программирования, в которой результатом написания кода является не потребительская программа, а изменение языка или и вовсе, создание нового. Звучит тяжело, но попробуем разобраться.
Как мв рассматривали ранее, в Ruby абсолютно все является объектами и классами. например наш кастомный класс Person невидимо для нас является наследником Object, при этом класс Person является объектом класса Class. Именно с последней особенностью тестно связаны наши методы класса, которые мы обявляет через self.
Для начала давайте разберем такое понятие как singleton методы.
Предположим у нас есть класс Person
classPersondefhelloputs'Hello'endend
А теперь посмотрим как мы можем добавить новый метод для объекта не изменяя сам класс
person_1=Person.newperson_2=Person.newperson_1.hello# = Helloperson_2.hello# = Helloperson_1.bye# Ошибка, ведь такой метод не существуетperson_2.bye# Ошибка, ведь такой метод не существует# Мы создали новый singleton метод у объекта под названием bye# Важно понимать, что этот метод существует только у данного объектаdefperson_1.byeputs'Bye'endperson_1.bye# Byeperson_2.bye# Ошибка, ведь такой метод не существует
Так вот, когда вы объявляете метод класса с помощью self в начале, то вы по сути создаете singletone метод для объекта класса Class, ведь наш класс Person вляется его объектом.
Само по себе ключевое слово self обозначает указание на собственный объект, только в зависимости от области нахождения этого слова, может меняться сам оюъект на который он указывает, т.е. в нашем случае это либо указание на собственный объект класса Person, либо указание на объект класса Class.
Аналогичную запись можно сделать с помощью наследования
Кроме того, мы может добавлять на лету методы для нашего класса
Помимо прочего, мы также можем расширять методы класса с помощью специального метода instance_eval
А также может добавлять методы для каждого объекта нашего лкасса с помощью метода class_eval
В Ruby существует оргомное количество библиотек, которые расширяют те или иные классы. Фреймворк Rails по большей части строится вокруг этой концепции, с чем вы убедитесь позже.
Задание reverse_words
Напишите метод reverse_words, который можно будет вызвать у любой строки и который будет менять последовательность слов в обратном порядке
person_1 = Person.new
person_2 = Person.new
person_1.hello # = Hello
person_2.hello # = Hello
person_1.bye # Ошибка, ведь такой метод не существует
person_2.bye # Ошибка, ведь такой метод не существует
# Мы создали новый singleton метод у объекта под названием bye
# Важно понимать, что этот метод существует только у данного объекта
def person_1.bye
puts 'Bye'
end
class << person_2
def world
puts 'World'
end
end
person_1.bye # Bye
person_2.bye # Ошибка, ведь такой метод не существует
person_1.world # Ошибка, ведь такой метод не существует
person_2.world # World
def Person.example
puts 'Example'
end
class << Person
def another_example
puts 'Another example'
end
end
Person.example # Example
Person.another_example # Another example
# Внутри этого блока кода мы можем создавать новые методы для нашего класса
Person.instance_eval do
def fly
puts 'Person is flying'
end
end
Person.fly # Person is flying
# Методы объявленные в этом блоке будут принадлежать всем объектам
Person.class_eval do
def toilet
puts "Person is going to toilet"
end
end
person_3 = Person.new
person_4 = Person.new
person_3.toilet # Person is going to toilet
person_4.toilet # Person is going to toilet