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

I have an object Which
sub new { my ($class)=@_; bless { _roundnum =>$_[1], _room =>$_[2], _judge =>$_[3], _type =>$_[4], _code =>$_[5], _contestants =>$_[6] },$class; } sub roundnum{ my ($self, $roundnum)=@_; $self->{_roundnum}=$roundnum if defined $roundnum; return $self->{_roundnum}; } ################################
Now when I write a simple testfile
use round; my $test=new round{roundnum=>1} $testval=$test->roundnum; print $testval

I get a hash back... Can someone explain this to me. I feel like this oo thing is more slippery every time I try it.

20040328 Edit by Corion: Added formatting

Replies are listed 'Best First'.
Re: OO Simple THing
by tinita (Parson) on Mar 28, 2004 at 19:48 UTC
    you probably want
    # untested sub new { my $class= shift; my %args = @_; my $self = {map { ("_$_" => $args{$_}) } qw(roundnum room judge type code contestants)}; bless $self, $class; }
    and you have to call it like:
    my $test=new round (roundnum=>1);
    in your example you're calling roundum() with a hashref as an argument {roundum => 1}

    update: and it's more common to use classnames with a first uppercase letter, just to distinguish it from pragmas (like strict, warnings, less etc.)
    also a good starter for programming oo-perl is one of the perldoc pages, like perlboot, perltoot etc.

Re: OO Simple THing
by graff (Chancellor) on Mar 28, 2004 at 19:53 UTC
    It might be useful to give us an idea of what you expected the output to be, given this code. Were you hoping it would print "1"?

    First off, the test program doesn't compile as posted -- there's no semi-colon at the end of the line for "my $test=new round...". Apart from that, you are using curly braces around the args being passed to "new round", which means you are passing an anonymous hash to the the "new" method for this object. Inside the object's "new" method, you are taking the first arg received after the class name as the value to assign to _round; since your test code is passing a reference to an anonymous hash as its first and only arg, this is what the "roundnum" method will return.

    On the other hand, if you were to use parens (like you're supposed to) instead of curlies around the args that you pass to "new round", you might still not get what you want, because your test code is now passing a list that looks like a "key=>value" pair, whereas the "new" method seems to be expecting just a list of values (no keys). So by just replacing curlies with parens, the test output is the string "roundnum", not the value "1". So make up your mind what sort of calling protocol you want, and write both the object and the test to use the same protocol.

    Hope that helps.

Re: OO Simple THing
by Aragorn (Curate) on Mar 28, 2004 at 19:49 UTC
    Two things:
    1. Use parentheses ('()') instead of braces ('{}') around the function arguments.
    2. Using roundnum => 1, you're passing a hash into the function. Call it like new round(1).

    Arjen

Re: OO Simple THing
by cormac (Acolyte) on Mar 28, 2004 at 20:39 UTC
    "I feel like this oo thing is more slippery every time I try it."

    These perldocs are very helpful: perlobj, perltooc, and perltoot.

    --
    Real men use curlies.

Re: OO Simple THing
by dragonchild (Archbishop) on Mar 29, 2004 at 00:17 UTC
    Try the following:
    package Round; sub new { my $class = shift; my %args = @_; my $self = {}; $self->{_$_} = $args{$_} for qw( roundnum room judge type code contestants ); bless $self, $class; } sub roundnum { my $self = shift; $self->{_roundnum} = shift if @_; $self->{_roundnum}; } ------------- use Round; my $test = Round->new( roundnum => 1 ); my $testval = $test->roundnum; print "$testval\n";

    That should give you the answer you're looking for.

    ------
    We are the carpenters and bricklayers of the Information Age.

    Then there are Damian modules.... *sigh* ... that's not about being less-lazy -- that's about being on some really good drugs -- you know, there is no spoon. - flyingmoose

      ITYM $self->{"_$_"}. What you've got compiles into $self->{$_->_}.

      $ perl -MO=Deparse -e 'print $self->{_$_};' print $$self{$_->_};
      $self->{_$_} = $args{$_} for qw( roundnum room judge type code contestants );

      The "_NAME" convention's purpose is a mnemonic one, and this (purpose) is not well served when used on $_. Don't you think it's better to use a named lexical for the for(each)?s scope here, dude?

      --
      Real men use curlies.

Re: OO Simple THing
by gpmartinson (Novice) on Mar 29, 2004 at 00:23 UTC
    I humbly thank you all for pointing me to the error in my ways and the source of my confusion. I submit the following: #!/usr/bin/perl; package Round;

    use strict;

    sub new {

    my $self = {};

    $self->{CODE} = undef;

    $self->{ROOM} = undef;

    $self->{TYPE} = undef;

    $self->{JUDGE} =undef;

    $self->{ROUNDNUM} =undef;

    $self->{CONTESTANTS} = [];

    bless($self);

    return $self;

    }

    sub roundnum{

    my $self=shift;

    if (@_) {$self->{ROUNDNUM}=shift }

    return $self->{ROUNDNUM};

    }

    etc...

    which does exactly what I want it to do. I know enough object code to get it to do what I want it to do, which is hide data and provide for a convenient storage. This place is wonderful! I am truly enlightened