Когда я начал учиться в школе Flatiron, первое, что мы узнали при изучении объектно-ориентированного программирования (ООП) и классов, - это макросы.
Что такое макросы и что такое драгоценные камни?
Макросы - это код (воспринимайте его скорее как метод), который вместо того, чтобы возвращать тип данных Ruby, возвращает больше кода Ruby, который помогает вам определять больше методов. Это код, который пишет код за вас! Драгоценный камень - это библиотека кода, которую вы можете вызвать при запуске проекта, в котором есть много макросов.
Этот тип метапрограммирования (по сути, код, который пишет код) и концепция наследования являются фундаментальной концепцией программирования и Ruby. Вот почему вам не нужно учить ваш новый класс действовать как объект, но наследует все эти атрибуты от чего-то, что называется базовым объектом. Подробнее об этом можно узнать здесь.
Макросы казались мне волшебством. Кодирующая мантра, с которой я действительно связан, - СУХОЙ (Не повторяй себя), потому что я действительно не люблю повторение.
Примером макроса являются методы attr_accessor, attr_writer и attr_reader. Представьте, что вы хотите создать новый класс с некоторыми атрибутами при инициализации.
class Foo
def initialize
@foo
end
end
Чтобы иметь возможность читать и писать в этот атрибут, вам необходимо создать метод получения и метод установки.
class Foo
def initialize
@foo
end
#reader method
def foo
@foo
end
#writer method
def foo=(value)
@foo = value
end
end
Весь этот код; просто чтобы иметь возможность читать и писать на Foo.foo! Теперь посмотрим, как это выглядит с макросом.
class Foo
#accessor is both a getter and a setter
attr_accessor :foo
def initialize
@foo
end
end
Вот и все! Вы сделали. Намного меньше кода, намного меньше повторений, намного больше счастливого кодирования.
Демистификация магии
Давайте посмотрим, как это написать самому. Все, что это есть, - это метод, который принимает атрибут в качестве параметра и создает методы установки и получения, которые мы создали ранее. Он заключен в собственный класс или модуль, встроенный в Ruby. Но мы могли легко создать свои собственные. Давайте посмотрим, как мы могли бы написать свой собственный attr_accessor.
def var(*method_name)
method_name.each do |method|
inst_variable_name = "@#{method}".to_sym
define_method(method) do
instance_variable_get inst_variable_name
end
define_method("#{method}=") do |new_value|
instance_variable_set inst_variable_name, new_value
end
end
end
А теперь давайте разберем его по строкам.
def var(*method_name)
var будет нашим attr_accessor методом. Параметр использует переменные arguments (*method_name) для передачи любого количества аргументов в виде массива. С другой стороны, вы также можете комбинировать этот тип аргумента с другими типами аргументов (name, *args).
method_name.each do |method|
Мы используем перечислитель .each для перебора любых аргументов, переданных в нашем параметре.
inst_variable_name = "@#{method}".to_sym
Мы устанавливаем для переменной inst_variable_name значение @whatever_method_name, которое вы передали, используя интерполяцию строк. .to_sym превращает его в символ.
define_method(method) do
define_method принимает аргумент как имя метода, который мы хотим сгенерировать, и использует тело блока в качестве своего метода. В нашем случае это имя метода получения.
instance_variable_get inst_variable_name end
instance_variable_get возвращает значение данной переменной экземпляра или nil, если переменная экземпляра не установлена. Ruby требует, чтобы все переменные экземпляра начинались с @. Ruby также преобразует в символ любую переданную ему строку (в случае, если мы не использовали .to_sym, который использовали ранее.
define_method("#{method}=") do |new_value|
instance_variable_set inst_variable_name, new_value
end
instance_variable_set устанавливает переменную экземпляра, названную символом, для данного объекта, используя два аргумента (:@instance_variable, value). Переменная экземпляра не обязательно должна существовать до этого вызова. Как и в предыдущем методе, Ruby преобразует любую строку, переданную в качестве переменной экземпляра, в символ.
Теперь, когда у нас есть собственный attr_accessor, давайте обернем модуль и протестируем его.
module Bar
def var(*method_name)
method_name.each do |method|
inst_variable_name = "@#{method}".to_sym
define_method(method) do
instance_variable_get inst_variable_name
end
define_method("#{method}=") do |new_value|
instance_variable_set inst_variable_name, new_value
end
end
end
end
class Foo
extend Bar
var :foo, :bar
end
foo = Foo.new
=> #<Foo:0x000055fbcc3e7a10>
foo.foo
=> nil
foo.foo = "Foo"
=> "Foo"
foo.foo
=> "Foo"
Оно работает! Мы могли бы использовать эти концепции для создания собственных макросов для чего угодно. Если вы видите, что начинаете немного повторяться и хотите творить собственное «волшебство», вы легко сможете это сделать. Ruby действительно гибкий, и вы можете использовать его по-своему.
Теперь давайте создадим рубиновый гем, который будет хранить наш макрос, поэтому все, что нам нужно сделать, это вызвать его один раз, и не нужно вызывать каждый класс, который мы создаем.
Создание драгоценного камня
Установите гем bundler, если он еще не установлен.
В вашем терминале напишите следующую команду.
bundle gem name_of_gem
Что касается именования драгоценных камней, вы можете ознакомиться с соглашением об именовании здесь.
Если вы хотите выполнить инициализацию, вам будет предложено несколько вопросов (например, лицензия, правила поведения и т. Д.). Затем он сгенерирует кучу файлов.
name_of_gem.gemspec- здесь нам нужно указать имя, описание и домашнюю страницу нашего драгоценного камня.lib/name_of_gem.rb- это то место, где находится написанный вами код.
Чтобы собрать драгоценный камень, напишите следующий код:
gem build name_of_gem.rspec
Это должно создать драгоценный камень (если вы столкнетесь с какими-либо ошибками, убедитесь, что вы правильно заполнили файл rspec и находитесь в правильном каталоге).
Чтобы установить гем после этого, напишите следующее:
# this is the new file generated after building gem install ./nameofgem-0.1.0.gem
Вот и все! Теперь вы можете получить доступ к драгоценному камню, используя require.
Если вы хотите добавить свой гем на RubyGems.org.
Завести аккаунт.
Затем нажмите на свой драгоценный камень с помощью следующего кода:
gem push nameofgem-0.1.0.gem
Чтобы проверить, был ли он добавлен:
gem list -r nameofgem-0.1.0.gem
Вот и все. Удачного кодирования.
Ресурсы:
Создание макросов:
Https://learn.co/lessons/ruby-oo-macros-readme
Написание макросов в Ruby
В Rails вы все время используете объявления уровня класса, такие как has_many, own_to и другие так называемые« макросы . Для… pragmaticstudio.com »
Методы:
Создание драгоценных камней:
Разработчики Ruby | Как создать Ruby Gem
Ruby Gems или «драгоценный камень - это менеджер пакетов для языка программирования Ruby, который предоставляет стандартный формат для… www.railscarma.com »