2010-07-24 19 views
2

Je me demande, pourquoi les méthodes d'un module inclus dans les définitions de classe ultérieures (comme si la classe l'incluait en soi)?héritage étrange dans ruby ​​mixins

module Foo 
    def bar 
    print "#{self}\n" 
    end 
end 

class Bar 
end 

begin 
    Bar.bar 
rescue NoMethodError 
    puts "There is no Bar.bar\n" 
end 

include Foo 

bar 
Bar.bar 
Bar.new.bar

impressions:

 
There is no Bar.bar 
main 
Bar 
#<Bar:0xb73f2048> 

Est-ce le comportement attendu? Pourquoi?

+0

Qu'attendiez-vous? –

Répondre

2

Lorsque vous incluez Foo dans votre programme mais en dehors de toute classe ou méthode, il est inclus dans la portée actuelle qui est l'objet main.

Vous pouvez tester cela en modifiant votre méthode de barre à la suite

def bar 
    print "InBar class: #{self.class} value: #{self}\n" 
    end 

Et puis en ajoutant les 2 lignes suivantes à la fin

2.bar 
Fixnum.bar 

Cela vous donne la sortie suivante

There is no Bar.bar 
InBar class: Object value: main 
InBar class: Class value: Bar 
InBar class: Bar value: #<Bar:0x21ecec> 
InBar class: Fixnum value: 2 
InBar class: Class value: Fixnum 
+0

'main' n'est en fait pas une classe c'est un objet. En tant que tel, «include» ne devrait pas (strictement) être disponible au niveau supérieur. Néanmoins, 'include 'est disponible sous forme de cas particulier (méthode de commodité) mais son comportement consiste à mélanger le module dans' Object' – horseyguy

+0

@banister. Merci doigts plus vite que le cerveau. Edité de manière appropriée –

2

un include au niveau supérieur mélange le module en Object. Dans la mesure où il est mélangé en Object, il est disponible en tant que méthode d'instance sur tout.