Вопрос

Я пришел с Java, и теперь я больше работаю с Ruby.

Одна языковая особенность, с которой я не знаком, - это module.Мне интересно, что именно представляет собой module и когда вы используете его, и зачем использовать module над собой class?

Это было полезно?

Решение

Первый ответ хорош и дает некоторые структурные ответы, но другой подход заключается в том, чтобы подумать о том, что вы делаете.Модули предназначены для предоставления методов, которые вы можете использовать в нескольких классах - думайте о них как о "библиотеках" (как вы могли бы видеть в приложении Rails).Классы - это объекты;модули - это функции.

Например, системы аутентификации и авторизации являются хорошими примерами модулей.Системы аутентификации работают в нескольких классах уровня приложения (аутентифицируются пользователи, сеансы управляют аутентификацией, множество других классов будут действовать по-разному в зависимости от состояния аутентификации), поэтому системы аутентификации действуют как общие API.

Вы также можете использовать модуль, когда у вас есть общие методы в нескольких приложениях (опять же, библиотечная модель здесь хороша).

Другие советы

╔═══════════════╦═══════════════════════════╦═════════════════════════════════╗
║               ║ class                     ║ module                          ║
╠═══════════════╬═══════════════════════════╬═════════════════════════════════╣
║ instantiation ║ can be instantiated       ║ can *not* be instantiated       ║
╟───────────────╫───────────────────────────╫─────────────────────────────────╢
║ usage         ║ object creation           ║ mixin facility. provide         ║
║               ║                           ║   a namespace.                  ║
╟───────────────╫───────────────────────────╫─────────────────────────────────╢
║ superclass    ║ module                    ║ object                          ║
╟───────────────╫───────────────────────────╫─────────────────────────────────╢
║ methods       ║ class methods and         ║ module methods and              ║
║               ║   instance methods        ║   instance methods              ║
╟───────────────╫───────────────────────────╫─────────────────────────────────╢
║ inheritance   ║ inherits behaviour and can║ No inheritance                  ║
║               ║   be base for inheritance ║                                 ║
╟───────────────╫───────────────────────────╫─────────────────────────────────╢
║ inclusion     ║ cannot be included        ║ can be included in classes and  ║
║               ║                           ║   modules by using the include  ║
║               ║                           ║   command (includes all         ║
║               ║                           ║   instance methods as instance  ║
║               ║                           ║   methods in a class/module)    ║
╟───────────────╫───────────────────────────╫─────────────────────────────────╢
║ extension     ║ can not extend with       ║ module can extend instance by   ║
║               ║   extend command          ║   using extend command (extends ║
║               ║   (only with inheritance) ║   given instance with singleton ║
║               ║                           ║   methods from module)          ║
╚═══════════════╩═══════════════════════════╩═════════════════════════════════╝

Я удивлен, что кто-то до сих пор этого не сказал.

Поскольку запрашивающий пришел из Java-среды (как и я), вот аналогия, которая помогает.

Классы - это просто как классы Java.

Модули подобны статическим классам Java.Подумайте о Math класс на Java.Вы не создаете его экземпляр, а повторно используете методы статического класса (например. Math.random()).

По сути, модуль не может быть создан.Когда класс включает модуль, генерируется прокси-суперкласс, который предоставляет доступ ко всем методам модуля, а также к методам класса.

Модуль может быть включен несколькими классами.Модули не могут быть унаследованы, но эта модель "смешивания" предоставляет полезный тип "множественного наследования".ОО-пуристы не согласятся с этим утверждением, но не позволяйте чистоте мешать выполнению работы.


(Этот ответ изначально связан с http://www.rubycentral.com/pickaxe/classes.html, но эта ссылка и ее домен больше не активны.)

Module в Ruby, в определенной степени, соответствует Java абстрактный класс -- имеет методы экземпляра, классы могут наследовать от него (через include, Ребята из Ruby называют это "микшированием"), но не имеет экземпляров.Есть и другие незначительные отличия, но этого объема информации достаточно, чтобы вы могли начать.

пространство имен: модули - это пространства имен...которых не существует в java ;)

Я также переключился с Java и python на Ruby, помню, у меня был точно такой же вопрос...

Итак, самый простой ответ заключается в том, что module - это пространство имен, которого не существует в Java.В Java наиболее близким подходом к пространству имен является a упаковка.

Итак, модуль в ruby похож на то, что в java:
класс? НЕТ
интерфейс? НЕТ
абстрактный класс? НЕТ
посылка? Да (возможно)

статические методы внутри классов в java:то же, что и методы внутри модулей в ruby

В java минимальной единицей измерения является класс, у вас не может быть функции вне класса.Однако в ruby это возможно (как и в python).

Итак, что входит в модуль?
классы, методы, константы.Модуль защищает их в этом пространстве имен.

Ни одного экземпляра: модули не могут быть использованы для создания экземпляров

Смешанные входы: иногда модели наследования не подходят для классов, но с точки зрения функциональности хочется сгруппировать набор классов / методов / констант вместе

Правила о модулях в ruby:
- Имена модулей указаны в верхнем регистре
- все константы внутри модулей являются заглавными (это правило одинаково для всех констант ruby, не специфичных для модулей)
- методы доступа:использовать .оператор
- константы доступа:использование ::символ

простой пример модуля:

module MySampleModule
  CONST1 = "some constant"

  def self.method_one(arg1)
    arg1 + 2
  end
end

как использовать методы внутри модуля:

puts MySampleModule.method_one(1) # prints: 3

как использовать константы модуля:

puts MySampleModule::CONST1 # prints: some constant

Некоторые другие соглашения о модулях:
Используйте один модуль в файле (например, классы ruby, по одному классу на файл ruby).

Итог:Модуль представляет собой нечто среднее между статическим / служебным классом и миксином.

Миксины - это повторно используемые фрагменты "частичной" реализации, которые могут быть объединены (или составлены) способом mix & match, чтобы помочь в написании новых классов.Конечно, эти классы могут дополнительно иметь свое собственное состояние и / или код.

Класс

Когда вы определяете класс, вы определяете схему элементов для типа данных.класс содержит данные, имеет метод, который взаимодействует с этими данными и используется для создания экземпляров объектов.

Модуль

  • Модули - это способ группировки методов, классов и констант.

  • Модули дают вам два основных преимущества:

    => Модули предоставляют пространство имен и предотвращают конфликты имен.Пространство имен помогает избежать конфликтов с функциями и классами с таким же именем, которые были написаны кем-то другим.

    => Модули реализуют функцию смешивания.

(включение модуля в Klazz предоставляет экземплярам Klazz доступ к методам модуля .)

(расширьте Klazz с помощью Mod, предоставив классу Klazz доступ к методам Mods.)

Во-первых, некоторые сходства, о которых еще не упоминалось.Ruby поддерживает открытые классы, но модули также являются открытыми.В конце концов, класс наследуется от Модуля в цепочке наследования классов, и поэтому класс и модуль действительно имеют некоторое сходное поведение.

Но вам нужно спросить себя, какова цель наличия как класса, так и Модуля на языке программирования?Класс предназначен для того, чтобы быть схемой для создания экземпляров, и каждый экземпляр является реализованной вариацией схемы.Экземпляр - это просто реализованная вариация схемы элементов (класса).Естественно, тогда классы функционируют как создание объектов.Более того, поскольку иногда мы хотим, чтобы одна схема была производной от другой схемы, классы предназначены для поддержки наследования.

Модули не могут быть созданы, не создают объекты и не поддерживают наследование.Поэтому помните, что один модуль НЕ наследуется от другого!

Итак, тогда в чем смысл наличия модулей на каком-либо языке?Одним из очевидных способов использования модулей является создание пространства имен, и вы заметите это и в других языках.Опять же, что здорово в Ruby, так это то, что модули можно повторно открывать (так же, как классы).И это большое применение, когда вы хотите повторно использовать пространство имен в разных файлах Ruby:

module Apple
  def a
    puts 'a'
  end
end

module Apple 
  def b
    puts 'b'
  end
end

class Fruit
  include Apple
end

 > f = Fruit.new
 => #<Fruit:0x007fe90c527c98> 
 > f.a
 => a
 > f.b
 => b

Но между модулями нет наследования:

module Apple
  module Green
    def green
      puts 'green'
    end
  end
end

class Fruit
  include Apple
end

> f = Fruit.new
 => #<Fruit:0x007fe90c462420> 
> f.green
NoMethodError: undefined method `green' for #<Fruit:0x007fe90c462420>

Модуль Apple не унаследовал никаких методов от модуля Green, и когда мы включили Apple в класс Fruit, методы модуля Apple были добавлены в цепочку предков экземпляров Apple, но не методы модуля Green, хотя модуль Green был определен в модуле Apple.

Итак, как же нам получить доступ к зеленому методу?Вы должны явно включить его в свой класс:

class Fruit
  include Apple::Green
end
 => Fruit 
 > f.green
=> green

Но у Ruby есть еще одно важное применение для модулей.Это средство смешивания, которое я описываю в другом ответе на SO.Но, подводя итог, миксины позволяют вам определять методы в цепочке наследования объектов.С помощью mixins вы можете добавлять методы в цепочку наследования экземпляров объектов (include) или singleton_class of self (extend).

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top