From: "Aleksi Niemelä" Date: 2000-07-05T20:14:34+02:00 Subject: [ruby-talk:03846] Private variables can be changed outside? Now I managed to drive myself almost insane. I thought private variables could not be changed outside class. Anyway, the source code below does change. The important routine is hopefully clearly marked: def change_object_burp_or_fish_burp_outside_fish(text="") @burp = "surprise" + text end The '@burp' could have different 'self' depending where it has been called from. When you call it directly from the top level the @burp is an instance variable of the object main (which prints in debugger #). When it's called from Fish#change_from_outside, self is referring to an object #. I don't know what to think. I think it's natural which object's @burp we're accessing. But it's not natural we can access a private variable (of our child class). If there's no bug in here, this opens up a huge hole. As every class descents from Object, every class *can* access every other's instance variables! This is accomplished by 1) creating a method Object#spy, which access the wanted instance variable 2) a method Class#spy, to the class we wanted to inspect, which caals just created Object#spy 3) and then by firing a call to Class#spy, which in turn calls Object#spy with proper 'self', pointing to Class-object. So we can mess whatever object we want to. Now, if somebody just provides a method to ask object's instance variables :P. - Aleksi Ps. taking out the comment before 'private' didn't change the run on Ruby 1.4.5. class Fish # private @burp public def initialize( burp ="blop" ) @burp = burp end def internal_burp puts "Fish says '#{@burp}'" end def change_from_outside change_object_burp_or_fish_burp_outside_fish end end @burp = "burp" def main_burp puts "Object says '#{@burp}'" end def change_object_burp_or_fish_burp_outside_fish(text="") @burp = "surprise" + text end #### fish = Fish.new fish.internal_burp main_burp puts "\nNow we call fish to change itself" fish.change_from_outside fish.internal_burp main_burp puts "\nNow we call self to change ourselves" change_object_burp_or_fish_burp_outside_fish(" again") fish.internal_burp main_burp ################# Outputs: Fish says 'blop' Object says 'burp' Now we call fish to change itself Fish says 'surprise' Object says 'burp' Now we call self to change ourselves Fish says 'surprise' Object says 'surprise again'