2015-12-17 5 views
5

Sono rimasto bloccato su questo per un po '. Prendete questa base:Perché Ruby non trova le classi in uno scope più elevato quando il modulo viene specificato usando ::?

module Top 
    class Test 
    end 

    module Foo 
    end 
end 

Più tardi, posso definire le classi all'interno Foo che si estende Test in questo modo:

module Top 
    module Foo 
    class SomeTest < Test 
    end 
    end 
end 

Tuttavia, se cerco di ridurre al minimo il rientro utilizzando :: per specificare il modulo:

module Top::Foo 
    class Failure < Test 
    end 
end 

questo viene a mancare con:

NameError: uninitialized constant Top::Foo::Test

Si tratta di un bug o è solo una conseguenza logica del modo in cui Ruby risolve i nomi delle variabili?

risposta

7

Is this a bug, or is it just a logical consequence

E 'un "capriccio". Alcuni lo considerano un bug.

Gli ambiti padre utilizzati per cercare le costanti non risolte sono determinati dall'annidamento dei moduli. Accade solo che quando usi module Top::Foo, crei solo un livello di nidificazione invece di due. Osservare:

module Top 
    module Foo 
    class SomeTest 
     Module.nesting # => [Top::Foo::SomeTest, Top::Foo, Top] 
    end 
    end 
end 

module Top::Foo 
    class SomeTest 
    Module.nesting # => [Top::Foo::SomeTest, Top::Foo] 
    end 
end 
+2

suona come un bug a me: P Ma la risposta molto informativo, grazie – Hubro

+0

direi Lo considero un bug, qualcuno ha trovato un bug report in Ruby su questo? Mi piacerebbe contribuire alla discussione e dare un'occhiata a cosa sarebbe coinvolto nel risolvere questo problema. –

+0

Nota: trovato un link che indica che è intenzionale [qui] (https://bugs.ruby-lang.org/issues/11705) –

1

Questo è previsto. L'utilizzo di :: modifica l'ambito della ricerca costante e prevede che Test sia definito in Top::Foo.

per ottenere il risultato previsto, si potrebbe scrivere:

module Top::Foo 
    class SomeTest < Top::Test 
    end 
end 

o:

module Top 
    class Foo::SomeTest < Test 
    end 
end 

o anche:

class Top::Foo::SomeTest < Top::Test 
end 
Problemi correlati