Şaşırtıcı bir şekilde, buradaki 10 cevabın hepsi aynı şeyi söylüyor. '::' bir ad alanı çözünürlük operatörüdür ve evet doğrudur. Ancak, sabit arama algoritması söz konusu olduğunda, ad alanı çözünürlük operatörü hakkında fark etmeniz gereken bir şey var . Matz 'Ruby Programlama Dili' adlı kitabında betimlediği gibi, sürekli aramanın birden fazla adımı vardır. İlk olarak, söz konusu sabitin atıfta bulunduğu sözcüksel kapsamda bir sabiti arar . Sabit noktayı sözlük kapsamı içinde bulamazsa, kalıtım hiyerarşisini arar . Bu sürekli arama algoritması nedeniyle, aşağıda beklenen sonuçları elde ediyoruz:
module A
module B
PI = 3.14
module C
class E
PI = 3.15
end
class F < E
def get_pi
puts PI
end
end
end
end
end
f = A::B::C::F.new
f.get_pi
> 3.14
F, E'den miras alırken, B modülü F'nin sözcüksel kapsamı içindedir. Sonuç olarak, F örnekleri B modülünde tanımlanan sabit PI'ye atıfta bulunacaktır. Şimdi B modülü PI tanımlamıyorsa, F örnekleri PI'ye atıfta bulunacaktır. E üst sınıfında tanımlanan sabit.
Peki ya modül yerleştirme yerine '::' kullanacaksak? Aynı sonucu alır mıydık? Hayır!
Yuvalanmış modülleri tanımlarken ad alanı çözümleme işlecini kullanarak, yuvalanmış modüller ve sınıflar artık dış modüllerinin sözcüksel kapsamı içinde değildir. Aşağıda görebileceğiniz gibi, A :: B'de tanımlanan PI A :: B :: C :: D'nin sözcüksel kapsamı içinde değildir ve bu nedenle get_pi örnek yönteminde PI'ye başvurmaya çalışırken başlatılmamış sabit alırız:
module A
end
module A::B
PI = 3.14
end
module A::B::C
class D
def get_pi
puts PI
end
end
end
d = A::B::C::D.new
d.get_pi
NameError: uninitialized constant A::B::C::D::PI
Did you mean? A::B::PI