Когда я начал учиться в школе 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 | Как создать Ruby Gem
Ruby Gems или «драгоценный камень
- это менеджер пакетов для языка программирования Ruby, который предоставляет стандартный формат для… www.railscarma.com »



Дополнительная литература: