2016-04-27 13 views
5

Sto provando ad accedere a una costante contenuta in varie classi in un modulo che sto includendo in esse. Come un esempio di baseRuby: Come accedere a una costante dalla classe un modulo è incluso in

module foo 
    def do_something_to_const 
    CONSTANT.each { ... do_something ... } 
    end 
end 

class bar 
    include foo 

    CONSTANT = %w(I want to be able to access this in foo) 
end 

class baz 
    include foo 

    CONSTANT = %w(A different constant to access) 
end 

quanto la logica per il modulo viene condiviso tra più classi mi piacerebbe essere in grado di fare riferimento solo alla costante (il cui nome rimane lo stesso in ogni classe, ma il contenuto variare). Come potrei andare in giro facendo questo?

risposta

3

È possibile fare riferimento al modulo di classe di essere incluso in quanto self.class e l'uso const_get o semplicemente self.class::CONST, con quest'ultimo è leggermente più veloce:

module M 
    def foo 
    self.class::CONST 
    end 
end 

class A 
    CONST = "AAAA" 
    include M 
end 

class B 
    CONST = "BBBB" 
    include M 
end 

puts A.new.foo # => AAAA 
puts B.new.foo # => BBBB 
+1

Grazie a @Vasfed è esattamente quello che stavamo cercando –

+0

Non è necessario utilizzare il riflesso. Puoi anche usare 'self.class :: CONST' senza riflettere. –

+0

@ JörgWMittag hai ragione, ed è circa il 2-9% più veloce, risposta aggiornata – Vasfed

0

È possibile utilizzare l'operatore :: nell'ambito CONSTANT nella classe BAR. La sintassi sarebbe simile a questa:

module Foo 
    def do_something_to_const 
    Bar::CONSTANT.each { |item| puts item } 
    end 
end 

class Bar 
    include Foo 

    CONSTANT = %w(I want to be able to access this in foo) 
end 

Bar.new.do_something_to_const # outputs each item in Bar::CONSTANT 

Vorrei provare a evitare questo, tuttavia. Il modulo incluso non dovrebbe aver bisogno di conoscere i dettagli di implementazione della classe per cui è inclusa.

+0

Il problema qui è come menzioni, il modulo non dovrebbe conoscere l'implementazione per quello che è incluso. Sto usando lo stesso modulo su molte classi e come tale non potrei farlo in questo modo. Estenderò l'esempio di codice originale per renderlo chiaro. –

1

è possibile fare riferimento alla classe con self.class

module Foo 
    def do_something 
    self.class::Constant.each {|x| puts x} 
    end 
end 

class Bar 
    include Foo 
    Constant = %w(Now is the time for all good men) 
end 

class Baz 
    include Foo 
    Constant = %w(to come to the aid of their country) 
end 

bar = Bar.new 
bar.do_something 
=> 
Now 
is 
the 
time 
for 
all 
good 
men 
=> ["Now", "is", "the", "time", "for", "all", "good", "men"] 

baz = Baz.new 
baz.do_something 
=> 
to 
come 
to 
the 
aid 
of 
their 
country 
=> ["to", "come", "to", "the", "aid", "of", "their", "country"] 
Problemi correlati