2010-07-30 7 views
3

Comment puis-je implémenter le '< <' pour avoir le même comportement lorsqu'il est utilisé comme méthode chaînable?Ruby chainable method/array

class Test 
    attr_accessor :internal_array 

    def initialize 
    @internal_array = [] 
    end 

    def <<(item) 
    @internal_array << :a 
    @internal_array << item 
    end 
end 

t = Test.new 
t << 1 
t << 2 
t << 3 
#t.internal_array => [:a, 1, :a, 2, :a, 3] 
puts "#{t.internal_array}" # => a1a2a3 

t = Test.new 
t << 1 << 2 << 3 
#t.internal_array => [:a, 1, 2, 3] 
puts "#{t.internal_array}" # => a123 , Why not a1a2a3? 

Je souhaite que les deux cas donnent le même résultat.

Répondre

4

Ajoutez self comme dernière ligne de la méthode < < pour le renvoyer. En l'état, vous renvoyez implicitement le tableau, pas l'instance.

0

Explication de la réponse ci-dessus:

Lorsqu'une méthode est enchaînée, la méthode suivante est appliquée à la suite de la première méthode.

Pour exemplo:

class A 
    def method1 
    B.new 
    end 
end 

class B 
    def method2 
    C.new 
    end 
end 

class C 
    def method3 
    puts "It is working!!!" 
    end 
end 

Le code ci-dessous fonctionnera

A.new.method1.method2.method3 

mais ce ne sera pas

A.new.method1.method3.method2 

car une instance de la classe B, ce qui est le résultat de A.new.method1 n'implémente pas la méthode3. C'est le même de:

(((A.new).method1).method3).method2 

Le code utilisé dans la question ci-dessus, était un peu plus d'un tour, parce que les deux, Test et Array avaient la méthode < <. Mais je veux le test # < < pour retourner moi-même, et pas le @internal_array qui était retourné.

+0

Est-ce censé être une réponse à votre question? Je suis confus. – Chuck

+0

C'est l'explication de la réponse ci-dessus. La réponse courte a été donnée par Matthew: ajoutez-vous au ... – Portela