copy contructor

A

Anno Siegel

A. Sinan Unur said:
(e-mail address removed)-berlin.de (Anno Siegel) wrote in
The code for the base class is mostly unchanged. The only difference
is that it inserts a do-nothing method (one that just returns its
object) into all of its accessors (not in other methods). So if the
accessor was

sub alpha { $_[ 0]->[ 0] }

it becomes

sub alpha { $_[ 0]->parent->[ 0] }
# ...
sub parent { shift }

[ rest of the discussion and code snipped ]

Anno:

I wanted to thank you very much for this series of posts, especially
this last one. I found it very informative.

Thankyou. It's nice to be appreciated. [As Brian (Nobull) just said in
another thread.]

In fact, I think I'll make a (not much) more extensive writeup of this
material and put it on the web (at least). The final trick deserves
publicity, if I say so myself, but even without it, more awareness of
accessors and their significance would help OO programming in Perl.

Anno
 
A

Anno Siegel

Abigail said:
Anno Siegel ([email protected]) wrote on MMMMCCCXL
September MCMXCIII in <URL:%%
%% That's why I'm preaching that accessors must be documented. An inheriting
%% class must know what they are and how to override them.


But that's breaking encapsulation. 'Accessor's are only a meaningful
term for the class that defines the accessor - any other class should
not have to know what is an accessor or not. With proper encapsulation,
a class, when viewed from the outside, is a black box. The box keeps
state, and it has some methods where you can poke at the box. Whether
a method happens to return an attribute or not should be irrelevant.
If you need to know, you break encapsulation.

True. The fundamental breach in encapsulation is that Perl objects
have a life of their own, they aren't opaque structures (nothing but
objects) like in most OO languages. That flaw can't be removed by
argumentation and paradigm shifts, it's here to stay.

The distinction in accessors and non-accessors can help in making
that breach manageable, not make it go away.

By publishing which methods are accessors and which aren't, you are
making a considerable implementational commitment. In particular,
you can't make an accessor out of what used not to be one. Your
client's code would break.
How do you subclass a class that keeps state, but doesn't provide
an accessor?

package Angry::Snake;

sub new {
bless \do {my $c = int rand 5} => shift;
}

sub poke_it_with_a_stick {
my $snake = shift;
$snake -> attack if $$snake -- < 0;
}

sub attack { ... }

Mmmmm, nice snakey, pretty snakey, I'm not poking, okay...?

No, you can't inherit ->poke_with_a_stick. That's because it's an
accessor, even if it is not a field accessor in the usual sense.
It accesses (de-references) the object, and so it's out.

If Angry::Snake were written with an overridable method (->snake)
guarding the access, like this:

sub poke_it_with_a_stick {
my $snake = shift;
$snake -> attack if ${ $snake->snake} -- < 0;
}

sub snake { shift }

things would be different. Here's a less aggressive snake that doesn't
always notice when it is poked:

package Sleepy::Snake;
BEGIN { our @ISA = 'Angry::Snake' }

sub new {
bless {
sleepiness => 0.5,
snake => Angry::Snake->new,
}, shift;
}

sub snake { $_[ 0]->{ snake} }

sub poke_it_with_a_stick {
my $sn = shift;
$sn->SUPER::poke_it_with_a_stick if rand > $sn->sleepiness;
}

sub sleepiness {
$_[ 0]->{ sleepiness} = shift if @_ > 1;
$_[ 0]->{ sleepiness};
}

Anno
 
A

Anno Siegel

[this article supercedes an earlier version to correct a coding error]

Abigail said:
Anno Siegel ([email protected]) wrote on MMMMCCCXL
September MCMXCIII in <URL:%%
%% That's why I'm preaching that accessors must be documented. An inheriting
%% class must know what they are and how to override them.


But that's breaking encapsulation. 'Accessor's are only a meaningful
term for the class that defines the accessor - any other class should
not have to know what is an accessor or not. With proper encapsulation,
a class, when viewed from the outside, is a black box. The box keeps
state, and it has some methods where you can poke at the box. Whether
a method happens to return an attribute or not should be irrelevant.
If you need to know, you break encapsulation.

True. The fundamental breach in encapsulation is that Perl objects
have a life of their own, they aren't opaque structures (nothing but
objects) like in most OO languages. That flaw can't be removed by
argumentation and paradigm shifts, it's here to stay.

The distinction in accessors and non-accessors can help in making
that breach manageable, not make it go away.

By publishing which methods are accessors and which aren't, you are
making a considerable implementational commitment. In particular,
you can't make an accessor out of what used not to be one. Your
client's code would break.
How do you subclass a class that keeps state, but doesn't provide
an accessor?

package Angry::Snake;

sub new {
bless \do {my $c = int rand 5} => shift;
}

sub poke_it_with_a_stick {
my $snake = shift;
$snake -> attack if $$snake -- < 0;
}

sub attack { ... }

Mmmmm, nice snakey, pretty snakey, I'm not poking, okay...?

No, you can't inherit ->poke_with_a_stick. That's because it's an
accessor, even if it is not a field accessor in the usual sense.
It accesses (de-references) the object, and so it's out.

If Angry::Snake were written with an overridable method (->snake)
guarding the access, like this:

sub poke_it_with_a_stick {
my $snake = shift;
$snake -> attack if ${ $snake->snake} -- < 0;
}

sub snake { shift }

things would be different. Here's a less aggressive snake that doesn't
always notice when it is poked:

package Sleepy::Snake;
BEGIN { our @ISA = 'Angry::Snake' }

sub new {
bless {
sleepiness => 0.5,
snake => Angry::Snake->new,
}, shift;
}

sub snake { $_[ 0]->{ snake} }

sub poke_it_with_a_stick {
my $sn = shift;
$sn->SUPER::poke_it_with_a_stick if rand > $sn->sleepiness;
}

sub sleepiness {
# $_[ 0]->{ sleepiness} = shift if @_ > 1; # this is in error
$_[ 0]->{ sleepiness} = $_[ 1] if @_ > 1;
$_[ 0]->{ sleepiness};
}

Anno
 
E

Eric Schwartz

Abigail said:
Here's how I would subclass Angry::Snake. Note that I subclass the
original Angry::Snake, without requiring it to have an "accessor".

package Angry::Snake;

sub new {
bless \do {my $c = int rand 5} => shift;
}

sub poke_it_with_a_stick {
my $snake = shift;
$snake -> attack if $$snake -- < 0;
}

sub attack { ... }

<snip rest of example>

Ow. Stop hurting my brain like that. So assuming you wanted to store
multiple bits of data, would Sick::Snake look something like:

package Sick::Snake
use Scalar::Util qw 'refaddr';

our @ISA = qw/Angry::Snake/;

my %attr;

sub set_shivering {
my $snake = shift;
$attr{refaddr $snake}{shivering} = shift;
$snake;
}

sub set_sneezing {
my $snake = shift;
$attr{refaddr $snake}{sneezing} = shift;
$snake;
}

sub shivering {...}
sub sneezing {...}

and so on?

That's a very neat trick. Should I ever be forced to write OO in
Perl, I will try to keep that in mind. Also, nice plug for
Scalar::Util, which while not quite as nifty as List::Util, is still
one of the more underappreciated modules in Perl, I think.

-=Eric
 
E

Eric Schwartz

Abigail said:
That's one way, but I don't like that (too much typing, and I prefer
to avoid using literal strings for hash keys - using lexical variables
gives you all the power 'use strict' can give you). I do it this way:

package Sick::Snake; {

use Scalar::Util qw 'refaddr';
our @ISA = qw /Angry::Snake/;

my %shivering;
my %sneezing;

I suppose the only concern I had was that if you have a number of
attributes for an object, this list might become wearying itself to
type. But then, I suppose you only have to do so once, and anyhow, a
nice comment block to alert the reader that these were attributes
would work fine. It just reminds me of a project I once worked on
where there was a data structure with literally dozens of parallel
arrays (poorly designed, I'll concede), and it was often hard to track
modifications so that they tracked each of these.
sub DESTROY {
my $snake = shift;
delete $shivering {refaddr $snake};
delete $sneezing {refaddr $snake};
}

Here in particular, if you aren't careful, you might add an attribute
and forget to put it in DESTROY, whereas my approach would look like:

sub DESTROY {
my $snake = shift;
delete $attrs{refaddr $snake};
}

But your arguments for lexicals giving the equivalent of use strict is
a strong one, and I don't suppose it's an undue burden to remember to
add a new attribute to DESTROY. Anyhow, even if you forget, the worst
that would happen is you hold a reference that is inaccessible-- a
memory leak, but not a critical program failure in itself.

-=Eric
 
A

Anno Siegel

Abigail said:
Anno Siegel ([email protected]) wrote on MMMMCCCXLI
September MCMXCIII in said:
[[ Snipped for brevity ]]


Here's how I would subclass Angry::Snake. Note that I subclass the
original Angry::Snake, without requiring it to have an "accessor".

Ah, but in my book (that would be a little paper I'm writing about
inheritance in Perl) it *has* an accessor. Any method that accesses the
object by de-referencing the object is an accessor, whether it returns
the value to the caller or does something else with it. That would make
->poke_it_with_a_stick an accessor. A field accessor in the usual
sense is just a special case. In most mainstream OO languages there
are no accessors except field accessors, so the two notions coincide,
but Perl is different.

That's just terminology. Maybe I should think it over and find a better
term. But what can you call a method whose distinguishing property is that
it accesses the object?
package Angry::Snake;

sub new {
bless \do {my $c = int rand 5} => shift;
}

sub poke_it_with_a_stick {
my $snake = shift;
$snake -> attack if $$snake -- < 0;
}

sub attack { ... }



package Sleepy::Snake; {
use Scalar::Util qw 'refaddr';

our @ISA = qw /Angry::Snake/;

my %sleepiness; # Store the attribute in a lexical variable.

sub set_sleepiness {
my $snake = shift;
$sleepiness {refaddr $snake} = shift;
$snake;
}
sub sleepiness {
my $snake = shift;
$sleepiness {refaddr $snake};
}

sub poke_it_with_a_stick {
my $snake = shift;
$snake -> SUPER::poke_it_with_a_stick
if rand > $snake -> sleepiness;
}

sub DESTROY {
my $snake = shift;
delete $sleepiness {refaddr $snake};
}
}

package main;

my $snake = Sleepy::Snake -> new -> set_sleepiness (0.5);


Note that Sleepy::Snake doesn't have its own constructor.

No, it can't. One of the tenets about Perl inheritance is "If you
inherit an accessor, you must also inherit ->new", which is what happens
here. Inherit as opposed to override.

Like all short formulas about complex fields (except exp(i*pi) = -1, hehe),
it is wrong. You can override ->new, provided you call the base class'
->new to create the object. Your objects must be structurally the same
as those of the base class if you want the base class accessors to work
on them. Put like that it's a truism.

However, in package Sleepy::Snake it would be safe to override ->new

sub new { shift()->SUPER::new->set_sleepiness( 0.5) }

so as not to create snakes with undefined sleepiness.
Nor does it rely
on how Angry::Snake has been implemented in any way. It doesn't require
its super class to make accessors available. It doesn't force anything
on a potential subclass either.

Quite so, it carries itself the full weight of inheriting from the
deliberately inheritance-unfriendly Angry::Snake. The weight is the
somewhat unusual implementation. It shows again that inheritance in
Perl doesn't come for free. Someone must support it, the base class
and/or the inheriting class.

So "Inside-out" is what you call them. (I've read some more of the thread,
but wanted to reply with your code in sight.) It's an ingenious answer
to the question: How can I assign additional data (fields) to an object when
I'm not allowed to change its structure?

I suppose you are using Scalar::Util::refaddr because stringification
may be overloaded for the base class. Otherwise the stringified object
would serve as well. I have used overload::StrVal for the purpose.
On re-reading perldoc overload I see that there is now a pointer to
Scalar::Util::refaddr.

Just out of spite, below is yet another way to inherit poke_it_with-
_a_stick from an (unchanged) Angry::Snake. It uses de-reference
overloading to persuade the base class to access Sleepy::Snake objects
in a special way. Overloading every possible kind of de-reference makes
sure it continues to work when Angry::Snake changes its implementation.
It is more heavy handed than the elegant inside-out objects, and it inhibits
further inheritance in a major way. Overloading de-reference is bad for
inheritance, carpet-bombing it over all types, as I do here, is worse.
The merit of this way, if any, is the standard implementation of
Sleepy::Snake as a typical hash-as-a-struct.

package Sleepy::Snake;
use base 'Angry::Snake';
use overload map { $_ => 'snake' } qw( ${} @{} %{} &{} *{});

sub new {
my $class = shift;
bless {
sleepiness => 0.5,
snake => Angry::Snake->SUPER::new,
}, $class;
}

sub set_sleepiness { $_[ 0]->{ sleepiness} = $_[ 1]; shift }
sub sleepiness { $_[ 0]->{ sleepiness} }

# we're the ->{ snake} field for Angry::Snake, ourselves for
# everyone else
sub snake { caller eq 'Angry::Snake' ? $_[ 0]->{ snake} : $_[ 0] }

sub poke_it_with_a_stick {
my $snake = shift;
$snake -> SUPER::poke_it_with_a_stick if rand > $snake -> sleepiness;
}
__END__

Anno
 
A

Anno Siegel

Abigail said:
Anno Siegel ([email protected]) wrote on MMMMCCCXLIV
September MCMXCIII in <URL:{} > Anno Siegel ([email protected]) wrote on MMMMCCCXLI
{} > September MCMXCIII in <URL:{} >
{} > > [[ Snipped for brevity ]]
{} >
{} >
{} > Here's how I would subclass Angry::Snake. Note that I subclass the
{} > original Angry::Snake, without requiring it to have an "accessor".
{}
{} Ah, but in my book (that would be a little paper I'm writing about
{} inheritance in Perl) it *has* an accessor. Any method that accesses the
{} object by de-referencing the object is an accessor, whether it returns
{} the value to the caller or does something else with it. That would make
{} ->poke_it_with_a_stick an accessor. A field accessor in the usual
{} sense is just a special case. In most mainstream OO languages there
{} are no accessors except field accessors, so the two notions coincide,
{} but Perl is different.

Oh, it has an accessor allright. Whether or not the super class has
an accessor is not important. Or rather, it's irrelevant. And that's
(IMO) the beauty of Inside-Out Objects. It's _irrelevant_ whether the
superclass has accessors. Or attributes/fields. Or how it stores them.
How the superclass is implemented does not matter - all that matters
is its API. And the whole implementation can change, accessors can turn
into non-accessors, or visa versa, if the API remains the same, there's
no need to update the inheriting class.

Well, paradise. A sunlit Caribbean island with no inheritance tax. The
one thing I don't see at a glance is how you would do multiple inheritance
that way. Your object *is* an object of the base class, only blessed
into yours. It can't be physically be many structures at once.
{} That's just terminology. Maybe I should think it over and find a better
{} term. But what can you call a method whose distinguishing property is that
{} it accesses the object?

I don't really care how you call them. I don't think a different term from
them is important. In fact, when I call methods in a class, I do not want
to have to know whether it's an accessor or not. When I look to a class
from anywhere but the class itself, all I should see is methods. If I
need to know (perhaps to do something different) that a method is an
"accessor", something is wrong. IMO, it breaks encapsulation, and OO with
broken encapsulation is no fun at all.

I agree. In inheritance paradise there is no need for the term "accessor".
But that blissful state is not where programmers find themselves who
go about Perl OO naively, or follow what they are taught in most tutorials.

To see why and how things go wrong, and what to do about it, I think I
need the term. But that's no concern of yours, you're right to point that
out.
{} > Note that Sleepy::Snake doesn't have its own constructor.
{}
{} No, it can't. One of the tenets about Perl inheritance is "If you
{} inherit an accessor, you must also inherit ->new", which is what happens
{} here. Inherit as opposed to override.

Sure it can have its own constructor. I just decided not to. I prefer
not to configure an object (that is, setting attribute values) in a
constructor because that makes multiple inheritance a real pain in the
ass, so I prefer to only have constructors in classes that don't inherit
other classes, and such constructors should only return the blessed
reference, and do not anything else. Having said, if I were to create
a constructor for the Sleepy::Snake class, I'd do it like this:

sub new {
my $snake = Angry::Snake -> new; # Let the class set itself up
# in whatever way it pleases.
$sleepiness {refaddr $snake} = 0.5; # Default value.
bless $snake => shift; # Bless it to our class.
}

{} Like all short formulas about complex fields (except exp(i*pi) = -1, hehe),
{} it is wrong. You can override ->new, provided you call the base class'
{} ->new to create the object. Your objects must be structurally the same
{} as those of the base class if you want the base class accessors to work
{} on them. Put like that it's a truism.

Yes. But that's the beauty of Inside-Out Objects. It doesn't care what
structure the super class has, because it doesn't use the structure at
all. All it needs is the memory address.

{} However, in package Sleepy::Snake it would be safe to override ->new
{}
{} sub new { shift()->SUPER::new->set_sleepiness( 0.5) }
{}
{} so as not to create snakes with undefined sleepiness.

That works as well as the constructor I used above. But it makes
multiple inheritance a lot harder.

As mentioned above, that was my first concern about your approach. How
do you inherit from more than one class in this way? Could you elaborate?

[some snippage]
Even with Inside-Out Objects, we have:

push @{$array {refaddr $_ [0]}} => 'one', 'two', 'three';

But I've fixed that as well. With Lexical::Attributes, I just write:

push @.array => 'one', 'two', 'three';

But that's for a different thread.
\end{side-remark}

Huh, what's that? A source filter? Oh, never mind. I'll look if I must
know.

I find this thread very worthwhile.

Anno
 
A

Anno Siegel

Abigail said:
Anno Siegel ([email protected]) wrote on MMMMCCCXLV
September MCMXCIII in <URL:
[ Inside-Out Objects ]

{}
{} Well, paradise. A sunlit Caribbean island with no inheritance tax. The
{} one thing I don't see at a glance is how you would do multiple inheritance
{} that way. Your object *is* an object of the base class, only blessed
{} into yours. It can't be physically be many structures at once.


If you're inheriting from two classes who use a different structure,
it's going to be hard. With different structures, you'll have to resort
to a has-a relationship, and dispatch all the methods of said class.

Right. Base it on a has-a. The crux is how to do the dispatching.
If you are inheriting from two classes that use the same structure, you
might be lucky, and will be able to do something by breaking encapsulation
and merging the objects. If both classes use refs to hashes, and they don't
use the same attributes, you can fill on hash with the content of the other.

Okay, same old same old. Except it is now two prospective base classes
that are coupled too close for comfort, not subclass and base class.
Not sure if that's generally better, but it's an alternative, and as
such yields some leeway in design.
Or you use a has-a relationship.

Again. Often, that's the cleanest solution. You have to support all
methods of the base class one way or another, so why not take an original
on board and support them through that.
If the classes you want to inherit from are Inside-Out Objects, and their
constructors only construct (and don't initialize) the object, multiple
inheritance is easy:

[snip code that leads to]
package Perl; {
our @ISA = qw /Floor::Wax Dessert::Topping/;

sub init {
my $self = shift;
$self -> Floor::Wax::init;
$self -> Dessert::Topping::init;
}

sub colour {
my $self = shift;

sprintf "%s and %s" => $self -> Floor::Wax::colour,
$self -> Dessert::Topping::colour;
}
}

package main;

my $p = Perl -> new -> init;

print $p -> colour, "\n";


__END__
yellow and white

That's a very pretty bit of machinery. I'll use it to study the
significance of keeping construction and initialization apart, thanks
for the example.

So "Perl" inherits whichever ->new happens to be first on @ISA, it doesn't
matter because they're all equivalent. And if another class (not
necessarily inside-out) also had separate construction and initialization,
it should be easy to thread it into the scheme. Correct me if I'm wrong,
but it looks like an inside-out class could inherit from such a base class
of *any* type without any further measures.

Of course, few real-world classes are like that.

Anno
 
A

Anno Siegel

Abigail said:
Anno Siegel ([email protected]) wrote on MMMMCCCXLVII
September MCMXCIII in <URL:^^
^^ So "Perl" inherits whichever ->new happens to be first on @ISA, it doesn't
^^ matter because they're all equivalent. And if another class (not
^^ necessarily inside-out) also had separate construction and initialization,
^^ it should be easy to thread it into the scheme. Correct me if I'm wrong,
^^ but it looks like an inside-out class could inherit from such a base class
^^ of *any* type without any further measures.


Indeed. By design. ;-)

Only once, sadly. So you can inherit from as many inside-out classes as
is good for you, plus one "normal" (type-committed) class.

One could wax philosophical about inside-out objects, how a normal inside-
in object holds everything of interest inside and nothing on the outside,
and thus, turning it inside-out, the core of an inside-out object becomes
an object-shaped void which is the former empty outside of the original,
and how this void can be filled with a normally functioning object
while the inside-out object continues to function because its function
is located on the outside, but
I won't.

Instead, let me add a thought that is only loosely related. It seems
to me that inheritance and encapsulation don't go together (anywhere,
not only in Perl) in one respect. When it comes to overriding some
of the original methods, you must know how the methods in the base class
use (call) each other in order to predict the result. On the other hand,
that's an implementation detail that shouldn't concern the inheriting
class. I don't see how that can be resolved.

Anno
 
A

Anno Siegel

Abigail said:
Anno Siegel ([email protected]) wrote on MMMMCCCXLVII
September MCMXCIII in <URL:^^
^^ So "Perl" inherits whichever ->new happens to be first on @ISA, it doesn't
^^ matter because they're all equivalent. And if another class (not
^^ necessarily inside-out) also had separate construction and initialization,
^^ it should be easy to thread it into the scheme. Correct me if I'm wrong,
^^ but it looks like an inside-out class could inherit from such a base class
^^ of *any* type without any further measures.


Indeed. By design. ;-)

Only once, sadly. So you can inherit from as many inside-out classes as
is good for you, plus one "normal" (type-committed) class.

One could wax philosophical about inside-out objects, how a normal inside-
in object holds everything of interest inside and nothing on the outside,
and thus, turning it inside-out, the core of an inside-out object becomes
an object-shaped void which is the former empty outside of the original,
and how this void can be filled with a normally functioning object
while the inside-out object continues to function because its function
is located on the outside, but I won't.

Instead, let me add a thought that is only loosely related. It seems
to me that inheritance and encapsulation don't go together (anywhere,
not only in Perl) in one respect. When it comes to overriding some
of the original methods, you must know how the methods in the base class
use (call) each other in order to predict the result. On the other hand,
that's an implementation detail that shouldn't concern the inheriting
class. I don't see how that can be resolved.

Anno
 
A

Anno Siegel

Abigail said:
Anno Siegel ([email protected]) wrote on MMMMCCCXLVIII
September MCMXCIII in <URL:() > Anno Siegel ([email protected]) wrote on MMMMCCCXLVII
() > September MCMXCIII in <URL:news:[email protected]>:

[multiple inheritance]
Unless you create some kind of has-a relationship. But this 'defect'
isn't restricted to inside-out objects. Whatever you do, it's going to
be hard to merge 2 hashes and 3 arrays. (Merging a single hash and a
single array would still be possible by overloading the object to have
@{} and %{} magic).

Overloading looks attractive and may work in specific cases, but the
restriction that no two classes be of the same type is too awkward to
be useful in a general class hierarchy. Also de-reference overloading
leads to problems with further inheritance.
But in practise, the wide-spread practise (sic) of configuring an object
in the constructor makes it already impossible to do MI without falling
back on a has-a relationship.

That's an interesting remark, and if I ever get that inheritance paper
written it will make an appearance there in one form or another.

[...]
() Instead, let me add a thought that is only loosely related. It seems
() to me that inheritance and encapsulation don't go together (anywhere,
() not only in Perl) in one respect. When it comes to overriding some
() of the original methods, you must know how the methods in the base class
() use (call) each other in order to predict the result. On the other hand,
() that's an implementation detail that shouldn't concern the inheriting
() class. I don't see how that can be resolved.

Well, IMO, it's a bad idea to override a proper subset of related methods.

Quite so, but how do you know which methods are related?
A lot of inheritance is done without overriding any methods - they are
merely adding functionality, not overriding any. Then you don't have
the problem you describe above. Furthermore, a lot of overriding is done
while still calling the overridden method using SUPER.

Sure, a lot can be done without overriding. A lot of useful OO applications
don't even use inheritance. But then, it is only overriding that lets
old code call new code in OO. If you don't need that feature, mere
delegation will do. So, for me, overriding is one of the more interesting
aspects of inheritance.
But if you have a statistical object with two methods, 'add' to add a
new number to the set, and 'average' to return the average of the set,
overriding either of 'add' or 'average', without calling SUPER:: is
unlikely to work properly.

Funny... the example I had in mind was also a statistical package, where
the user would have to know whether or not ->variance called ->mean before
overriding ->mean to calculate (say) the geometric mean. But the problem
occurs in everyday programming. When inheriting from Tie::Handle, which
of WRITE, PRINT, and PRINTF do you override to get what effect? Only
the source (or experimentation) will tell.

Anno
 
D

David Combs

A. Sinan Unur said:
(e-mail address removed)-berlin.de (Anno Siegel) wrote in
The code for the base class is mostly unchanged. The only difference
is that it inserts a do-nothing method (one that just returns its
object) into all of its accessors (not in other methods). So if the
accessor was

sub alpha { $_[ 0]->[ 0] }

it becomes

sub alpha { $_[ 0]->parent->[ 0] }
# ...
sub parent { shift }

[ rest of the discussion and code snipped ]

Anno:

I wanted to thank you very much for this series of posts, especially
this last one. I found it very informative.

Thankyou. It's nice to be appreciated. [As Brian (Nobull) just said in
another thread.]

In fact, I think I'll make a (not much) more extensive writeup of this
material and put it on the web (at least). The final trick deserves
publicity, if I say so myself, but even without it, more awareness of
accessors and their significance would help OO programming in Perl.

Anno


WHERE, WHERE?

WHEN, WHEN?

IF, IF?


Thanks from *lots* of people!

David
 

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,797
Messages
2,569,647
Members
45,378
Latest member
danzeev

Latest Threads

Top