2012-05-27 7 views
5

Sto provando a mischiare un modulo in una classe e voglio che alcuni dei metodi si comportino come metodi di classe e altri come metodi di istanza.classe << notazione nei moduli

Tuttavia, io non voglio sia includeeextend il modulo. Preferirei semplicemente lo include.

Quando ho avvolgere i metodi che voglio essere metodi di classe in questa notazione, funziona:

class << 
    # ... 
end 

Tuttavia, quando uso questa notazione non funziona:

class << self 
    # ... 
end 

I sospetto che la parola chiave self stabilisca un binding esplicito per il modulo, piuttosto che la classe in cui viene mescolato. Ma non ho visto alcuna documentazione che consiglia di disattivare la parola chiave self quando si utilizza la notazione class <<.

Qualcuno sa cosa sta succedendo con questo?


UPDATE: Ecco alcuni esempi di codice per maggiore chiarezza:

module M 
    class << 
    def class_method 
     puts "From inside the class_method" 
    end 
    end 

    def instance_method 
    puts "From inside the instance_method" 
    end 
end 

class Object 
    include M 
end 

class C 
end 


C.class_method 

obj = C.new 
obj.instance_method 
+1

Huh, mi sono perso qualcosa? 'class << end' è un errore di sintassi. – sepp2k

risposta

6

class << deve essere sempre seguita da un oggetto. Solo class <<; end è un errore di sintassi. Nel tuo caso sembra che funziona a causa dei seguenti:

class << 
    def class_method 
    puts "From inside the class_method" 
    end 
end 

è lo stesso di

class << def class_method 
    puts "From inside the class_method" 
    end 
end 

, che è lo stesso di

temp = def class_method 
    puts "From inside the class_method" 
end 
class << temp 
end 

, che è lo stesso di

def class_method 
    puts "From inside the class_method" 
end 
class << nil 
end 

che è t lui stesso come

def class_method 
    puts "From inside the class_method" 
end 

Ovviamente questo non definisce un metodo di classe. Definisce un metodo di istanza.

+0

Lol. Questo spiega perché il metodo di classe "apparente" doveva essere in Object per funzionare. In realtà era un metodo di istanza singleton. Bel lavoro. – Nathan

0

Sì, se si vuole ottenere un vero e proprio self nel modulo si dovrebbe usare includedcallback. Qualcosa di simile si punto nella giusta direzione:

module Bar 
    def self.included(base) 
    class << base 
     def class_method 
     "class_method" 
     end 
    end 
    end 
end 

class Foo 
    include Bar 
end 


p Foo.class_method # => "class_method" 
+0

Credo che questo sia ciò che vuole effettivamente risolvere il suo problema, ma non risponde alla domanda reale di ciò che 'class' 'sta facendo rispetto a' class << self'. –

+0

come @ sepp2k ha detto che 'class << end' è un errore di sintassi. Quindi in realtà non so cosa voglia dire Nathan :( –

+0

Grazie nash, conosco il metodo incluso, ma ho scoperto che lasciare il sé sembra avere un effetto simile. Non sto ottenendo un errore di sintassi, e ho provato ruby 1.8 e 1.9.3 - Inserirò un campione completo di codice in un po 'per altri utenti da provare. – Nathan