Access Modifiers

V

Vin Raja

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
 
L

Leonard Chin

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
 
M

Mariusz Pękala

--UugvWAfsgieZRqgk
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

Hi All
Now another hitch:
=20
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=3D Person.new
16 puts p
17 puts "********"
18 puts p.to_s
=20
+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
CASE I
With the above class the output comes out to be:
=20
just another person
********
just another person
=20
CASE II
Now when I comment Line 4 and Uncomment Line 12, the output comes to be:
=20
just another person
********
yet.rb:18: private method `to_s' called for just another person:person
(NoMethodError)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
=20
THE HITCH
=20
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??
=20
AND
=20
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.
=20
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
=3D> NoMethodError: private method `to_s' called for bleh:person

puts Person.new.send:)to_s)
=3D> "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.

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

--UugvWAfsgieZRqgk
Content-Type: application/pgp-signature
Content-Disposition: inline

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.7-ecc0.1.6 (GNU/Linux)

iD8DBQFGYBfWsnU0scoWZKARAgjuAKCc/mpKjr4ArbfmSLYEpAvJAeg9PACeLsUQ
iJW63COJLeSQ8jswtqZjX/A=
=wbVB
-----END PGP SIGNATURE-----

--UugvWAfsgieZRqgk--
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,577
Members
45,054
Latest member
LucyCarper

Latest Threads

Top