Beefy Boxes and Bandwidth Generously Provided by pair Networks
good chemistry is complicated,
and a little bit messy -LW

Class::Struct question

by shemp (Deacon)
on Sep 14, 2004 at 16:24 UTC ( #390896=perlquestion: print w/replies, xml ) Need Help??
shemp has asked for the wisdom of the Perl Monks concerning the following question:

I was wondering if there is any way built-in to Class::Struct generated objects that would allow incrementing (and decrementing) in an overloaded sort of way, as opposed to building my own operator overloads. What i mean is, i'd like to be able to do something like:
use strict; use warnings; use Class::Struct; struct MyStruct => { 'Counter' => '$', ... } my $x = MyStruct('Counter', 0); $x->Counter++; # of course i could always do the following: $x->Counter( $x->Counter + 1 );
Is what i want to do directly possible (built-in)? I suppose i'd also like to be able to:
... $x->Counter += 7;
will i need to build my own overloads?

Replies are listed 'Best First'.
Re: Class::Struct question
by ikegami (Pope) on Sep 14, 2004 at 18:17 UTC

    On the plus side, it's possible, and you don't even need overloaded operators.

    use strict; use warnings; package MyStruct; sub new { my $class = shift(@_); return bless({@_}, $class); } sub Counter : lvalue { my $self = shift(@_); $self->{'Counter'} = $_[0] if (scalar(@_)); $self->{'Counter'} } package main; { my $x = MyStruct->new(Counter=>0); print($x->Counter, "\n"); # 0 $x->Counter($x->Counter + 1); print($x->Counter, "\n"); # 1 $x->Counter = $x->Counter + 1; print($x->Counter, "\n"); # 2 ++($x->Counter); print($x->Counter, "\n"); # 3 ++$x->Counter; print($x->Counter, "\n"); # 4 $x->Counter++; print($x->Counter, "\n"); # 5 $x->Counter += 1; print($x->Counter, "\n"); # 6 }

    On the downside, you can't use Class::Struct with this method, or you have modify it slightly. I think the changes are limited to the following:

    Change (untested)
    $out .= "  sub $name {$cmt\n    my \$r = shift;\n";
    $out .= "  sub $name : lvalue {$cmt\n    my \$r = shift;\n";
    and scalar accessors will be returned by lvalue. Array accessors and hash accessors need a little more changes, because they use 'return' than that wipes the lvalue-ness.

Re: Class::Struct question
by hardburn (Abbot) on Sep 14, 2004 at 16:36 UTC

    No, but for reasons that have nothing to do with Class::Struct, and everything about Perl OO and operator precedence. Since '++' binds more tightly than '->', when you say:


    According to B::Deparse, Perl translates that to:


    Which should then be tokenized into something like:

    (++$x) -> Counter

    Which is probably not at all what you want.

    Without knowing your specific situation, I would suggest looking more carefully at your object structure. What you're trying to do indicates to me that you're playing too closely to the object's internals.

    Update: Forget I said anything. See ikegami's response below.

    "There is no shame in being self-taught, only in not trying to learn in the first place." -- Atrus, Myst: The Book of D'ni.

      ++' binds more tightly than '->'

      That's not true. '->' is just above '++' in precedence. ++$x->Counter; is the same as ++($x->Counter);. The problem is that Counter does not return an lvalue. See the other post I'm making in this thread for an example.

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://390896]
Approved by fxmakers
and all is quiet...

How do I use this? | Other CB clients
Other Users?
Others scrutinizing the Monastery: (9)
As of 2017-01-23 15:27 GMT
Find Nodes?
    Voting Booth?
    Do you watch meteor showers?

    Results (192 votes). Check out past polls.