in reply to Re: I hate the leading underscores.
in thread I hate the leading underscores.

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.

Replies are listed 'Best First'.
Re^3: I hate the leading underscores.
by BrowserUk (Patriarch) on Feb 16, 2005 at 14:11 UTC
    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.
Re^3: I hate the leading underscores.
by RazorbladeBidet (Friar) on Feb 16, 2005 at 13:28 UTC
    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 :)
      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.

      Private methods/variables should have no reason to be called outside a class.

      How about whitebox unit testing? I do this all the time.

              $perlmonks{seattlejohn} = 'John Clyman';

        Good point - looks like that comes up in JUnit testing as well:

        JUnit

        How do they solve it? Reflection :) Pretty much a hack around it, I suppose.
      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.

        Just call the method if that pleases you. Noone is stopping you from calling an undocumented method. Just don't be surprised that after an upgrade, the method is no longer there, or causes your system to send out spam.

        That's what private means. It means the author/maintainer keeps the rights to modify it without notice. I don't see the difference between calling a private method or fiddling with attributes directly. It's great as long as it works. But you've voided your warranty. If you do it with my modules, you don't get support, and you don't get sympathy if your program breaks.

        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.

        That's usually why you'd need protected elements. So derived classes can access them. But I believe there are cases where you should be mindful of changing access to private information. It's private for a reason.
      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.
        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.

        Not quite - not documenting them is just one way to hide variables. Programmers may not be expected to read the code, but they don't always do as expected (do you?). I agree with your last statement

        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.

        Ok, I can agree with you there. I've little experience with using scope to hide things from end users. I do consider closures a built-in way to hide things. I can see them in a scope sense being similar to private variables. However they seem to be more than that, and you have more rope to hang yourself with. I don't consider closures akin to the private/protected/public modifiers. That does not make it a bad thing, I just don't see it as being intended to provide that. I could be wrong, of course.

        What I would say (overall) is that it makes placing an underscore before a private variable a secondary security measure. If a private variable is undocumented, that may well be the first line of defense, I'll grant you that. However, if a premise of using visual cues (or lack thereof) to alert a developer to the accessibility of an attribute or method has already been established, then it makes more sense to use the leading underscore in that case.
Re^3: I hate the leading underscores.
by herveus (Prior) on Feb 23, 2005 at 19:28 UTC
    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.

    yours,
    Michael