Я пришел с Java, и теперь я больше работаю с Ruby.
Одна из особенностей языка, с которой я не знаком, это module. Мне интересно, что именно moduleи когда вы используете один, и почему использовать более moduleчем class?
Первый ответ хорош и дает некоторые структурные ответы, но другой подход - подумать о том, что вы делаете. Модули предназначены для предоставления методов, которые вы можете использовать в нескольких классах - думайте о них как о «библиотеках» (как вы видели бы в приложении Rails). Классы об объектах; модули о функциях.
Например, системы аутентификации и авторизации являются хорошими примерами модулей. Системы аутентификации работают в нескольких классах уровня приложения (пользователи проходят аутентификацию, сеансы управляют аутентификацией, многие другие классы будут работать по-разному в зависимости от состояния аутентификации), поэтому системы аутентификации действуют как общие API.
Вы также можете использовать модуль, когда у вас есть общие методы для нескольких приложений (опять же, модель библиотеки здесь хорошая).
@Caffeine на самом деле не потому, что модули Ruby на самом деле включают в себя реализации, в то время как интерфейсы в Java являются абстрактными
Jorge Israel Peña
8
Нет, Модули и Пакеты Java / JAR - совершенно разные звери.
Кароли Хорват
9
Я больше похож на абстрактные классы с реализацией метода.
Автомат
2
На самом деле, @Chole сталкивается с одной из приятных особенностей модулей: пространством имен. Таким образом, хотя модули не являются прямым эквивалентом пакетов в Java, их можно использовать для достижения чего-то похожего: blog.rubybestpractices.com/posts/gregory/…
michaelok
513
╔═══════════════╦═══════════════════════════╦═════════════════════════════════╗
║ ║ 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) ║
╚═══════════════╩═══════════════════════════╩═════════════════════════════════╝
Я получил иерархию, Класс -> Модуль -> Объект -> BasicObject. Круто!!
Aashish P
Почему «модуль состоит из» пропускаемых переменных, когда и классы, и модули поддерживают переменные класса? Смотрите принятый ответ на stackoverflow.com/questions/5690458/…
Как модуль может "не быть реализован" и при этом иметь методы экземпляра?
Деви
91
Я удивлен, что никто еще не сказал это.
Поскольку спрашивающий пришел из Java-фона (и я тоже), вот аналогия, которая помогает.
Классы просто похожи на классы Java.
Модули похожи на статические классы Java. Подумайте о Mathклассе в Java. Вы не создаете его экземпляр и повторно используете методы в статическом классе (например, Math.random()).
Но модули также могут добавлять методы экземпляра во включающий класс, в то время как статические классы в Java не могут.
Восстановить Монику - Нотмейнард
4
Это утверждение также верно из-за тяжелого C # фона.
Дэймон Дрейк,
5
Это не совсем верно; модули не имеют статических методов, они просто имеют методы. Модули могут «расширяться» (фактически синтаксис extend self), делая их методы доступными для их selfметакласса. Это позволяет отправлять метод как random()в Mathмодуле. Но по своей природе методы модуля не могут быть вызваны самим модулем self. Это связано с понятием Руби self, его метаклассами и тем, как работает поиск методов. Проверьте "Метапрограммирование Руби" - Паоло Перлотта для деталей.
scottburton11
Я бы сказал, что модули больше похожи на интерфейсы с методами в них (интерфейсы Java 8 с impl по умолчанию), но не могут наследовать один от другого в отличие от интерфейсов java
divByZero
Откуда у этого ответа столько голосов? Кстати, это было сказано более хорошими словами за 1 месяц до этого: stackoverflow.com/a/17027346/986862
Андре Фигуейредо
39
По сути, модуль не может быть создан. Когда класс включает в себя модуль, создается прокси-суперкласс, который обеспечивает доступ ко всем методам модуля, а также к методам класса.
Модуль может быть включен несколькими классами. Модули не могут быть унаследованы, но эта модель "mixin" предоставляет полезный тип "множественного наследования". ОО-пуристы не согласятся с этим утверждением, но не позволяют чистоте мешать выполнению работы.
(Этот ответ изначально связан с http://www.rubycentral.com/pickaxe/classes.html, но эта ссылка и ее домен больше не активны.)
Да, вот как это работает. Таким образом, модули не сопоставимы с «статическими» классами Java; суперкласс прокси (некоторые называют его «метаклассом») становится получателем сообщений диспетчеризации метода модуля, что делает его более сопоставимым со статическим классом в Java, а его методы работают подобно статическим методам. Однако то же самое верно для классов Ruby, которые могут использовать «статические» методы, extendиспользуя класс. На самом деле Ruby вообще не различает методы «instance» и «class / static», только их получатели.
scottburton11
7
Moduleв Ruby, в некоторой степени, соответствует абстрактному классу Java - имеет методы экземпляра, классы могут наследовать от него (через include, ребята из Ruby называют его «mixin»), но не имеют экземпляров. Существуют и другие незначительные различия, но этого достаточно, чтобы начать работу.
namespace: модули - это пространства имен ... которые не существуют в java;)
Я также переключился с Java и Python на Ruby, я помню, был точно такой же вопрос ...
Таким образом, самый простой ответ заключается в том, что модуль является пространством имен, которого нет в Java. В Java самый близкий образ мышления к пространству имен - это пакет .
Таким образом, модуль в ruby похож на то, что в java: class? Нет интерфейса? Нет абстрактного класса? Нет пакета? Да, может быть)
статические методы внутри классов в java: так же, как методы внутри модулей в ruby
В Java минимальной единицей является класс, у вас не может быть функции вне класса. Однако в ruby это возможно (как в python).
Итак, что входит в модуль?
классы, методы, константы. Модуль защищает их в этом пространстве имен.
Нет экземпляра: модули не могут быть использованы для создания экземпляров
Смешанные модули: иногда модели наследования не подходят для классов, но с точки зрения функциональности хотят сгруппировать набор классов / методов / констант вместе
Правила для модулей в ruby:
- Имена модулей - UpperCamelCase
- константы внутри модулей - ВСЕ CAPS (это правило одинаково для всех констант ruby, не специфично для модулей)
- методы доступа: использовать. оператор
- константы доступа: используйте :: символ
«- методы доступа: использовать. оператор - константы доступа: используйте :: символ ”, только этот ответ упоминал об этом!
Qiulang
4
Итог: модуль представляет собой нечто среднее между статическим / служебным классом и миксином.
Миксины - это многократно используемые части «частичной» реализации, которые можно комбинировать (или составлять) в режиме «смешивать и сочетать», чтобы помочь в написании новых классов. Конечно, эти классы могут иметь собственное состояние и / или код.
Когда вы определяете класс, вы определяете план для типа данных. класс содержит данные, имеет метод, который взаимодействует с этими данными и используется для создания экземпляров объектов.
модуль
Модули - это способ группировки методов, классов и констант.
Модули дают вам два основных преимущества:
=> Модули предоставляют пространство имен и предотвращают конфликты имен. Пространство имен помогает избежать конфликтов с функциями и классами с тем же именем, которые были написаны кем-то другим.
=> Модули реализуют смешанный механизм.
(Включение модуля в Klazz дает экземплярам доступа Klazz к методам модуля.)
(расширить Klazz с помощью Mod, предоставив классу Klazz доступ к методам Mods.)
Во-первых, некоторые сходства, которые еще не были упомянуты. Ruby поддерживает открытые классы, но модули также открыты. В конце концов, Class наследует от Module в цепочке наследования Class, и поэтому Class и Module имеют похожее поведение.
Но вы должны спросить себя, какова цель наличия класса и модуля на языке программирования? Предполагается, что класс является планом для создания экземпляров, а каждый экземпляр представляет собой реализованный вариант плана. Экземпляр - это просто реализованная вариация проекта (Класса). Естественно, что классы функционируют как создание объектов. Кроме того, поскольку иногда мы хотим, чтобы один проект был получен из другого проекта, классы предназначены для поддержки наследования.
Модули не могут быть созданы, не создают объекты и не поддерживают наследование. Помните, что один модуль НЕ наследуется от другого!
Так в чем же смысл наличия модулей на языке? Одно из очевидных применений модулей - создание пространства имен, и вы заметите это и на других языках. Опять же, что хорошо в Ruby, так это то, что Модули можно открывать снова (так же, как Классы). И это большое использование, когда вы хотите повторно использовать пространство имен в разных файлах Ruby:
moduleAppledef a
puts 'a'endendmoduleAppledef b
puts 'b'endendclassFruit
include Appleend> f =Fruit.new
=>#<Fruit:0x007fe90c527c98> > f.a
=> a
> f.b
=> b
Но нет наследования между модулями:
moduleApplemoduleGreendef green
puts 'green'endendendclassFruit
include Appleend> f =Fruit.new
=>#<Fruit:0x007fe90c462420> > f.green
NoMethodError: undefined method `green' for #<Fruit:0x007fe90c462420>
Модуль Apple не наследовал никаких методов от модуля Green, и когда мы включили Apple в класс Fruit, методы модуля Apple были добавлены в цепочку предков экземпляров Apple, но не в методы модуля Green, хотя Green модуль был определен в модуле Apple.
Так как же нам получить доступ к зеленому методу? Вы должны явно включить его в свой класс:
classFruit
include Apple::Greenend=>Fruit> f.green
=> green
Но у Ruby есть еще одно важное применение для модулей. Это средство Mixin, которое я опишу в другом ответе на SO. Подводя итог, можно сказать, что миксины позволяют определять методы в цепочке наследования объектов. С помощью миксинов вы можете добавлять методы в цепочку наследования экземпляров объектов (include) или singleton_class класса self (extension).
Ответы:
Первый ответ хорош и дает некоторые структурные ответы, но другой подход - подумать о том, что вы делаете. Модули предназначены для предоставления методов, которые вы можете использовать в нескольких классах - думайте о них как о «библиотеках» (как вы видели бы в приложении Rails). Классы об объектах; модули о функциях.
Например, системы аутентификации и авторизации являются хорошими примерами модулей. Системы аутентификации работают в нескольких классах уровня приложения (пользователи проходят аутентификацию, сеансы управляют аутентификацией, многие другие классы будут работать по-разному в зависимости от состояния аутентификации), поэтому системы аутентификации действуют как общие API.
Вы также можете использовать модуль, когда у вас есть общие методы для нескольких приложений (опять же, модель библиотеки здесь хорошая).
источник
источник
Я удивлен, что никто еще не сказал это.
Поскольку спрашивающий пришел из Java-фона (и я тоже), вот аналогия, которая помогает.
Классы просто похожи на классы Java.
Модули похожи на статические классы Java. Подумайте о
Math
классе в Java. Вы не создаете его экземпляр и повторно используете методы в статическом классе (например,Math.random()
).источник
extend self
), делая их методы доступными для ихself
метакласса. Это позволяет отправлять метод какrandom()
вMath
модуле. Но по своей природе методы модуля не могут быть вызваны самим модулемself
. Это связано с понятием Рубиself
, его метаклассами и тем, как работает поиск методов. Проверьте "Метапрограммирование Руби" - Паоло Перлотта для деталей.По сути, модуль не может быть создан. Когда класс включает в себя модуль, создается прокси-суперкласс, который обеспечивает доступ ко всем методам модуля, а также к методам класса.
Модуль может быть включен несколькими классами. Модули не могут быть унаследованы, но эта модель "mixin" предоставляет полезный тип "множественного наследования". ОО-пуристы не согласятся с этим утверждением, но не позволяют чистоте мешать выполнению работы.
(Этот ответ изначально связан с
http://www.rubycentral.com/pickaxe/classes.html
, но эта ссылка и ее домен больше не активны.)источник
extend
используя класс. На самом деле Ruby вообще не различает методы «instance» и «class / static», только их получатели.Module
в Ruby, в некоторой степени, соответствует абстрактному классу Java - имеет методы экземпляра, классы могут наследовать от него (черезinclude
, ребята из Ruby называют его «mixin»), но не имеют экземпляров. Существуют и другие незначительные различия, но этого достаточно, чтобы начать работу.источник
namespace: модули - это пространства имен ... которые не существуют в java;)
Я также переключился с Java и Python на Ruby, я помню, был точно такой же вопрос ...
Таким образом, самый простой ответ заключается в том, что модуль является пространством имен, которого нет в Java. В Java самый близкий образ мышления к пространству имен - это пакет .
Таким образом, модуль в ruby похож на то, что в java:
class? Нет
интерфейса? Нет
абстрактного класса? Нет
пакета? Да, может быть)
статические методы внутри классов в java: так же, как методы внутри модулей в ruby
В Java минимальной единицей является класс, у вас не может быть функции вне класса. Однако в ruby это возможно (как в python).
Итак, что входит в модуль?
классы, методы, константы. Модуль защищает их в этом пространстве имен.
Нет экземпляра: модули не могут быть использованы для создания экземпляров
Смешанные модули: иногда модели наследования не подходят для классов, но с точки зрения функциональности хотят сгруппировать набор классов / методов / констант вместе
Правила для модулей в ruby:
- Имена модулей - UpperCamelCase
- константы внутри модулей - ВСЕ CAPS (это правило одинаково для всех констант ruby, не специфично для модулей)
- методы доступа: использовать. оператор
- константы доступа: используйте :: символ
Простой пример модуля:
как использовать методы внутри модуля:
Как использовать константы модуля:
Некоторые другие соглашения о модулях:
Используйте один модуль в файле (например, классы ruby, один класс на файл ruby)
источник
Итог: модуль представляет собой нечто среднее между статическим / служебным классом и миксином.
Миксины - это многократно используемые части «частичной» реализации, которые можно комбинировать (или составлять) в режиме «смешивать и сочетать», чтобы помочь в написании новых классов. Конечно, эти классы могут иметь собственное состояние и / или код.
источник
Учебный класс
Когда вы определяете класс, вы определяете план для типа данных. класс содержит данные, имеет метод, который взаимодействует с этими данными и используется для создания экземпляров объектов.
модуль
Модули - это способ группировки методов, классов и констант.
Модули дают вам два основных преимущества:
=> Модули предоставляют пространство имен и предотвращают конфликты имен. Пространство имен помогает избежать конфликтов с функциями и классами с тем же именем, которые были написаны кем-то другим.
=> Модули реализуют смешанный механизм.
источник
Во-первых, некоторые сходства, которые еще не были упомянуты. Ruby поддерживает открытые классы, но модули также открыты. В конце концов, Class наследует от Module в цепочке наследования Class, и поэтому Class и Module имеют похожее поведение.
Но вы должны спросить себя, какова цель наличия класса и модуля на языке программирования? Предполагается, что класс является планом для создания экземпляров, а каждый экземпляр представляет собой реализованный вариант плана. Экземпляр - это просто реализованная вариация проекта (Класса). Естественно, что классы функционируют как создание объектов. Кроме того, поскольку иногда мы хотим, чтобы один проект был получен из другого проекта, классы предназначены для поддержки наследования.
Модули не могут быть созданы, не создают объекты и не поддерживают наследование. Помните, что один модуль НЕ наследуется от другого!
Так в чем же смысл наличия модулей на языке? Одно из очевидных применений модулей - создание пространства имен, и вы заметите это и на других языках. Опять же, что хорошо в Ruby, так это то, что Модули можно открывать снова (так же, как Классы). И это большое использование, когда вы хотите повторно использовать пространство имен в разных файлах Ruby:
Но нет наследования между модулями:
Модуль Apple не наследовал никаких методов от модуля Green, и когда мы включили Apple в класс Fruit, методы модуля Apple были добавлены в цепочку предков экземпляров Apple, но не в методы модуля Green, хотя Green модуль был определен в модуле Apple.
Так как же нам получить доступ к зеленому методу? Вы должны явно включить его в свой класс:
Но у Ruby есть еще одно важное применение для модулей. Это средство Mixin, которое я опишу в другом ответе на SO. Подводя итог, можно сказать, что миксины позволяют определять методы в цепочке наследования объектов. С помощью миксинов вы можете добавлять методы в цепочку наследования экземпляров объектов (include) или singleton_class класса self (extension).
источник