2013-07-11 20 views
7

İç içe geçmiş bir modülü yeniden açmak, kullanılan sözdizimine bağlı olarak farklı sonuçlar veriyor?Ruby'de iç içe geçmiş modül anormalliği yeniden açıldı

module A 
    module E 
    end 
end 
module A 
    module E 
    def E.e 
    end 
    end 
end 

Ama bu: Örneğin, bu iyi çalışır birisi bu işaret Önce

reopen.rb:6:in `<module:E>': uninitialized constant A::E::E (NameError) 
from reopen.rb:5:in `<main>' 

(bir geçici çözüm olduğunu self kullanmak yerine, söz konusu:

module A 
    module E 
    end 
end 
module A::E 
    def E.e 
    end 
end 

hata veriyor Ee'yi tanımlarken modül adı, ancak bu yazının asıl konusu bu değil.)

+2

Peki, soru nedir? –

+0

Adil nokta - yeniden yazılmıştır. –

cevap

4

The module anahtar sözcüğü, Varolan Modül adlarına yapılan başvurular için kontrol edilen bir ad alanı bağlamı belirler. Bu ad alanları daha sonra Modül (ve Sınıf) adlarına yapılan başvuruları çözümlemek için içten dışa doğru aranır. Hem örneklerde ne olur

module A 
    module E 
    end 
end 
module A 
    def E.e 
    end 
end 

Yakut bakar olmalarıdır: module E bloğun içine E.e tanımlamak gerekebilir sevdiği İlk örnekte

, bu görünüyor, ama aslında değil mi Geçerli ad alanı ve bir modül adı olarak <namespace>::E çalışır. Yani her iki örnekte, kontrol ettiği ilk şey aslında mevcut olmayan A::E::E'dur. Sonra bir sonraki içeriğe geri düşer. Örneklerin farklı olduğu yer budur: İlk örnekte geçerli olan A::E, ikinci örnekte, sadece E değil. Daha sonra attığı hata, kontrol ettiği ilk adla ilgilidir.

+1

İlginç. IMO 'modülü A :: E' bir" yuvalanmış "adı ile yuvalanmamış bir bağlam yaratma bir hatadır. o eşdeğer olsaydı: 'A modül E ... Bu ad hakkında normale sezgi çok daha yakın olacağını söyleyebilirim' modülü. –

+0

Evet, her zaman 'modül' bloğu içinde tek bir bağlam oluşturur. Bu açıdan en azından kendi kendine tutarlıdır. Tarihsel sebepler dışında, başka bir yolla çalışmanın neden bir nedenini göremiyorum - mevcut davranışa dayanan bir kod bile olabilir - burada "E" ve "A :: E" nin her ikisi de tanımlanmıştır Örneğin. –

+0

Yeterince adil. Belki de bu konuyu gündeme getirmek, Ruby'nin gelecekteki bir versiyonuna girmesine neden olabilir. –

İlgili konular