Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Ruby > Private methods not so private?

Reply
Thread Tools

Private methods not so private?

 
 
Frank Meyer
Guest
Posts: n/a
 
      08-01-2007
Hello,
I'm using Ruby 1.8.2 and I'm reading the book "Programming Ruby 2nd
edition". In this book they say, that Ruby implements private methods by
not allowing another receiver than "self". After reading this, I tried
the following:

class Test
private
def print_hello
puts "Hello everyone!"
end
end

t = Test.new
t.send( "print_hello" )


This program runs just fine and prints "Hello everyone!".



Is this behaviour to be expected?



Turing
--
Posted via http://www.ruby-forum.com/.

 
Reply With Quote
 
 
 
 
Alex Young
Guest
Posts: n/a
 
      08-01-2007
Frank Meyer wrote:
> Hello,
> I'm using Ruby 1.8.2 and I'm reading the book "Programming Ruby 2nd
> edition". In this book they say, that Ruby implements private methods by
> not allowing another receiver than "self". After reading this, I tried
> the following:
>
> class Test
> private
> def print_hello
> puts "Hello everyone!"
> end
> end
>
> t = Test.new
> t.send( "print_hello" )
>
>
> This program runs just fine and prints "Hello everyone!".
>
>
>
> Is this behaviour to be expected?

Yes - send trumps private. Private in Ruby is more of a guideline than
a rule. The implementer is trying to tell you not to go there, but you
can get around it if you really need to.

--
Alex

 
Reply With Quote
 
 
 
 
Ben Bleything
Guest
Posts: n/a
 
      08-01-2007
On Thu, Aug 02, 2007, Frank Meyer wrote:
> class Test
> private
> def print_hello
> puts "Hello everyone!"
> end
> end
>
> t = Test.new
> t.send( "print_hello" )
>
> This program runs just fine and prints "Hello everyone!".
>
> Is this behaviour to be expected?


Yes. send bypasses protection levels, for reasons I'm not really clear
on. If I were to hazard a guess, it would be that what you send is
eval'ed inside the context of the object, thereby making self the
receiver, but that's a total guess.

Test.new.print_hello will cause the error you expect.

As a sidenote, upgrade your ruby

Ben

 
Reply With Quote
 
Daniel Berger
Guest
Posts: n/a
 
      08-02-2007


On Aug 1, 4:06 pm, Alex Young <(E-Mail Removed)> wrote:
> Frank Meyer wrote:
> > Hello,
> > I'm using Ruby 1.8.2 and I'm reading the book "Programming Ruby 2nd
> > edition". In this book they say, that Ruby implements private methods by
> > not allowing another receiver than "self". After reading this, I tried
> > the following:

>
> > class Test
> > private
> > def print_hello
> > puts "Hello everyone!"
> > end
> > end

>
> > t = Test.new
> > t.send( "print_hello" )

>
> > This program runs just fine and prints "Hello everyone!".

>
> > Is this behaviour to be expected?

>
> Yes - send trumps private. Private in Ruby is more of a guideline than
> a rule.


It's a guideline in any language.

I think people tend to think of 'private' as some sort of security
enforcement. It's not. It just means, "You aren't supposed to access
this method directly. If you go out of your way to do so, I am not
responsible for the consequences".

The advantage of allowing send to access private methods is that it
allows you to test private methods.

Regards,

Dan


 
Reply With Quote
 
Skye Shaw!@#$
Guest
Posts: n/a
 
      08-02-2007
On Aug 1, 5:42 pm, Daniel Berger <(E-Mail Removed)> wrote:
> On Aug 1, 4:06 pm, Alex Young <(E-Mail Removed)> wrote:
>
>
>
> > Frank Meyer wrote:
> > > Hello,
> > > I'm using Ruby 1.8.2 and I'm reading the book "Programming Ruby 2nd
> > > edition". In this book they say, that Ruby implements private methods by
> > > not allowing another receiver than "self". After reading this, I tried
> > > the following:

>
> > > class Test
> > > private
> > > def print_hello
> > > puts "Hello everyone!"
> > > end
> > > end

>
> > > t = Test.new
> > > t.send( "print_hello" )

>
> > > This program runs just fine and prints "Hello everyone!".

>
> > > Is this behaviour to be expected?

>
> > Yes - send trumps private. Private in Ruby is more of a guideline than
> > a rule.

>
> It's a guideline in any language.
>
> I think people tend to think of 'private' as some sort of security
> enforcement. It's not.


It is in C++ and Java, maybe even VB, if I recall... (I try not to
recall VB).
Well, maybe not a "security enforcement" but a visibility and/or
invocation restriction.

My JVM even gives me an IllegalAccessException when I try to access an
private Method at runtime via reflection.






 
Reply With Quote
 
Dan Zwell
Guest
Posts: n/a
 
      08-02-2007
Ben Bleything wrote:
> On Thu, Aug 02, 2007, Frank Meyer wrote:
>> class Test
>> private
>> def print_hello
>> puts "Hello everyone!"
>> end
>> end
>>
>> t = Test.new
>> t.send( "print_hello" )
>>
>> This program runs just fine and prints "Hello everyone!".
>>
>> Is this behaviour to be expected?

>
> Yes. send bypasses protection levels, for reasons I'm not really clear
> on. If I were to hazard a guess, it would be that what you send is
> eval'ed inside the context of the object, thereby making self the
> receiver, but that's a total guess.
>
> Test.new.print_hello will cause the error you expect.
>
> As a sidenote, upgrade your ruby
>
> Ben
>
>


Ben,

It is always possible to run private methods, change class variables,
etc. The way to do it is to reopen the class (or add an instance method)
that calls the private method or sets/gets the variable we need. Since
it's possible, why not make it easier? Ruby tries not to impose on what
the user can do, so we have foo.send, foo.instance_variable_set, and
foo.instance_variable_get.

Dan

 
Reply With Quote
 
Jørgen P. Tjernø
Guest
Posts: n/a
 
      08-02-2007
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

Daniel Berger wrote:
> [ .. snip .. ]
> The advantage of allowing send to access private methods is that it
> allows you to test private methods.

Isn't that a Bad Practice (tm)? Private methods are mostly meant for the
internals of a class, and a test should really only test how the class
interacts with the rest of the world - right? (i.e. public methods)

I might've missed the whole point, so this post contains Many
Questionmarks.

Kindest regards, Jørgen P. Tjernø.
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.6 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org

iD8DBQFGsbDiUMzc1WGo4zgRAoJ3AJ9MtInhJTZS9Uq1ABXwxx N9rwkeVACffYBG
+iCp8nwruwSH/WzNSAsbQp8=
=ndYq
-----END PGP SIGNATURE-----

 
Reply With Quote
 
dohzya
Guest
Posts: n/a
 
      08-02-2007
Le jeudi 02 août 2007 à 20:28 +0900, "Jørgen P. Tjernø" a écrit :
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>
> Daniel Berger wrote:
> > [ .. snip .. ]
> > The advantage of allowing send to access private methods is that it
> > allows you to test private methods.

> Isn't that a Bad Practice (tm)? Private methods are mostly meant for the
> internals of a class, and a test should really only test how the class
> interacts with the rest of the world - right? (i.e. public methods)
>
> I might've missed the whole point, so this post contains Many
> Questionmarks.
>
> Kindest regards, Jørgen P. Tjernø.
> -----BEGIN PGP SIGNATURE-----
> Version: GnuPG v1.4.6 (GNU/Linux)
> Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org
>
> iD8DBQFGsbDiUMzc1WGo4zgRAoJ3AJ9MtInhJTZS9Uq1ABXwxx N9rwkeVACffYBG
> +iCp8nwruwSH/WzNSAsbQp8=
> =ndYq
> -----END PGP SIGNATURE-----
>


It is a root of bad practices, but it may be necessary... I think a good
principe is : use public methods only of others's libraries, and use
instance_eval (etc) of yours when you need it, and if there is
collaboration between classes (like friendly classes of C++).
Thus you will be able to keep your model safe.

--
Etienne Vallette d'Osia


 
Reply With Quote
 
dblack@rubypal.com
Guest
Posts: n/a
 
      08-02-2007
--1926193751-1278936812-1186055005=:5495
Content-Type: MULTIPART/MIXED; BOUNDARY="1926193751-1278936812-1186055005=:5495"

This message is in MIME format. The first part should be readable text,
while the remaining parts are likely unreadable without MIME-aware tools.

--1926193751-1278936812-1186055005=:5495
Content-Type: TEXT/PLAIN; charset=X-UNKNOWN; format=flowed
Content-Transfer-Encoding: QUOTED-PRINTABLE

Hi --

On Thu, 2 Aug 2007, "J=F8rgen P. Tjern=F8" wrote:

> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>
> Daniel Berger wrote:
>> [ .. snip .. ]
>> The advantage of allowing send to access private methods is that it
>> allows you to test private methods.

> Isn't that a Bad Practice (tm)? Private methods are mostly meant for the
> internals of a class, and a test should really only test how the class
> interacts with the rest of the world - right? (i.e. public methods)


No; you definitely want to test your private methods too. First of
all, if you're writing a class, you need to test its internals;
nothing should be a "black box" for the tests. Second, private
methods are actually available to the world, even without send. They
just have to be called the right way:

puts "Hi"
class C
attr_accessor
end
C.class_eval { define_method "y" }

puts, attr_accessor, and define_method are all private, but you'd
certainly want to test them if you had written them.


David

--=20
* Books:
RAILS ROUTING (new! http://www.awprofessional.com/title/0321509242)
RUBY FOR RAILS (http://www.manning.com/black)
* Ruby/Rails training
& consulting: Ruby Power and Light, LLC (http://www.rubypal.com)
--1926193751-1278936812-1186055005=:5495--
--1926193751-1278936812-1186055005=:5495--

 
Reply With Quote
 
Ben Bleything
Guest
Posts: n/a
 
      08-02-2007
On Thu, Aug 02, 2007, Dan Zwell wrote:
> Ben Bleything wrote:
> >Yes. send bypasses protection levels, for reasons I'm not really clear
> >on. If I were to hazard a guess, it would be that what you send is
> >eval'ed inside the context of the object, thereby making self the
> >receiver, but that's a total guess.

>
> It is always possible to run private methods, change class variables,
> etc. The way to do it is to reopen the class (or add an instance method)
> that calls the private method or sets/gets the variable we need. Since
> it's possible, why not make it easier? Ruby tries not to impose on what
> the user can do, so we have foo.send, foo.instance_variable_set, and
> foo.instance_variable_get.


Right. I was just trying to answer the original question

Ben

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Is there a way to find the class methods of a class, just like'methods' finds the instance methods? Kenneth McDonald Ruby 5 09-26-2008 03:09 PM
Why is define_method private? Plus,what's the point of private methods? Daniel Finnie Ruby 3 12-16-2006 10:09 PM
Private methods called from public methods Robert Javascript 16 05-06-2006 11:32 PM
Re: Why does python class have not private methods? Will this neverchanged? Simon Brunning Python 4 04-19-2005 02:50 PM
Re: Templates and friends and template methods with private methods. Buster Copley C++ 5 07-07-2003 12:50 AM



Advertisments