2011-03-14 14 views
8

Sono molto confuso dal comportamento di Ruby quando si definiscono const_missing e altri metodi di classe all'interno di una definizione class << self rispetto alla sintassi def self.foo.Costante mancante e "const_missing" all'interno della definizione "classe << auto"

stavo cercando di fare qualcosa di simile:

class Foo 
    class << self 
    def foo 
     puts MISSING 
    end 

    def const_missing(name) 
     puts "#{name} missing" 
    end 
    end 
end 

Foo.foo 

Io uso soprattutto la sintassi class << self per definire metodi di classe. Tuttavia, non ha funzionato come previsto. const_missing non viene mai chiamato. Il risultato sopra è un NameError.

Definizione entrambi i metodi come questo funziona come previsto:

def self.foo 
    puts MISSING 
end 

def self.const_missing(name) 
    puts "#{name} missing" 
end 

ho pensato che la sintassi class << self è solo un altro modo per definire metodi di classe, ma completamente equivalente a def self.foo? Ho provato quanto sopra con MRI 1.8.7, 1.9.2 e JRuby 1.5.6. Quindi ovviamente mi manca qualcosa qui?

Qualsiasi suggerimento è molto apprezzato.

Grazie, Martin

risposta

12

class << self non è una scorciatoia per definire metodi di classe. Questa sintassi (non conosco l'esatta denominazione) apre l'eigenclass da un oggetto (nel tuo caso, una classe). Con ciò è possibile definire metodi per l'oggetto (non i metodi di istanza). Ma quando chiami una costante nell'eigenclass, stai chiamando una costante dall'eigenclass, non dalla classe. In questo caso è necessario definire un metodo della classe sulle eigenclass ai const_missing, due modi per farlo:

class Test 
    class << self 
    def foo 
     p MISSING 
    end 

    # First way: (syntax sugar for the second way) 
    def self.const_missing(name) 
     name 
    end 

    # Second way: 
    class << self # eigenclass of the eigenclass of the class 
     def const_missing(name) 
     name 
     end 
    end 

    end 
end 

Test.foo #=> :MISSING 
+0

Grazie mille, LBG. Sapevo che 'class << self' apre l'eigenclass di una classe. Ma poiché i metodi di classe sono solo dei metodi di esempio dell'eigenclass, pensavo che avrebbe funzionato in questo modo. Ha perfettamente senso, tuttavia, che una costante riferita all'eigenclass non è la stessa di una costante cui fa riferimento la classe stessa. A volte questa cosa mi fa girare la testa :) – martido

Problemi correlati