Domanda

Sono venuto da Java e ora sto lavorando di più con Ruby.

Una caratteristica della lingua che non conosco è il module . Mi chiedo che cosa sia esattamente un modulo e quando ne usi uno, e perché usare un modulo su una classe ?

È stato utile?

Soluzione

La prima risposta è buona e fornisce alcune risposte strutturali, ma un altro approccio è quello di pensare a quello che stai facendo. I moduli riguardano la fornitura di metodi che puoi utilizzare in più classi: pensali come " librerie " (come vedresti in un'app Rails). Le lezioni riguardano gli oggetti; i moduli riguardano le funzioni.

Ad esempio, i sistemi di autenticazione e autorizzazione sono buoni esempi di moduli. I sistemi di autenticazione funzionano su più classi a livello di app (gli utenti sono autenticati, le sessioni gestiscono l'autenticazione, molte altre classi agiranno in modo diverso in base allo stato di autenticazione), quindi i sistemi di autenticazione agiscono come API condivise.

Puoi anche usare un modulo quando hai metodi condivisi su più app (di nuovo, qui il modello di libreria è buono).

Altri suggerimenti

╔═══════════════╦═══════════════════════════╦═════════════════════════════════╗
║               ║ 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)          ║
╚═══════════════╩═══════════════════════════╩═════════════════════════════════╝

Sono sorpreso che nessuno l'abbia ancora detto.

Poiché il richiedente proviene da un background Java (e anche io), ecco un'analogia che aiuta.

Le classi sono semplicemente come le classi Java.

I moduli sono come le classi statiche Java. Pensa alla classe Math in Java. Non lo installi e riutilizzi i metodi nella classe statica (ad es. Math.random () ).

Fondamentalmente, il modulo non può essere istanziato. Quando una classe include un modulo, viene generata una superclasse proxy che fornisce l'accesso a tutti i metodi del modulo e ai metodi della classe.

Un modulo può essere incluso da più classi. I moduli non possono essere ereditati, ma questo "mixin" Il modello fornisce un tipo utile di "ereditarietà multipla". I puristi di OO non saranno d'accordo con questa affermazione, ma non lasciare che la purezza ostacoli il lavoro.


(Questa risposta originariamente era collegata a http://www.rubycentral.com/pickaxe/classes.html , ma quel link e il suo dominio non sono più attivi.)

Modulo in Ruby, in una certa misura, corrisponde a Java classe astratta - ha metodi di istanza, le classi possono ereditare da esso (tramite include , I ragazzi di Ruby lo chiamano "mixin", ma non ha istanze. Ci sono altre differenze minori, ma queste informazioni sono sufficienti per iniziare.

namespace: i moduli sono namespace ... che non esistono in java;)

Sono passato anche da Java e Python a Ruby, ricordo che aveva esattamente la stessa domanda ...

Quindi la risposta più semplice è che il modulo è uno spazio dei nomi, che non esiste in Java. In java la mentalità più vicina allo spazio dei nomi è un pacchetto .

Quindi un modulo in ruby ??è come quello di java:
classe? No
interfaccia? No
classe astratta? No
pacchetto? Sì (forse)

metodi statici all'interno delle classi in java: uguale ai metodi all'interno dei moduli in ruby ??

In java l'unità minima è una classe, non puoi avere una funzione al di fuori di una classe. Tuttavia nel rubino questo è possibile (come il pitone).

Quindi cosa succede in un modulo?
classi, metodi, costanti. Il modulo li protegge in quello spazio dei nomi.

Nessuna istanza: i moduli non possono essere utilizzati per creare istanze

Informazioni contrastanti: a volte i modelli di ereditarietà non vanno bene per le classi, ma in termini di funzionalità vogliono raggruppare un insieme di classi / metodi / costanti

Regole sui moduli in ruby:
- I nomi dei moduli sono UpperCamelCase
- le costanti all'interno dei moduli sono TUTTE MAIUSCOLE (questa regola è la stessa per tutte le costanti ruby, non specifiche per i moduli)
- metodi di accesso: usare. operatore
- Costanti di accesso: usa :: simbolo

semplice esempio di un modulo:

module MySampleModule
  CONST1 = "some constant"

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

come utilizzare i metodi all'interno di un modulo:

puts MySampleModule.method_one(1) # prints: 3

come usare le costanti di un modulo:

puts MySampleModule::CONST1 # prints: some constant

Alcune altre convenzioni sui moduli:
Usa un modulo in un file (come le classi ruby, una classe per file ruby)

Linea di fondo: un modulo è un incrocio tra una classe statica / di utilità e un mixin.

I mixin sono pezzi riutilizzabili di "parziale" implementazione, che può essere combinata (o composta) in un mix & amp; abbinare la moda, per aiutare a scrivere nuove lezioni. Queste classi possono inoltre avere il proprio stato e / o codice, ovviamente.

Classe

Quando si definisce una classe, si definisce un modello per un tipo di dati.  i dati di conservazione della classe, hanno un metodo che interagisce con tali dati e vengono utilizzati per creare un'istanza di oggetti.

modulo

  • I moduli sono un modo per raggruppare metodi, classi e costanti.

  • I moduli offrono due vantaggi principali:

    = > I moduli forniscono uno spazio dei nomi e prevengono gli scontri tra nomi. Lo spazio dei nomi aiuta a evitare conflitti con funzioni e classi con lo stesso nome che sono state scritte da qualcun altro.

    = > I moduli implementano la funzione di mixin.

  

(incluso il modulo in Klazz fornisce alle istanze di accesso Klazz al modulo   metodi. )

     

(estendi Klazz con Mod dando alla classe Klazz l'accesso ai metodi Mods.)

Innanzitutto, alcune somiglianze che non sono ancora state menzionate. Ruby supporta classi aperte, ma anche moduli aperti. Dopotutto, Class eredita da Module nella catena di ereditarietà di Class e quindi Class e Module hanno un comportamento simile.

Ma devi chiederti qual è lo scopo di avere sia una classe che un modulo in un linguaggio di programmazione? Una classe deve essere un modello per la creazione di istanze e ogni istanza è una variante realizzata del modello. Un'istanza è solo una variante realizzata di un progetto (la Classe). Naturalmente, quindi, le classi funzionano come creazione di oggetti. Inoltre, poiché a volte desideriamo che un progetto derivi da un altro progetto, le Classi sono progettate per supportare l'ereditarietà.

I moduli non possono essere istanziati, non creano oggetti e non supportano l'ereditarietà. Quindi ricorda che un modulo NON eredita da un altro!

Allora, qual è il punto di avere moduli in una lingua? Un ovvio utilizzo dei moduli è quello di creare uno spazio dei nomi, e lo noterai anche con altre lingue. Ancora una volta, il bello di Ruby è che i moduli possono essere riaperti (proprio come le classi). E questo è un grande uso quando vuoi riutilizzare uno spazio dei nomi in diversi file 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

Ma non c'è ereditarietà tra i moduli:

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>

Il modulo Apple non ha ereditato alcun metodo dal modulo Green e quando abbiamo incluso Apple nella classe Fruit, i metodi del modulo Apple vengono aggiunti alla catena di antenati delle istanze Apple, ma non anche i metodi del modulo Green sebbene il modulo verde sia stato definito nel modulo Apple.

Quindi, come possiamo accedere al metodo verde? Devi includerlo esplicitamente nella tua classe:

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

Ma Ruby ha un altro uso importante per i moduli. Questa è la funzione Mixin, che descrivo in un'altra risposta su SO. Riassumendo, i mixin consentono di definire metodi nella catena di ereditarietà degli oggetti. Tramite i mixin, è possibile aggiungere metodi alla catena di ereditarietà delle istanze di oggetti (include) o alla classe_ singleton di self (estensione).

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top