[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.ruby

Access Modifiers

raja

6/1/2007 10:33:00 AM

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

--
Posted via http://www.ruby-....

2 Answers

Leonard Chin

6/1/2007 12:00:00 PM

0

On 6/1/07, Vin Raja <vineetraja@gmail.com> 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.ht...

Mariusz Pekala

6/1/2007 12:58:00 PM

0

On 2007-06-01 19:33:03 +0900 (Fri, Jun), Vin Raja wrote:
> 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???

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.

--
No virus found in this outgoing message.
Checked by 'grep -i virus $MESSAGE'
Trust me.