From: Stefano Crocco Date: 2007-11-24T19:24:50+09:00 Subject: Re: Access modifier : private Alle sabato 24 novembre 2007, Dharmarth Shah ha scritto: > Hi! > > I'm missing some core ruby concept here that I just can't figure out; > any assistance would be excellent and welcome: > > I came to know from various posts that Class level varibales are > shared among its subclasses in 1.8. > > But my confusion is, even though i mark it as private, it is > accessible in subclass. See example below for more clarity on doubt. > > class Test1 > private > @@v=10 > end > > class Test2 < Test1 > def pr > @@v=12 > puts @@v > end > end > > Test2.new.pr > > ~Dharmarth > -- > "When I let go of what I am, I become what I might be." First of all, private only works for instance methods, not for variables, either instance variables or class variables, which are always private. Second, the meaning of "private" in ruby is different from what you have in other languages such as C++. In ruby, "private" only means you can't call it with a receiver (i.e, using the form receiver.method). This means that a method declared private in a class can be called in a subclass. The same is true for instance variables (writing rec.@var gives a syntax error, which is the reason instance variables are always private). Here are some examples: class A def initialize @x=1 end def m1 puts "m1 calling m" m end def m2 puts "m2 calling self.m" self.m end def m3 other puts "m3 calling m on other instance of class A" other.m end private def m puts "m" end end class B < A def mb1 puts "@x is: #{@x}" end def mb2 puts "mb2 calling m" m end end After loading the previous code in IRB (from the file test_private.rb), I run the methods defined for A and B, with the following results: irb(main):001:0> require 'test_private' => true irb(main):002:0> a = A.new => # irb(main):003:0> a.m1 m1 calling m m => nil irb(main):004:0> a.m2 m2 calling self.m NoMethodError: private method `m' called for # from ./prova.rb:14:in `m2' from (irb):4 irb(main):005:0> a.m3 A.new m3 calling m on other instance of class A NoMethodError: private method `m' called for # from ./prova.rb:19:in `m3' from (irb):6 irb(main):006:0> b = B.new => # irb(main):007:0> b.mb1 @x is: 1 => nil irb(main):008:0> b.mb2 mb2 calling m m => nil A#m1, obviously, works. A#m2 doesn't work because it calls m using a receiver, which is forbidden (even when the receiver is the implicit receiver, self). A#m3 doesn't work because it calls m with a receiver (even if of the same class as self). B#bm1 works, because the instance variable is called without a receiver. B#mb2 works, because it's calling the method without the receiver. The fact that the method is private doesn't matter. I hope this helps Stefano