2012-07-24 11 views
6

Ruby'de, anlamıyorum, herhangi bir çıplak yöntem çağrısı için self ima edilen alıcıdır. Ancak:Eğer `self` her zaman Ruby'de ima edilen alıcıysa, neden self.puts çalışmıyor?

~: irb 
>> puts "foo" 
foo 
=> nil 
>> self.puts "foo" 
NoMethodError: private method `puts' called for main:Object 

Bunu açıklayan nedir? self açıkça birini belirtmeyen zımni alıcı olduğunu

>> method(:puts).owner 
=> Kernel 
+1

Denemeyi deneyin self.send: "foo" koyar. Gönder ile özel yöntemlere ulaşabilirsiniz. – DGM

cevap

8

Özel yöntemler cevabı şudur bir alıcı

Bence olamaz.

Bir örnek: hiçbir açık alıcısını olamaz yana

class Baker 
    def bake_cake 
    make_batter 
    self.use_oven # will explode: called with explicit receiver 'self' 
    end 

    private 
    def make_batter 
    puts "making batter!" 
    end 

    def use_oven 
    puts "using oven!" 
    end 

end 

b = Baker.new 
b.bake_cake 

, kesinlikle b.use_oven yapamaz. Ve yöntem gizliliği nasıl uygulanır.

+0

ama koyar kamu yöntemidir, yöntem (: koyar) .owner.public_methods.grep/koyar/döndürür [: koyar]. MRI ruby ​​1.93p194 – dfang

+0

Üzgünüm method yöntem aramayı unuttum. self.class.ancestors => [Object, Kernel, BasicObject] – dfang

+0

@dfang - belki bir çocuk dersi tarafından gizli olarak yeniden sınıflandırılır? Özel durumu göstermek için –

3

Doğru konum:

durumda herhangi bir yardım bu. self.puts yapmanıza izin verilmemesinin nedeni, açık bir alıcıya sahip özel yöntemleri (bu alıcı self olsa bile) arayaamayacağınız ve hata mesajının belirttiği gibi, puts özel bir yöntemdir.

1

self. söz dizimini kullanarak veya genellikle herhangi bir alıcı (.'un önündeki bir şeyle) kullanarak konuşarak özel yöntemlere erişemezsiniz. Bu sadece korunan yöntemler için mümkündür. yöntem gizlilik zorlamayı Ruby'nin yolu açık seçik bir alıcı özel yöntemleri çağırmadan izin vermez şudur:

4

Bu Ruby'deki gizlilik tanımıdır: özel yöntemler yalnızca örtülü bir alıcıyla çağrılabilir.

Aslında bu kuralın bir istisnası var: foo = barhep yerel bir değişken oluşturur çünkü aksi takdirde tüm onları çağırmak mümkün olmaz, çünkü olmadan (self.foo = bar gibi özel ayarlayıcıları çağırmak için izin verilir yansımayı kullanarak).

+1

+1. –

+0

Yansımanın yanı sıra 'self' kullanmadan foo = (bar)' yapabilirsiniz. –

+1

@AndrewGrimm: Çalışmıyor, sadece denedim. Aynı zamanda işe yaramazsa da mantıklıdır, çünkü parantezler ifade gruplaması için kullanılabilir, bu yüzden de mükemmel bir yerel değişken atamasıdır. –

İlgili konular