rob25 has asked for the wisdom of the Perl Monks concerning the following question:

Greetings,

at first the short form of my question(s) - direct from my heart to the monestary public. After that, I provide some more background.

In short:

I recently implemented some code inspired by a CPAN code example. Here is a snippet:

# add one handle and count it sub add_handle($$) { my $self = shift; my $easy = shift; $$self++; $self->SUPER::add_handle( $easy ); }

Why is it possible to use an object as a counter? Why does this not destroy the object? When I coded a similar thing for testing, the program breaks with the message "Not a scalar reference".

Background of the question:

The example comes form the Net-Curl-package (see https://metacpan.org/pod/distribution/Net-Curl/lib/Net/Curl/examples.pod#Extracted-from-examples/02-multi-simple.pl). I made a successful API implementation along this example. But while adopting the example this special bit of code (the $$self++) looks so wired to me, that I choose to replace it by somewhat more readable ($self->{MULTI_HANDLER_COUNT}++).
But now I did some profiling on the API, and I ask myself, whether there is the essential difference between the official example code and the way I implemented the counting.

I hope someone can give me some deeper insights about the difference.

Replies are listed 'Best First'.
Re: Why does $$self++ work?
by hippo (Archbishop) on Sep 28, 2018 at 09:56 UTC
    Why is it possible to use an object as a counter?

    You are not using the object as a counter but the de-reference of the object. $self is the object but it's also a reference to a scalar (since that's how you have constructed it). When you de-reference the object therefore you get a scalar and so $$self++ is incrementing the scalar. Since the example you mentioned starts with $active = 0, that's the value from which you will be incrementing.

      You are not using the object as a counter but the de-reference of the object

      The OP --not you-- has the correct terminology. The thing referenced is the object --the thing that is blessed-- not the reference.

      The code in question does indeed increment the object, which is unusually a scalar instead of a hash.

      Thanks to point me to the usage of $active in the constructor! By passing it as a reference, it is the scalar I access while dereferencing $self.
      Now, as understand whats going on, I will try to use this approach in my implementation, and see wether there will be a notable performance improvement. :-)

Re: Why does $$self++ works?
by LanX (Saint) on Sep 28, 2018 at 10:09 UTC
    Additional to hippo's answer:

    Most languages implement objects as "blessed" hashes, and that's also the overwhelming case in Perl.

    But in Perl you are free to use any reference as a container for the state of the instance.

    And that's what is happening here, you have a blessed scalar (ref)

    See bless ...

    update

    ... and perlobj#An-Object-is-Simply-a-Data-Structure

    > Objects are merely Perl data structures (hashes, arrays, scalars, filehandles, etc.) that have been explicitly associated with a particular class.

    > That explicit association is created by the built-in bless function, which is typically used within the constructor subroutine of the class.

    Cheers Rolf
    (addicted to the Perl Programming Language :)
    Wikisyntax for the Monastery FootballPerl is like chess, only without the dice

Re: Why does $$self++ works?
by davido (Cardinal) on Sep 28, 2018 at 13:48 UTC

    This is a blessed scalar. Something like this:

    sub new { my ($class, $initial_int) = @_;; my $scalar = 0+($initial_int // 0); return bless \$scalar, $class; }

    A more typical constructor would bless a hashref:

    sub new { my ($class, $args) = @_; die "Constructor args must be passed as a hash reference.\n" if defined($args) && ref($args) ne 'HASH'; $args //= {}; return bless $args, $class; }

    (Neither of these have a sufficient level of error checking on their input paramaters, and are intended as a demonstration only.)

    But we'll look at the blessed scalar reference, as it's what is probably at play here. The last piece is this:

    my $o = Foo->new(0); ${$o}++; # dereference $o, then increment the value of the scalar that + the scalar reference in $o points to. # Because the dereferencing sigil binds more closely than the postincr +ement operator, you can also do this: $$o++; # dereference $o, then increment the value of the scalar that t +he scalar reference in $o points to.

    Dave

Re: Why does $$self++ works?
by AnomalousMonk (Archbishop) on Sep 28, 2018 at 14:54 UTC