Re^2: I hate the leading underscores.
by Anonymous Monk on Feb 16, 2005 at 13:18 UTC
|
That means, you give up encapsulation. If you allow private methods to be called, they aren't private, and if you change
the interface or functionality of such a method, or remove it
all together, you've just broken backwards compatability.
OO without encapsulation doesn't make any sense to me. Then it just becomes syntactical sugar to be able to use cool looking arrows. | [reply] |
|
|
OO without encapsulation doesn't make any sense to me. Then it just becomes syntactical sugar to be able to use cool looking arrows.
Many, I amongst them, would argue that your statement is incorrect. You have used the word "encapsulation" where, from the context, you really meant "information hiding".
That may seem like a facetious argument, but this Encapsulation is not information hiding may change your mind.
Examine what is said, not who speaks.
Silence betokens consent.
Love the truth but pardon error.
| [reply] |
|
|
Agreed. Private methods/variables should have no reason to be called outside a class. If necessary, simply make a public accessor that calls that private method/variable.
I personally use underscores because it is helpful from a visual standpoint. Especially when there are no built-in security measures in place to hide variables and methods (not include closures, but that's not what I'd consider a "built-in" way to hide things, no offense to closures, of course).
Even still, coming from Java, I used them there. You simply get used to it, and while I agree it is not the prettiest thing in the world, I've seen worse :)
| [reply] |
|
|
Just to give a slight hint at how you can use closures to hide methods:
#!/usr/bin/perl -w
use strict;
package Foo;
{
# private
my $set_a = sub {
my $self = shift;
$self->{a} = shift;
};
# public
sub a {
my $self = shift;
return $self->{a};
}
# public
sub new {
my $self = bless {},shift;
$self->$set_a('abcdef');
return $self;
}
}
package main;
my $foo = Foo->new;
print $foo->a();
It is a pretty secure and not too hard way to hide private methods, but I've never used it in production code, because I happen to agree with the philosophy that undocumented methods are private. It does have the advantage of not polluting namespaces with private methods, though.
| [reply] [d/l] |
|
|
| [reply] |
|
|
|
|
Agreed. Private methods/variables should have no reason to be called outside a class. If necessary, simply make a public accessor that calls that private method/variable.
What if you don't have access to the original source code? Usually you do in Perl, but it's not always convenient to modify it. You're then at the mercy of someone else's design decisions.
You could have a perfectly legitimate reason for calling a method that someone else thought you wouldn't or shouldn't. The problem with a strict OO design is that it assumes the original design is perfect.
I'm not saying we should always call private methods (otherwise there'd be no need to indicate them with a leading underscore), but it's nice to have the option.
| [reply] |
|
|
|
|
|
|
there are no built-in security measures in place to hide variables and methods
The way to hide variables and methods is not to document them. Programmers using a module are not expected to read the code, they're expected to read the documentation. Using undocumented features is always an At Your Own Risk activity.
If you prefer to make things programmatically inaccessible, scoping is the built-in tool for that, though I don't think that proper methods (automatically passing self) can be made this way. I'm not sure why you don't consider closures a built-in way to hide things.
More on this topic in Private Methods Meditation.
Caution: Contents may have been coded under pressure.
| [reply] |
|
|
|
|
|
|
|
Howdy!
That means, you give up encapsulation. If you allow private methods to be called, they aren't private
The first claim is non sequitur. The second depends on a
specific connotation of "private" that does not necessarily
hold. Further, the concept of "allowing" methods to be
called implies some way to prevent it, which is decidedly
non-Perlish.
Moving onward, you can troll through the namespace of a module to
see what CODE references you can find in the name space. That then
gives you names of subroutines. If you want to actively prevent
methods from being called under certain circumstances, you can
use caller() to try to decide if the caller is acceptable, and
barf otherwise. In general, that is a lot of work for little to
no gain. Further, that sort of "protection" can still be
circumvented by clever hackery -- hackery that has no place in
a "finished" product, but possible hackery nonetheless.
| [reply] |