Hi All Now another hitch: 1 class Person 2 attr_reader :genre, :style 3 protected :genre 4 private :to_s 5 def psedonym 6 @name 7 end 8 9 def to_s 10 "just another person" 11 end 12 #private :to_s 13 end 14 15 p= Person.new 16 puts p 17 puts "********" 18 puts p.to_s +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ CASE I With the above class the output comes out to be: >ruby yet.rb just another person ******** just another person CASE II Now when I comment Line 4 and Uncomment Line 12, the output comes to be: >ruby yet.rb just another person ******** yet.rb:18: private method `to_s' called for just another person:Person (NoMethodError) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ THE HITCH In first case it appears that that private declaration had no effect, thus the textual position matters here; If this is really so, can anyone explain why?? AND In second case why the private declaration had no effect on puts p when in fact (this is what i infer) it uses the same method which puts p.to_s uses. Can anyone Explain this bias??? Thanks Raja
on 2007-06-01 12:33
on 2007-06-01 14:00
On 6/1/07, Vin Raja <firstname.lastname@example.org> wrote: > THE HITCH > > In first case it appears that that private declaration had no effect, > thus the textual position matters here; If this is really so, can anyone > explain why?? Note first that private is not a declaration. It is a method call. In your case, note that to_s is actually defined on Object already. In case 1, the to_s inherited from Object is turned private, then gets overridden. When you override it, it is no longer private. In case 2, you override to_s first and then make it private, leaving it private. Keep in mind that this happens because you are overriding an existing method! You would get different behaviour if it wasn't an existing method Play around in irb more :) > > AND > > In second case why the private declaration had no effect on > puts p > when in fact (this is what i infer) it uses the same method which > puts p.to_s > uses. p doesn't call to_s. If you look at the docs, it actually calls Object#inspect which then uses to_s -> which is OK, because they are methods on the same object! Kernel.p docs: http://corelib.rubyonrails.org/classes/Kernel.html#M002080
on 2007-06-01 14:59
On 2007-06-01 19:33:03 +0900 (Fri, Jun), Vin Raja wrote: > 8 > > Now when I comment Line 4 and Uncomment Line 12, the output comes to be: > In first case it appears that that private declaration had no effect, > > Can anyone Explain this bias??? While waiting for someone wiser than me to answer, I'll try to explain how I understand it :-) In line 4 you change the visibility of existing method to_s. In line 9 you declare new method with *public* visibility. That's why the line 12 is required to change it back to private. And why? That's because in Ruby the definition of your class is not parsed and then compiled in one step, just it is executed as ordinary program - each line in your code does something. That's why the order of your lines matter - it matters if you first change the visibility of the method and then define it. Try to do something like this: class A private :non_existing def non_existing p 'in non_existing' end end class B def non_existing p 'in non_existing' end private :non_existing end In your second topic, the private method to_s may be invoked by not calling it directly, but by using the 'send' hack: The actual command executed by 'puts' is not 'object.to_s' but 'object.send(:to_s)'. Try something like: class Person def to_s 'bleh' end private :to_s end puts Person.new.to_s => NoMethodError: private method `to_s' called for bleh:Person puts Person.new.send(:to_s) => "bleh" The 'send' hack allows you to call private methods of any object. To prevent this you could: - make 'send' private (not recommended, since this would bleak almost everything, I'm afraid) - override 'send' and react when it receives :to_s as parameter. HTH.