Re: Private method variations
by TimToady (Parson) on Mar 01, 2004 at 05:52 UTC
|
You should probably be aware that the MY:: package name will be reserved in Perl 6 for getting at your current lexical scope.
On the other hand, your approach isn't so very different from that which Perl 6 will take--private methods and attributes will essentially be off in their own chunk of namespace. Of course, Perl 6 won't need to use source filtering for that...
Anyway, you're on the right track. Now if I could convince you to use My instead of MY, your scripts will be slightly easier to translate to Perl 6. | [reply] [Watch: Dir/Any] [d/l] [select] |
|
| [reply] [Watch: Dir/Any] [d/l] [select] |
|
| [reply] [Watch: Dir/Any] [d/l] |
|
|
|
|
Maybe I am being niave but, is there something wrong with MyClass::PRIVATE:: ? It would be the least ambiguous of all IMO. I mean it would be hard to grab the PRIVATE:: root namespace, but if you are using a source filter anyway, you could generate the MyClass::PRIVATE:: "inner"-package with ease.
-stvn
| [reply] [Watch: Dir/Any] |
|
|
|
|
| [reply] [Watch: Dir/Any] |
Re: Private method variations
by dragonchild (Archbishop) on Mar 01, 2004 at 02:35 UTC
|
sub greet_world : no_override {
my $self = shift;
my ($greeting) = @_;
print "$greeting, world\n";
}
Of course, I don't know a lot about attributes, but that would make more syntactical sense, to me ...
Update: Would Attribute::Protected do this?
------
We are the carpenters and bricklayers of the Information Age.
Please remember that I'm crufty and crochety. All opinions are purely mine and all code is untested, unless otherwise specified.
| [reply] [Watch: Dir/Any] [d/l] |
|
How is SUPER implemented? I think it would make more sense to leverage that code and make it part of Perl itself.
I doubt there would be much code to leverage. Beyond the lexical similarity there's not a lot of common ground. SUPER is doing a runtime method lookup, while MY is doing compile-time namespace fiddling.
An alternative I prefer better is to make it an attribute
You could use an attribute to wrap a method to check it was only called on objects of a specific type. However this would still leave the method in the same name space, which leads to the original problem of subclasses breaking due to implementation changes in the base class.
You could also use the attribute, I guess, to mark methods for later transfer to another namespace in an INIT block - but that would still leave the method calls to be dealt with. You'd have to use a source filter for that - or use the full package name of the private namespace which CanBeTedious.
Of course in Perl 6 it would both trivial (since we have a decent macro system) and unnecessary (since Larry and friends are making what looks to be a very nice OO environment).
| [reply] [Watch: Dir/Any] |
|
Problem is, that is run-time, not compile-time stuff.
When called from inappropriate classes, those methods throw an exception like foo() is a protected method of Foo!.
Can't say I like that. I want to know if my system is broken before I happen to stumble across a particular leg of code -- especially if it's not going to be covered very often.
Yes, some one else is going to chime in and say "Perl OO isn't like that", and I'll say "why shouldn't it be?". Hint: that's a rhetorical question.
| [reply] [Watch: Dir/Any] |
|
I agree with you, that its nice to know at compile time, but perl isn't like tha...
Yes, some one else is going to chime in and say "Perl OO isn't like that", and I'll say "why shouldn't it be?". Hint: that's a rhetorical question.
Its not so much that Perl is not like that, its that the more "dynamic" OO languages are not like that. Smalltalk, Python, etc. etc. most of them don't have a concept of public, protected and private either. It's really an idea that is much more acceptable in a more "static" OO language where such "restrictions" are the norm. It's a trade-off really.
Personally, I am waiting to see how they solve issues like this in the Perl 6 object model. It should be very interesting.
-stvn
| [reply] [Watch: Dir/Any] |
Re: Private method variations
by flyingmoose (Priest) on Mar 01, 2004 at 01:36 UTC
|
I'm rather new to Perl OO-ness (but I have significant experience in other languages), but I must say, I like this idea very very much. It fixes one of my biggest issues with Perl OO -- enforcing encapsulation requires some huge incantations that make the code rather hard to read.
Just thinking aloud, but could something similar be done to enforce private variables? This would be a cool feature to have, even if strangely implemented. Hopefully in the same module?
Even if some extra private-variable functionality was not added, I can see how this could trivially be used to restrict an accessor/mutator function. Generally I try to write my OO such that trivial accessor/mutators aren't needed (too many accessors/mutators tends to indicate design flaws), but in Perl, the accessor/mutators are somewhat useful since it's way too easy to create a typo in a hash lookup.
Also, source filters, from what I know of them, are supposed to be evil...but as long as this one doesn't bork with line numbers, it should be ok! Seems like goodness to me.
Cool. I'd say definitely put something like this on CPAN. I'd use it.
| [reply] [Watch: Dir/Any] |
|
| [reply] [Watch: Dir/Any] |
|
Well, normally "private" variables are named with an "_" at the beginning as a key in the blessed hashref...
since the blessed object is "just" a normal data structure in perl, it is always possible to access the data within that structure... but why does the user who is using your module want to kill himself by not using your methods but accessing the datastructure itself?!?
On your hand, Perl OO is not as other OO programming like in C++ or java. The blessed "thingy" is not your class object but just an object within your class. so it can not know anything about public or private.
Hope, i got it right!
Update:Daim... i missed the original post...sorry...stupid mistake...
| [reply] [Watch: Dir/Any] |
|
| [reply] [Watch: Dir/Any] |
Re: Private method variations
by hardburn (Abbot) on Mar 01, 2004 at 14:23 UTC
|
If you want to avoid namespace clashes, you can just avoid the method lookup entirely and pass the object as the first parameter to the private method (this happens anyway, we just aren't faking it). As a bonus, the subroutine lookup time is reduced:
my $private1 = sub { print "Private1\n" };
sub _private2 { print "Private2\n" }
sub public_method
{
my $self = shift;
$private1->($self);
_private2($self);
}
Calling like this shouldn't be done for public and protected methods because it breaks subclassing, but private methods aren't supposed to be subclassed anyway.
----
: () { :|:& };:
Note: All code is untested, unless otherwise stated
| [reply] [Watch: Dir/Any] [d/l] [select] |
|
| [reply] [Watch: Dir/Any] |
|
Nevertheless, it's the use of the same calling style that is the root of the problem.
Perl 6 will have a compromise solution to this. The calling style for a private method is very like, but not quite the same as, the calling style for a public method. All private attributes and method names will start with a distinguishing character, which at the moment I would guess is colon, though at one time it was exclamation mark. Anyway,
has $.foo; # public attribute
has $:bar; # private attribute
method foo (){...} # public method
method :bar () {...} # private method
...
$self.foo() # always calls public method virtually
.foo() # unary variant
$self.:bar() # always calls private method
.:bar() # unary variant
...
$self.bar() # calls public bar, not private.
In this way, you don't have to change your argument passing--it's just a matter of inserting an extra character. The calls are also self-documenting, since you can tell by inspection whether you're looking for something public or private. Likewise, any use of $.foo is obviously public, while any use of $:foo is obviously private.
| [reply] [Watch: Dir/Any] [d/l] [select] |
|
|
|
|
|