still crabby about copy constuctor craziness

Discussion in 'Perl Misc' started by Unknown Poster, Jul 24, 2004.

  1. I'm not even able to verify that a "copy constructor" is called even when "="
    is overloaded and code like that on page 357 of Programming Perl 3E runs:

    $copy = $original;
    $++copy;
    ----------------------
    This is perl, v5.6.1 built for MSWin32-x86-multi-thread

    in my class:

    use overload "=" => \&c;


    sub c
    {
    # there was other code here, but it makes no difference
    print "in copy constructor \n";
    }


    I don't even know what a copy constructor ought to look like (an example
    in P.P is needed), but I have a print statement to at least show that
    the "c" sub is run. I run code using the class - there are no
    errors, but the print statement never outputs anything. What's going on?
     
    Unknown Poster, Jul 24, 2004
    #1
    1. Advertising

  2. (Unknown Poster) wrote in
    news::

    > I'm not even able to verify that a "copy constructor" is called even
    > when "=" is overloaded and code like that on page 357 of Programming
    > Perl 3E runs:
    >
    > $copy = $original;
    > $++copy;
    > ----------------------
    > This is perl, v5.6.1 built for MSWin32-x86-multi-thread
    >
    > in my class:
    >
    > use overload "=" => \&c;
    >
    >
    > sub c
    > {
    > # there was other code here, but it makes no difference
    > print "in copy constructor \n";
    > }
    >
    >
    > I don't even know what a copy constructor ought to look like (an
    > example in P.P is needed), but I have a print statement to at least
    > show that the "c" sub is run. I run code using the class - there are
    > no errors, but the print statement never outputs anything. What's
    > going on?


    I am not sure. I had not overloaded anything in Perl until I read this
    message and my curiosity led me to waste some time reading

    perldoc overload

    I came up with the following code. It is probably not a good idea to
    infer too much about the right way of doing things from my code but it
    seems work :) On the other hand, if you asked me why I overloaded the
    increment and the stringfication operators also, my only answer is
    because the code would not run without them.

    I am hoping someone more knowledgable than myself will offer some
    insights and corrections. Code follows:

    use strict;
    use warnings;

    package Copyable;

    sub new {
    my ($class, $value) = @_;
    bless \$value, $class;
    }

    sub value { ${$_[0]}; }

    use overload '=' => 'copyctor';
    use overload '++' => 'increment';
    use overload '""' => 'tostring';

    sub copyctor { my $copy = ${$_[0]}; bless \$copy; }

    sub increment { ++${$_[0]}; shift; }

    sub tostring { "${$_[0]}"; }

    package main;

    my $v = Copyable->new(10);

    my $z = $v;
    print ++$z;

    __END__

    C:\Home> copyctor.pl
    11
    --
    A. Sinan Unur
    d
    (remove '.invalid' and reverse each component for email address)
     
    A. Sinan Unur, Jul 24, 2004
    #2
    1. Advertising

  3. Unknown Poster

    Anno Siegel Guest

    Unknown Poster <> wrote in comp.lang.perl.misc:
    > I'm not even able to verify that a "copy constructor" is called even when "="
    > is overloaded and code like that on page 357 of Programming Perl 3E runs:
    >
    > $copy = $original;
    > $++copy;
    > ----------------------
    > This is perl, v5.6.1 built for MSWin32-x86-multi-thread
    >
    > in my class:
    >
    > use overload "=" => \&c;
    >
    >
    > sub c
    > {
    > # there was other code here, but it makes no difference
    > print "in copy constructor \n";
    > }
    >
    >
    > I don't even know what a copy constructor ought to look like (an example
    > in P.P is needed), but I have a print statement to at least show that
    > the "c" sub is run.


    I suppose, the author(s) thought, "copy constructor", i.e. "constructor
    of a copy", was self-explanatory. It is a method that returns a *copy*
    of the given object (as opposed to a pointer to the same object).

    > I run code using the class - there are no
    > errors, but the print statement never outputs anything. What's going on?


    Have you looked up "Copy Constructor" in "perldoc overload"? There it
    says:

    This operation is called in the situations when a mutator is applied to
    a reference that shares its object with some other reference, such as

    $a=$b;
    ++$a;

    Whatever that means in detail, it says that overloading "=" is only
    relevant in situations where you also overload a mutator, like "++".
    Since you don't do that, the operation for "=" never had a chance of
    being called.

    If you don't intend to overload mutators, don't worry about it.
    Understanding "=" is not essential to understanding overloading.
    It is a workaround for a nasty side-effect of overloading mutators.

    If you do intend to overload mutators, build another example that
    includes an overloaded mutator, and watch the copy constructor being
    called in the situation sketched in the doc.

    Anno
     
    Anno Siegel, Jul 24, 2004
    #3
  4. Unknown Poster

    J. Romano Guest

    (Unknown Poster) wrote in message news:<>...
    > I'm not even able to verify that a "copy constructor" is called even when "="
    > is overloaded and code like that on page 357 of Programming Perl 3E runs:
    >
    > $copy = $original;
    > $++copy;
    >
    > use overload "=" => \&c;


    Dear Unknown Poster,

    A few weeks ago (on June 26), I posted a write-up explaining this
    exact issue. I too was confused about this, even after reading the
    "Programming Perl" book and "perldoc overload".

    I recommend you read it. The subject is "Regarding copy
    constructors and mutators" and it was posted to the
    comp.lang.perl.misc newsgroup. This link should take you there:

    http://groups.google.com/groups?hl=

    This posting explains when the copy constructor gets called (and
    why). I spent a lot of time writing this, so I would appreciate it if
    people would at least try reading it when they experience "copy
    constructor crazyness". (It even contains a sample program so you can
    follow along and see exactly what's happening.)

    -- Jean-Luc
     
    J. Romano, Jul 24, 2004
    #4
  5. Unknown Poster

    Ben Morrow Guest

    Quoth (Unknown Poster):
    > I'm not even able to verify that a "copy constructor" is called even when "="
    > is overloaded and code like that on page 357 of Programming Perl 3E runs:
    >
    > $copy = $original;
    > $++copy;
    > ----------------------
    > This is perl, v5.6.1 built for MSWin32-x86-multi-thread
    >
    > in my class:
    >
    > use overload "=" => \&c;
    >
    > sub c
    > {
    > # there was other code here, but it makes no difference
    > print "in copy constructor \n";
    > }
    >
    >
    > I don't even know what a copy constructor ought to look like (an example
    > in P.P is needed),


    Have you read perldoc overload? You should *always* read the relevant
    perldocs as well as any books.

    The following may help you understand:

    #!/usr/bin/perl

    {{

    package CC;

    use subs qw/clone incr/;

    use overload '++' => \&incr, '=' => \&clone, '""' => \&str;

    sub new {
    my $c = shift;
    warn 'NEW';
    return bless \do {my $o = 0}, $c;
    }

    sub clone {
    my $s = shift;
    warn 'CLONE';
    return bless \do {my $o = $$s}, ref $s;
    }

    sub incr {
    my $s = shift;
    warn 'INCR';
    return ++$$s;
    }

    sub str {
    my $s = shift;
    return $$s;
    }

    }}

    warn 'about to call NEW';
    my $x = CC->new;
    warn 'about to copy';
    my $y = $x;
    warn 'about to incr';
    $x++;
    warn 'done';

    __END__

    about to call NEW at cc line 31.
    NEW at cc line 13.
    about to copy at cc line 33.
    about to incr at cc line 35.
    CLONE at cc line 19.
    INCR at cc line 25.
    done: 1, 0 at cc line 37.

    Ben

    --
    Razors pain you / Rivers are damp
    Acids stain you / And drugs cause cramp. [Dorothy Parker]
    Guns aren't lawful / Nooses give
    Gas smells awful / You might as well live.
     
    Ben Morrow, Jul 25, 2004
    #5
  6. Perhaps the implementation of 5.6 on Windows is just messed up. The behavior
    I see simply does not match what is in the Camel book. If the guy who wrote
    Perl can't explain how it's supposed to work, who am I supposed to believe?

    First, this sentence on page 357, is, to put it charitably, misleading:

    "The handler for = is used in situations where a mutator (such as ++,
    --, or any of the assigment operators) is applied to a reference that
    shares its object with another reference."

    It ought to be ""... where an explicitly overloaded mutator ..."

    Anyway, this means that a user of a class doesn't
    know if a copy constructor will be called unless he/she knows if
    the mutator has been explicitly overloaded. Simply unacceptable.


    Now, this is just wrong, at least in my environment - page 354:

    "The ++$a operation can be autogenerated ... However, this does not
    trigger the copying behavior that a real ++ operator would."

    My ++ is autogenerated. If it did NOT cause copying then $a == $b
    after $a = $b; ++$a; Nope, $a is one more than $b when I run this code.

    Likewise, again on page 357:
    "$copy = $original; $copy = $copy + 1;
    then no copying occurs ..."

    Again, $copy is one more than $original, so copying certainly did occur.

    Maybe this mess will be fixed in Perl 6. Otherwise, there's always Java -
    no such thing as a copy constructor, and no operator overloading.
     
    Unknown Poster, Jul 28, 2004
    #6
  7. Unknown Poster

    Jay Tilton Guest

    (Unknown Poster) wrote:

    : Perhaps the implementation of 5.6 on Windows is just messed up. The behavior
    : I see simply does not match what is in the Camel book.

    Share with us a _complete_ program that demonstrates this discontinuity
    between specification and implentation.

    : If the guy who wrote
    : Perl can't explain how it's supposed to work, who am I supposed to believe?
    :
    : First, this sentence on page 357, is, to put it charitably, misleading:
    :
    : "The handler for = is used in situations where a mutator (such as ++,
    : --, or any of the assigment operators) is applied to a reference that
    : shares its object with another reference."
    :
    : It ought to be ""... where an explicitly overloaded mutator ..."

    Go ahead and submit a documentation patch.

    : Anyway, this means that a user of a class doesn't
    : know if a copy constructor will be called unless he/she knows if
    : the mutator has been explicitly overloaded. Simply unacceptable.

    Defining appropriate behavior when instances of a class are mutated is the
    job for the class's author, not for the user and not for you.

    : Now, this is just wrong, at least in my environment - page 354:
    :
    : "The ++$a operation can be autogenerated ... However, this does not
    : trigger the copying behavior that a real ++ operator would."
    :
    : My ++ is autogenerated. If it did NOT cause copying then $a == $b
    : after $a = $b; ++$a; Nope, $a is one more than $b when I run this code.

    Because you have not shown the class and its operator overloaders, your
    assumptions on what has been autogenerated, your test and your
    interpretation of its results are meaningless.

    : Likewise, again on page 357:
    : "$copy = $original; $copy = $copy + 1;
    : then no copying occurs ..."
    :
    : Again, $copy is one more than $original, so copying certainly did occur.

    Again, because you have not shown the class, you've demonstrated nothing.
    You certainly haven't shown that Perl's documentation is wrong.

    : Maybe this mess will be fixed in Perl 6. Otherwise, there's always Java -
    : no such thing as a copy constructor, and no operator overloading.

    Or you could simply not use that feature in your Perl code.
     
    Jay Tilton, Jul 28, 2004
    #7
  8. (Jay Tilton) wrote in message news:<>...

    >
    > : Anyway, this means that a user of a class doesn't
    > : know if a copy constructor will be called unless he/she knows if
    > : the mutator has been explicitly overloaded. Simply unacceptable.
    >
    > Defining appropriate behavior when instances of a class are mutated is the
    > job for the class's author, not for the user and not for you.



    You've got to be joking. This is a violation of abstraction atits most
    basic. The whole point of OO is to separate interface from implementation,
    and this situation is as blatant a mixing of the two as you can get.

    Perhaps Wall, Christiansen, and Orant are all afraid of the number 13,
    as evidenced by this chapter being written in such a sloppy manner.
    Here's another gem from page 357:

    "If the copy constructor is required during the execution of some
    mutator, but a handler for = was not specified, it can be autogenerated
    as a string copy provided the object is a plain scalar and not
    something fancier."

    I would REALLY love to see an example of a "plain scalar" that is an object.
    Heck, I wouldn't even call a reference to an object a "plain scalar".

    >
    > : Now, this is just wrong, at least in my environment - page 354:
    > :
    > : "The ++$a operation can be autogenerated ... However, this does not
    > : trigger the copying behavior that a real ++ operator would."
    > :
    > : My ++ is autogenerated. If it did NOT cause copying then $a == $b
    > : after $a = $b; ++$a; Nope, $a is one more than $b when I run this code.
    >
    > Because you have not shown the class and its operator overloaders, your
    > assumptions on what has been autogenerated, your test and your
    > interpretation of its results are meaningless.
    >


    It's not explicitly overloaded, "fallback" is not set, there is no
    "nomethod" handler, and the code runs without raising an exception,
    so unless the Tooth Fairy has overloaded "++", it must (according
    to the rules) be autogenerated.

    > : Likewise, again on page 357:
    > : "$copy = $original; $copy = $copy + 1;
    > : then no copying occurs ..."
    > :
    > : Again, $copy is one more than $original, so copying certainly did occur.
    >
    > Again, because you have not shown the class, you've demonstrated nothing.
    > You certainly haven't shown that Perl's documentation is wrong.


    Oh, yes I have ... see above
    >
    > : Maybe this mess will be fixed in Perl 6. Otherwise, there's always Java -
    > : no such thing as a copy constructor, and no operator overloading.
    >
    > Or you could simply not use that feature in your Perl code.


    Better yet, the Perl gurus could design an "object oriented Perl" that
    actually follows the tenents of OOP.

    BTW, don't you just love the way you can "overload" a non-existent operator,
    and get no error, no exception, no warning?
     
    Unknown Poster, Jul 29, 2004
    #8
  9. Unknown Poster

    Anno Siegel Guest

    Unknown Poster <> wrote in comp.lang.perl.misc:
    > (Jay Tilton) wrote in message
    > news:<>...
    >
    > >
    > > : Anyway, this means that a user of a class doesn't
    > > : know if a copy constructor will be called unless he/she knows if
    > > : the mutator has been explicitly overloaded. Simply unacceptable.
    > >
    > > Defining appropriate behavior when instances of a class are mutated is the
    > > job for the class's author, not for the user and not for you.

    >
    >
    > You've got to be joking. This is a violation of abstraction atits most
    > basic. The whole point of OO is to separate interface from implementation,
    > and this situation is as blatant a mixing of the two as you can get.


    Yup.

    Perl's approach to (not only) OO is pragmatic and minimalistic. You get
    the stuff necessary to implement OO, but little care has been taken to
    enforce the tenets of OO, like separation of implementation and interface,
    encapsulation, private methods and what have you. Mind you, you can
    implement all that in Perl, as Damian Conway demonstrates in _Object
    Oriented Perl_, but very little is enforced from the get-go. Even plain
    inheritance must be supported by the class author, it doesn't come for
    free.

    You find that deplorable, you may even say that, then, Perl OO isn't
    OO at all. You wouldn't be the first to say so, and you'd be in good
    company. Abigail has said things to that effect and, afaik has not
    published OO Perl code.

    Others go ahead with what's there and implement quite impressive
    software with Perl OO methods. It's your choice. If you want
    Java, you know where to find it.

    > Perhaps Wall, Christiansen, and Orant are all afraid of the number 13,
    > as evidenced by this chapter being written in such a sloppy manner.
    > Here's another gem from page 357:
    >
    > "If the copy constructor is required during the execution of some
    > mutator, but a handler for = was not specified, it can be autogenerated
    > as a string copy provided the object is a plain scalar and not
    > something fancier."
    >
    > I would REALLY love to see an example of a "plain scalar" that is an object.
    > Heck, I wouldn't even call a reference to an object a "plain scalar".


    Nor should you.

    Perl parlance with respect to references is traditionally sloppy. We
    often speak of "arrays" and "hashes" where "array reference" and "hash
    reference" would be correct. Even more so, we say "object" when what
    we really have is an "object reference". That is because we *must*
    access an object through a reference. The object itself, the under-
    lying (blessed) data structure is rather useless (and taboo, under
    OO strictures).

    So, in my view, saying that an object is a plain scalar is in fact
    correct. Calling a ref to the scalar an "object" is common practice,
    but sloppy.

    Otherwise, I am quite with you that the documentation of Perl's overloading
    could be better written. I have struggled with it myself.

    The documentation is as open as the source. Until someone sits down
    and re-writes the overload chapter, we got to work with what we have.

    [big snip]

    > Better yet, the Perl gurus could design an "object oriented Perl" that
    > actually follows the tenents of OOP.


    Tenets. Perl 6 will most likely be that. The current implementation
    deliberately is not. That gives us additional degrees of freedom, for
    instance to use one aspect of OO but not others. The Exporter module
    uses inheritance, but little more. I wouldn't call it a class.

    > BTW, don't you just love the way you can "overload" a non-existent operator,
    > and get no error, no exception, no warning?


    Minor quibble. Report a bug if it bothers you. I'm sure it is trivial
    to fix.

    Anno
     
    Anno Siegel, Jul 29, 2004
    #9
  10. Unknown Poster

    Anno Siegel Guest

    Unknown Poster <> wrote in comp.lang.perl.misc:
    > (Jay Tilton) wrote in message
    > news:<>...
    >
    > >
    > > : Anyway, this means that a user of a class doesn't
    > > : know if a copy constructor will be called unless he/she knows if
    > > : the mutator has been explicitly overloaded. Simply unacceptable.
    > >
    > > Defining appropriate behavior when instances of a class are mutated is the
    > > job for the class's author, not for the user and not for you.

    >
    >
    > You've got to be joking. This is a violation of abstraction atits most
    > basic. The whole point of OO is to separate interface from implementation,
    > and this situation is as blatant a mixing of the two as you can get.


    Yup.

    Perl's approach to (not only) OO is pragmatic and minimalistic. You get
    the stuff necessary to implement OO, but little care has been taken to
    enforce the tenets of OO, like separation of implementation and interface,
    encapsulation, private methods and what have you. Mind you, you can
    implement all that in Perl, as Damian Conway demonstrates in _Object
    Oriented Perl_, but very little is enforced from the get-go. Even plain
    inheritance must be supported by the class author, it doesn't come for
    free.

    You may find that deplorable, you may even say that, then, Perl OO isn't
    OO at all. You wouldn't be the first to say so, and you'd be in good
    company. Abigail has said things to that effect and, afaik has not
    published OO Perl code.

    Others go ahead with what's there and implement quite impressive
    software with Perl OO methods. It's your choice. If you want
    Java, you know where to find it.

    > Perhaps Wall, Christiansen, and Orant are all afraid of the number 13,
    > as evidenced by this chapter being written in such a sloppy manner.
    > Here's another gem from page 357:
    >
    > "If the copy constructor is required during the execution of some
    > mutator, but a handler for = was not specified, it can be autogenerated
    > as a string copy provided the object is a plain scalar and not
    > something fancier."
    >
    > I would REALLY love to see an example of a "plain scalar" that is an object.
    > Heck, I wouldn't even call a reference to an object a "plain scalar".


    Nor should you.

    Perl parlance with respect to references is traditionally sloppy. We
    often speak of "arrays" and "hashes" where "array reference" and "hash
    reference" would be correct. Even more so, we say "object" when what
    we really have is an "object reference". Because we *must* access an
    object through a reference, the term "object reference" is rarely used.
    The object itself, the underlying (blessed) data structure is rather
    useless (and taboo, under OO strictures), so it doesn't hurt (much)
    that there is no distinct term for it.

    So, in my view, saying that an object is a plain scalar is in fact
    correct. Calling a ref to the scalar an "object" is common practice,
    but sloppy.

    Otherwise, I am quite with you that the documentation of Perl's overloading
    could be better written. I have struggled with it myself.

    The documentation is as open as the source. Until someone sits down
    and re-writes the overload chapter, we got to work with what we have.

    [big snip]

    > Better yet, the Perl gurus could design an "object oriented Perl" that
    > actually follows the tenents of OOP.


    Tenets. Perl 6 will most likely be that. The current implementation
    deliberately is not. That gives us additional degrees of freedom, for
    instance to use one aspect of OO but not others. The Exporter module
    uses inheritance, but little more. I wouldn't call it a class.

    > BTW, don't you just love the way you can "overload" a non-existent operator,
    > and get no error, no exception, no warning?


    Minor quibble. Report a bug if it bothers you. I'm sure it is trivial
    to fix.

    Anno
     
    Anno Siegel, Jul 29, 2004
    #10
  11. Unknown Poster

    Ben Morrow Guest

    [you're very close to going in the killfile. I'd tone down your comments
    *just* a little if I were you...]

    Quoth (Unknown Poster):
    > (Jay Tilton) wrote in message news:<>...
    >
    > >
    > > : Anyway, this means that a user of a class doesn't
    > > : know if a copy constructor will be called unless he/she knows if
    > > : the mutator has been explicitly overloaded. Simply unacceptable.
    > >
    > > Defining appropriate behavior when instances of a class are mutated is the
    > > job for the class's author, not for the user and not for you.

    >
    > You've got to be joking. This is a violation of abstraction atits most
    > basic. The whole point of OO is to separate interface from implementation,
    > and this situation is as blatant a mixing of the two as you can get.


    Please explain... AFAICS, the only person who needs to know if a copy
    constructor is called or not is the class's author, and they are exactly
    the only person who knows whether ++ was explicitly overloaded or not.
    Am I missing something?

    > Perhaps Wall, Christiansen, and Orant are all afraid of the number 13,
    > as evidenced by this chapter being written in such a sloppy manner.


    Rudeness will get you nowhere, fast.

    > Here's another gem from page 357:
    >
    > "If the copy constructor is required during the execution of some
    > mutator, but a handler for = was not specified, it can be autogenerated
    > as a string copy provided the object is a plain scalar and not
    > something fancier."
    >
    > I would REALLY love to see an example of a "plain scalar" that is an object.
    > Heck, I wouldn't even call a reference to an object a "plain scalar".


    <*seriously* picky mode>
    The object is the refer*ant*, not the reference. It is the referant
    which is blessed, not the reference (even though the blessing is done
    through a ref). Thus

    sub new {
    return bless \do { my $o = "hello world" }, shift;
    }

    is a constructor for an object which is a plain scalar: that is, it
    creates a scalar, blesses it and returns a ref to it.

    > > : Now, this is just wrong, at least in my environment - page 354:
    > > :
    > > : "The ++$a operation can be autogenerated ... However, this does not
    > > : trigger the copying behavior that a real ++ operator would."
    > > :
    > > : My ++ is autogenerated. If it did NOT cause copying then $a == $b
    > > : after $a = $b; ++$a; Nope, $a is one more than $b when I run this code.


    $a and $b are both refs, so to say '$a is one more than $b' is
    meaningless.

    > > Because you have not shown the class and its operator overloaders, your
    > > assumptions on what has been autogenerated, your test and your
    > > interpretation of its results are meaningless.

    >
    > It's not explicitly overloaded, "fallback" is not set, there is no
    > "nomethod" handler, and the code runs without raising an exception,
    > so unless the Tooth Fairy has overloaded "++", it must (according
    > to the rules) be autogenerated.


    Can you post a complete working program that demonstrates, please?

    > > : Maybe this mess will be fixed in Perl 6. Otherwise, there's always Java -
    > > : no such thing as a copy constructor, and no operator overloading.
    > >
    > > Or you could simply not use that feature in your Perl code.

    >
    > Better yet, the Perl gurus could design an "object oriented Perl" that
    > actually follows the tenents of OOP.


    ....or you could simply learn how OO works in Perl?

    > BTW, don't you just love the way you can "overload" a non-existent operator,
    > and get no error, no exception, no warning?


    This is a forward-compatibility feature. If new overloadable tags are
    added later, old perls running new programs will simply ignore them.

    Ben

    --
    Every twenty-four hours about 34k children die from the effects of poverty.
    Meanwhile, the latest estimate is that 2800 people died on 9/11, so it's like
    that image, that ghastly, grey-billowing, double-barrelled fall, repeated
    twelve times every day. Full of children. [Iain Banks]
     
    Ben Morrow, Jul 29, 2004
    #11
  12. Unknown Poster

    Jay Tilton Guest

    (Unknown Poster) wrote:

    : (Jay Tilton) wrote in message news:<>...
    :
    : > : Now, this is just wrong, at least in my environment - page 354:
    : > :
    : > : "The ++$a operation can be autogenerated ... However, this does not
    : > : trigger the copying behavior that a real ++ operator would."
    : > :
    : > : My ++ is autogenerated. If it did NOT cause copying then $a == $b
    : > : after $a = $b; ++$a; Nope, $a is one more than $b when I run this code.
    : >
    : > Because you have not shown the class and its operator overloaders, your
    : > assumptions on what has been autogenerated, your test and your
    : > interpretation of its results are meaningless.
    :
    : It's not explicitly overloaded, "fallback" is not set, there is no
    : "nomethod" handler, and the code runs without raising an exception,
    : so unless the Tooth Fairy has overloaded "++", it must (according
    : to the rules) be autogenerated.

    That's nice, dear. Are you going to show the class or not?
     
    Jay Tilton, Jul 30, 2004
    #12
  13. Unknown Poster

    J. Romano Guest

    (Unknown Poster) wrote in message news:<>...

    > Anyway, this means that a user of a class doesn't
    > know if a copy constructor will be called unless he/she knows if
    > the mutator has been explicitly overloaded. Simply unacceptable.


    I don't think it's unacceptable. When the copy constructor gets
    called is the business of the programmer who wrote the class. If the
    class writer wrote the class well, then the user of the class doesn't
    have to concern him/herself with when the copy constructor gets called
    or if a mutator has been explicitly overloaded.

    Consider the Math::BigInt package. Over the years, there have been
    different implementations of this class. Old versions of Math::BigInt
    would autogenerate certain mutators (like "++" and "--"), but the
    newest version explicitly overloads them (for efficiency's sake).
    Calls to Math::BigInt's copy constructor will happen in one version
    where it will not happen in the other. Yet the output is the same,
    meaning that a programmer that uses Math::BigInt does not need to know
    about Math::BigInt's internals like when the copy constructor will be
    called or when a mutator has been explicitly overloaded. There is
    nothing unacceptable about this.

    > Now, this is just wrong, at least in my environment - page 354:
    >
    > "The ++$a operation can be autogenerated ... However, this does not
    > trigger the copying behavior that a real ++ operator would."
    >
    > My ++ is autogenerated. If it did NOT cause copying then $a == $b
    > after $a = $b; ++$a; Nope, $a is one more than $b when I run this code.
    >
    > Likewise, again on page 357:
    > "$copy = $original; $copy = $copy + 1;
    > then no copying occurs ..."
    >
    > Again, $copy is one more than $original, so copying certainly did occur.


    No, you are mistaken. Copying DID NOT occur. Examine the
    following lines carefully:

    $a = $b;
    ++$a;

    When the '++' operator is autogenerated, these lines are equivalent
    to:

    $a = $b;
    $a = $a + 1;

    which DOES NOT call the copy constructor. Instead, the function used
    for overloading the '+' operator is called, which normally creates a
    new object, populates that object from $a and 1, then returns that new
    object, which then gets assigned to $a WITHOUT ever modifying $b. In
    other words, no copy of $b was every made or needed (which is why I
    said that you are mistaken when you claim that copying certainly did
    occur).

    Confusing? A little. That's exactly why I posted a write-up
    explaining this exact issue. I even posted the title of this write-up
    ("Regarding copy constructors and mutators") to you, and even included
    a link to it. It seems like you didn't read it, so I invite you to
    read it again so that your confusion about this subject can be cleared
    up. In case you missed the link the first time around, here it is
    again:

    http://groups.google.com/groups?hl=

    And if you want the exact excerpt that deals with this topic
    (without having to look for it), here it is (paraphrased to fit your
    example):


    === Beginnining of excerpt ===

    The line:

    ++$a;

    was treated as if it was:

    $a = $a + 1;

    making it so that the function used for '+', and not for '++', was
    used. The
    function used for '+' does NOT mutate (or change) any parameter passed
    in. Instead, that method creates a new object, modifies its value,
    and returns that instance. This mutates the new object but it doesn't
    affect either of the values passed in. Because of this, '+' isn't
    considered by Perl to be a mutator, so it will not call the copy
    constructor (and will not give an error if a copy constructor doesn't
    exist). It just simply creates a new object from $a and 1 and assigns
    it back to $a, making $a lose its original object reference.

    CLARIFICATION:
    If '+=' is used on a shared reference when '+=' is OVERLOADED, it WILL
    call the copy constructor. But if it is AUTOGENERATED (from '+'), it
    WILL NOT call the copy constructor, because '+' has no need for one.

    The same goes for '++'. If it's not overloaded, Perl is smart enough
    to autogenerate by converting "$a++" to "$a = $a + 1" (which doesn't
    need the copy constructor) to give you exactly what you'd expect.

    === End of excerpt ===


    Basically, what Anno Siegel wrote in an earlier post was absolutely
    correct:

    > > If you don't intend to overload mutators, don't worry about it.
    > > Understanding "=" is not essential to understanding overloading.
    > > It is a workaround for a nasty side-effect of overloading mutators.


    So unless you plan to overload mutators, don't worry about it at all.
    (There is nothing unacceptable about that.)

    > Maybe this mess will be fixed in Perl 6. Otherwise, there's always Java -
    > no such thing as a copy constructor, and no operator overloading.


    Maybe this "mess" will be understood when you get around to reading
    the write-up I posted (intended for the Perl community and anyone
    confused (like I was) about "Copy Constructor Crazyness"). You are
    one of the people I posted that write-up for, so please read it before
    criticizing this aspect of Perl again.

    Hopefully this will clear the issue for you.

    -- Jean-Luc
     
    J. Romano, Jul 30, 2004
    #13
  14. Unknown Poster

    Joe Smith Guest

    Unknown Poster wrote:

    > "The handler for = is used in situations where a mutator (such as ++,
    > --, or any of the assigment operators) is applied to a reference that
    > shares its object with another reference."
    >
    > It ought to be ""... where an explicitly overloaded mutator ..."


    No, it happens for all mutators.

    > "The ++$a operation can be autogenerated ... However, this does not
    > trigger the copying behavior that a real ++ operator would."
    >
    > My ++ is autogenerated. If it did NOT cause copying then $a == $b
    > after $a = $b; ++$a; Nope, $a is one more than $b when I run this code.
    >
    > Likewise, again on page 357:
    > "$copy = $original; $copy = $copy + 1;
    > then no copying occurs ..."
    >
    > Again, $copy is one more than $original, so copying certainly did occur.


    The word 'copy' means something different.

    You've got to remember that the equal sign creates a copy-on-write reference
    to what is on the right hand side.

    $b = 'z' x 1_000_000; # Create a string of one million asterisks.
    $a = $b; # $a is a copy-on-write reference to $b's string.
    $a .= 'z'; # This is a mutator. A copy of $a is created,
    # then the copy gets a 'z' appended to it.
    $a = $b; # Set $a back to a copy-on-write reference
    $b .= 'y'; # A copy of $a is created, then $b gets modified.
    $a = $b; # Back to the 1,000,001 character string.
    $a = ':' . $a; # Create a new object (new string) and set its value.
    $a = $b; # Back to the 1,000,001 character string.
    $a = $a . 'w'; # Like the ':' case, a new object is created.
    # The old object's value is used. This is
    # not the same as using a copy of an object.

    The overloaded '=' operator is called when a shared object is going to
    be updated in place. There is a definite distinction between creating a
    full-blown exact copy of an object versus duplicating an object's value.

    $n++; # Is update-in-place; copy if needed before updating.
    $n = $n + 1' # Not update-in-place; build a new object, add, store.

    -Joe
     
    Joe Smith, Jul 30, 2004
    #14
  15. The Camel authors may have their own idea, but I don't think there
    is any argument about what the word "copy" means. The bottom line
    is that Perl ALWAYS does object copying in the situations discussed in this
    thread. The anomaly is, that for some bizarre reason, when you explicitly
    overload "++" or another "mutator", you are forced to write a so-called
    "copy constructor" by overloading "=".

    To add to the fun, here's another whopper from page 357:
    "The need for copying is recognized only by mutators ... If the operation
    is autogenerated via +, as in: $copy = $original; $copy = $copy + 1;
    then no copying occurs ..."

    What operation? I think they might mean that a copy constructor is
    autogenerated. Who knows?

    Anyway, copying most definitely does occur if $copy and $original
    are object references, and you (as you must) overload "++" to work
    on objects of the class. This is not some magical, temporary copying
    that only affects the "+ 1" line above. It's easy to demonstrate.
    Simply change the value of either object after the addition, then
    display the values. Since they differ, this proves that $copy
    and $original now refer to two distinct objects. How'd that happen?
    C-O-P-Y
     
    Unknown Poster, Jul 30, 2004
    #15
  16. Unknown Poster

    Anno Siegel Guest

    Unknown Poster <> wrote in comp.lang.perl.misc:
    > The Camel authors may have their own idea, but I don't think there
    > is any argument about what the word "copy" means. The bottom line
    > is that Perl ALWAYS does object copying in the situations discussed in this
    > thread.


    No. See below.

    > The anomaly is, that for some bizarre reason, when you explicitly
    > overload "++" or another "mutator", you are forced to write a so-called
    > "copy constructor" by overloading "=".


    Yes. You *must* tell it how to make a copy of an object, if you want
    it to protect an original from being changed along with the copy.

    > To add to the fun, here's another whopper from page 357:
    > "The need for copying is recognized only by mutators ... If the operation
    > is autogenerated via +, as in: $copy = $original; $copy = $copy + 1;
    > then no copying occurs ..."
    >
    > What operation? I think they might mean that a copy constructor is
    > autogenerated. Who knows?


    No, the "+=" operation. It can be autogenerated using "+". Now,
    "+" doesn't need to protect its operands. Any reasonable implementation
    of "+" will leave the operands alone and create a new object containing
    the sum. So there's no need for the copy constructor.

    > Anyway, copying most definitely does occur if $copy and $original
    > are object references, and you (as you must) overload "++" to work
    > on objects of the class.


    No, nothing is copied. Addition creates an independent sum object.

    And where did you get that one *must* overload "++"?

    > This is not some magical, temporary copying
    > that only affects the "+ 1" line above.


    Huh?

    > It's easy to demonstrate.
    > Simply change the value of either object after the addition, then
    > display the values. Since they differ, this proves that $copy
    > and $original now refer to two distinct objects. How'd that happen?
    > C-O-P-Y


    Again, no. Your exasperation is getting tedious.

    The copy constructor is only needed when an actual mutator method is
    used to overload "+=" (or "++", or another potentially mutating operation).
    A mutator method changes the content of a given object, as opposed to
    creating a new object with modified content.

    Only then, that is if "+=" is *explicitly overloaded* will the copy
    constructor be called. It is not needed when "+=" is autogenerated.

    Anno
     
    Anno Siegel, Jul 30, 2004
    #16
  17. [A complimentary Cc of this posting was sent to
    Unknown Poster
    <>], who wrote in article <>:

    > BTW, don't you just love the way you can "overload" a non-existent operator,
    > and get no error, no exception, no warning?


    *I* do. This way I can easily write modules which work with different
    versions of perl, which have different lists of overloadable operators.

    But indeed, having something like

    use overload strict => 1, '+0' => \&numify;

    would be a good thing. Feel free to do this if you want to.

    Yours,
    Ilya
     
    Ilya Zakharevich, Aug 2, 2004
    #17
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Alexander Stippler
    Replies:
    3
    Views:
    446
    Leor Zolman
    Apr 9, 2004
  2. Tapeesh

    Default constuctor

    Tapeesh, Mar 1, 2005, in forum: C++
    Replies:
    4
    Views:
    469
    John Carson
    Mar 2, 2005
  3. Replies:
    18
    Views:
    516
    Steve Pope
    Oct 5, 2006
  4. Sid K
    Replies:
    2
    Views:
    274
    Sid K
    Aug 7, 2008
  5. Unknown Poster

    Copy Constructor Craziness

    Unknown Poster, Feb 4, 2004, in forum: Perl Misc
    Replies:
    6
    Views:
    156
    Jay Tilton
    Feb 9, 2004
Loading...

Share This Page