Quelle est la différence entre inclure et exiger dans Ruby?

465

Ma question est similaire à " Quelle est la différence entre inclure et étendre dans Ruby? ".

Quelle est la différence entre Ruby requireet includeRuby? Si je veux simplement utiliser les méthodes d'un module de ma classe, dois-je le requirefaire ou le includefaire?

Owen
la source
1
Pour ce que ça vaut la peine, voici des liens vers la documentation communautaire pour requireet include, et aussi pertinents, Module#append_features.

Réponses:

543

Quelle est la différence entre "inclure" et "exiger" dans Ruby?

Réponse:

Les méthodes include et require font des choses très différentes.

La méthode require fait ce qui inclut dans la plupart des autres langages de programmation: exécuter un autre fichier. Il suit également ce que vous avez demandé par le passé et ne nécessitera pas deux fois le même fichier. Pour exécuter un autre fichier sans cette fonctionnalité supplémentaire, vous pouvez utiliser la méthode de chargement.

La méthode include prend toutes les méthodes d'un autre module et les inclut dans le module actuel. C'est une chose au niveau de la langue par opposition à une chose au niveau du fichier comme avec require. La méthode include est le principal moyen d'étendre des classes avec d'autres modules (généralement appelés mix-ins). Par exemple, si votre classe définit la méthode "each", vous pouvez inclure le module mixin Enumerable et il peut agir comme une collection. Cela peut être déroutant car le verbe include est utilisé très différemment dans d'autres langues.

La source

Donc, si vous voulez simplement utiliser un module, plutôt que de l'étendre ou de faire un mixage, alors vous voudrez l'utiliser require.

Curieusement, Ruby requireest analogue à C de include, alors que Ruby includeest presque rien comme C de include.

HanClinto
la source
45
En fait, l'inclusion de C ne charge pas un fichier comme l'exige, mais remplace plutôt la ligne #include par le contenu du fichier. Les fichiers inclus ne doivent pas être «en-tête» et #include ne doit pas être au début du fichier mais peut être n'importe où, comme dans la classe ou même une définition de méthode. Cela signifie que vous pouvez faire du mixage en C ++ en écrivant quelques méthodes dans un fichier et l'inclure dans le code d'une classe, exactement comme vous le feriez en ruby. Ils ne sont donc pas si loin, même si ce n'est en effet pas une pratique courante dans les C.
mb14
13
Cette réponse pourrait bénéficier en incluant des exemples.
Travis Bear
12
Commentaire de MB14 implique, mais il porte indiquant explicitement: contrairement à ce que dit la réponse, ne nécessitent pas « run » un fichier, mais plutôt des charges comme si elle faisait partie du fichier contenant. Cela peut sembler être une piqûre sémantique, mais en fait, c'est une différence assez importante.
Lonny Eachus
Grande explication. Merci d'avoir enfoncé le clou avec la dernière déclaration: "Curieusement, l'exigence de Ruby est analogue à l'inclusion de C, tandis que l'inclusion de Ruby ne ressemble presque pas à l'inclusion de C."
ArtSabintsev
1
@GregSchmit: includedans Ruby, c'est simplement l'héritage. class C; include M endfait Mla superclasse de Cet la (ancienne) superclasse de Cla superclasse de M. Je ne pense pas que C includefonctionne via l'héritage, je pense que c'est une simple substitution textuelle / lexicale.
Jörg W Mittag
100

Si vous utilisez un module, cela signifie que vous apportez toutes les méthodes dans votre classe. Si vous extendune classe avec un module, cela signifie que vous "apportez" les méthodes du module en tant que méthodes de classe . Si vous includeune classe avec un module, cela signifie que vous "apportez" les méthodes du module en tant que méthodes d' instance .

EX:

 module A
   def say
     puts "this is module A"
   end
 end

 class B
   include A
 end

 class C
   extend A
 end

B.say => méthode non définie 'say' pour B: Class

B.new.say => c'est le module A

C.say => c'est le module A

C.new.say => méthode non définie 'say' pour C: Class

Peter Dang
la source
23
Je pense que cela ne répond pas à la question, mais c'est ce que je cherchais =)
Ciro Santilli 郝海东 冠状 病 六四 事件 法轮功
2
Cela ne répond pas réellement à la question de savoir quelles sont les différences entre requireet includesont.
94

Du livre Metaprogramming Ruby,

La require()méthode est assez similaire à load(), mais elle est destinée à un but différent. Vous utilisez load()pour exécuter du code et vous utilisez require()pour importer des bibliothèques.

Pratik Khadloya
la source
73
Votez pour ne pas avoir comparé à une autre langue dans votre réponse :)
Stevo
Votez contre pour ne pas avoir répondu dans le contexte de la question: "Si je veux juste utiliser les méthodes d'un module de ma classe?"
benc
57
  • Ruby requireressemble plus à «inclure» dans d'autres langages (comme C). Il indique à Ruby que vous souhaitez importer le contenu d'un autre fichier . Des mécanismes similaires dans d'autres langues sont:

  • Ruby includeest un mécanisme d'héritage orienté objet utilisé pour les mixins .

Il y a une bonne explication ici :

[La] réponse est simple: exiger et inclure sont essentiellement sans rapport.

"require" est similaire à l'inclusion C, ce qui peut créer de la confusion chez les débutants. (Une différence notable est que les sections locales dans le fichier requis "s'évaporent" lorsque la demande est effectuée.)

L' inclusion Ruby ne ressemble en rien à l'inclusion C. L'instruction include "mélange" un module dans une classe. C'est une forme limitée d'héritage multiple . Un module inclus confère littéralement une relation «est-un» à la chose qui l'inclut.

Je souligne.

Bradheintz
la source
7

Avez-vous déjà essayé requireun module? Quels ont été les résultats? Essayez simplement:

MyModule = Module.new
require MyModule # see what happens

Les modules ne peuvent pas être requis, seulement inclus!

Boris Stitnicky
la source
L'affirmation ici n'est pas correcte. Des modules peuvent être nécessaires. Et toute personne exécutant le code ci-dessus constatera qu'elle recevra le même résultat ( TypeError) si le mot Moduleest changé en Class.
pjd
7

De la programmation de Ruby 1.9

Nous allons faire quelques remarques sur la déclaration d'inclusion avant de continuer. Tout d'abord, cela n'a rien à voir avec les fichiers. Les programmeurs C utilisent une directive de préprocesseur appelée #include pour insérer le contenu d'un fichier dans un autre pendant la compilation. L'instruction Ruby include fait simplement référence à un module. Si ce module se trouve dans un fichier séparé, vous devez utiliser require (ou son cousin moins utilisé, load) pour faire glisser ce fichier avant d'utiliser include. Deuxièmement, une inclusion Ruby ne copie pas simplement les méthodes d'instance du module dans la classe. Au lieu de cela, il fait une référence de la classe au module inclus. Si plusieurs classes incluent ce module, elles pointeront toutes vers la même chose. Si vous modifiez la définition d'une méthode dans un module, même pendant l'exécution de votre programme,

cizixs
la source
3

Inclure Lorsque vous incluez un module dans votre classe comme indiqué ci-dessous, c'est comme si vous preniez le code défini dans le module et l'insérez dans la classe, où vous l'incluez. Il permet le comportement «mixin». Il est utilisé pour SECHER votre code pour éviter la duplication, par exemple, s'il y avait plusieurs classes qui auraient besoin du même code dans le module.

Charger La méthode de chargement est presque comme la méthode require, sauf qu'elle ne garde pas la trace du chargement ou non de cette bibliothèque. Il est donc possible de charger une bibliothèque plusieurs fois et également lorsque vous utilisez la méthode de chargement, vous devez spécifier l'extension «.rb» du nom du fichier de bibliothèque.

Require La méthode require vous permet de charger une bibliothèque et l'empêche d'être chargée plus d'une fois. La méthode require retournera 'false' si vous essayez de charger la même bibliothèque après la première fois. La méthode require ne doit être utilisée que si la bibliothèque que vous chargez est définie dans un fichier séparé, ce qui est généralement le cas.

Vous pouvez préférer ceci http://ionrails.com/2009/09/19/ruby_require-vs-load-vs-include-vs-extend/

Sanket
la source
3

Voici quelques différences de base entre exiger et inclure:

Exiger:

  1. Exiger lit le fichier à partir du système de fichiers, l'analyse, l'enregistre dans la mémoire et l'exécute à un endroit donné, ce qui signifie que si vous changez quoi que ce soit pendant que le script est en cours d'exécution, ce changement ne se reflétera pas.
  2. Nous avons besoin d'un fichier par nom, pas par nom de module.
  3. Il est généralement utilisé pour les bibliothèques et les extensions.

Comprendre:

  1. Lorsque vous incluez un module dans votre classe, il se comporte comme si vous preniez le code défini dans votre module et l'insérez dans votre classe.
  2. Nous incluons le nom du module, pas le nom du fichier.
  3. Il est généralement utilisé pour assécher le code et supprimer la duplication dans le code.
Awais Shafqat
la source
2
require(name)

Il retournera bolean true / false

Le nom qui est passé en paramètre à require, ruby ​​essaiera de trouver le fichier source avec ce nom dans votre chemin de chargement. La méthode require retournera 'false' si vous essayez de charger la même bibliothèque après la première fois. La méthode require ne doit être utilisée que si la bibliothèque que vous chargez est définie dans un fichier séparé. Il garde donc la trace du fait que cette bibliothèque a déjà été chargée ou non.

include module_name

Supposons que vous ayez des méthodes à avoir dans deux classes différentes. Ensuite, vous n'avez pas à les écrire dans les deux classes. Au lieu de cela, vous pouvez le définir dans le module. Et puis inclure ce module dans d'autres classes. Il est fourni par Ruby juste pour assurer le principe DRY. Il est utilisé pour sécher votre code pour éviter la duplication

Shrinivas
la source
2

Comprendre

Lorsque vous includeinsérez un module dans votre classe, c'est comme si vous preniez le code défini dans le module et l'insérez dans la classe, où vous l'incluez. Il permet le comportement «mixin». Il est utilisé pour sécher votre code pour éviter la duplication, par exemple, s'il y avait plusieurs classes qui auraient besoin du même code dans le module.

module Log 
  def class_type
    "This class is of type: #{self.class}"
  end
end

class TestClass 
  include Log 
  # ... 
end

tc = TestClass.new.class_type # -> success
tc = TestClass.class_type # -> error

Exiger

La méthode require vous permet de charger une bibliothèque et empêche son chargement plusieurs fois. La méthode require retournera 'false' si vous essayez de charger la même bibliothèque après la première fois. La méthode require ne doit être utilisée que si la bibliothèque que vous chargez est définie dans un fichier séparé, ce qui est généralement le cas.

Il garde donc la trace du fait que cette bibliothèque a déjà été chargée ou non. Vous n'avez pas non plus besoin de spécifier l'extension «.rb» du nom du fichier de bibliothèque. Voici un exemple d'utilisation de require. Placez la méthode require tout en haut de votre fichier «.rb»:

Charge

La méthode de chargement est presque comme la méthode require, sauf qu'elle ne garde pas la trace du chargement ou non de cette bibliothèque. Il est donc possible de charger une bibliothèque plusieurs fois et également lorsque vous utilisez la méthode de chargement, vous devez spécifier l'extension «.rb» du nom de fichier de la bibliothèque.

Étendre

Lorsque vous utilisez la méthode extend au lieu d'inclure, vous ajoutez les méthodes du module en tant que méthodes de classe plutôt qu'en tant que méthodes d'instance.

module Log 
  def class_type
    "This class is of type: #{self.class}"
  end
end

class TestClass 
  extend Log 
  # ... 
end

tc = TestClass.class_type
Imran Ahmad
la source
2

'Charger' - insère le contenu d'un fichier (analyser le fichier à chaque appel du fichier)

'Require' - insère un fichier analysé le contenu (fichier analysé une fois et stocké en mémoire)

'Inclure' - inclut le module dans la classe et peut utiliser des méthodes à l'intérieur du module comme méthode d'instance de la classe

«Étendre» - inclut le module dans la classe et peut utiliser des méthodes à l'intérieur du module comme méthode de classe

Vaishali Venkatesan
la source