Learning OO, object creation query.

J

Justin C

I've been reading various OO tutorials and other references on the web
(I found <URL: http://www.perlmonks.org/?node_id=218778> more useful
than perlboot and perltoo - though they are more clear to me now). To
see if I'm understanding correctly I'm writing something that has little
use other than educating me.

I have a module:

package My_Product;

use strict;

sub new {
my $class = shift;
my $item = shift;
my $style = shift;
my $price = shift;
my @sizes = @_;
my $self = {
ITEM => $item,
STYLE => $style,
PRICE => $price,
SIZES => @sizes,
};
return bless $self, $class;
}

I'm creating a new object with:

my $item = MM_Product->new($fields[0], $fields[1], $fields[2], @sizes);

But when I later do
foreach my $size ($item->{SIZES}) {
...
}

I only get the first item of the array.

I know that there are several items in the array when it's passed to the
new object, but I don't know how to be sure that it arrived at the
object, and that, therefore, it's there when I want to access it.

Here's a working version of the program (if you create the above module
too) it's as short as I could make it.

#!/usr/bin/perl

use warnings;
use strict;
use My_Product;

my @items;
foreach (<DATA>) {
chomp;
my @fields = split /:/;
my $size_count = length $fields[3];
my @sizes;
for (my $i = 0; $i < $size_count; $i++) {
my $size = substr($fields[3], $i, 1);
push @sizes, $size;
}
my $item = My_Product->new($fields[0], $fields[1], $fields[2], @sizes);
push @items, $item;
}

foreach my $item (@items) {
foreach my $size ( $item->{SIZES} ) {
printf("%-4s %-20s %-20s %7.2f \n", $size, $item->{ITEM}, $item->{STYLE}, $item->{PRICE});
}
}


__DATA__
AVS1234:TS:6.99:678ABCD
DMBT007:HS:7.99:BCD
G12128C:TS:8.99:ABCD


Thank you for any help you can give with this.

Justin.
 
W

Willem

Justin C wrote:
) I've been reading various OO tutorials and other references on the web
) (I found <URL: http://www.perlmonks.org/?node_id=218778> more useful
) than perlboot and perltoo - though they are more clear to me now). To
) see if I'm understanding correctly I'm writing something that has little
) use other than educating me.

Your problem has nothing to do with OO.
Here's a simple program that demonstrates the same problem:

sub foo {
my @sizes = @_;
my $hash = {
SIZES => @sizes,
};
return $hash;
}
my $hash = foo(1, 2, 3);
for my $item ($hash->{SIZES}) { print $item }

To find the answer to your problem, read up on references (perlreftut ?).

Simply put: you can't use an array as a value in a hash, and when you do it
will get expanded to a list.

Assuming: @sizes = (1, 2, 3)
This: { SIZES => @sizes }
Gets expanded to: { 'SIZES', 1, 2, 3 }
Or, equivalently: { SIZES => 1, 2 => 3 }

What you want is either: { SIZES => \@sizes } or: { SIZES => [@sizes] }

Be sure to read up on perldoc perlreftut and you'd also do good to read
some more about basic Perl.


SaSW, Willem
--
Disclaimer: I am in no way responsible for any of the statements
made in the above text. For all I know I might be
drugged or something..
No I'm not paranoid. You all think I'm paranoid, don't you !
#EOT
 
D

Dr.Ruud

Justin said:
I've been reading various OO tutorials and other references on the web
(I found <URL: http://www.perlmonks.org/?node_id=218778> more useful
than perlboot and perltoo - though they are more clear to me now). To
see if I'm understanding correctly I'm writing something that has little
use other than educating me.

I have a module:

package My_Product;

use strict;

sub new {
my $class = shift;
my $item = shift;
my $style = shift;
my $price = shift;
my @sizes = @_;
my $self = {
ITEM => $item,
STYLE => $style,
PRICE => $price,
SIZES => @sizes,
};
return bless $self, $class;
}

The error is in "=> @sizes", you probably meant "=> \@sizes".

I would rather split a new() like that into a new() and an init().


$ cat My_Product.pm
package My_Product;
use strict;
use warnings;
our $VERSION = "1.00";

sub new {
my $class= shift;
my $self= bless {}, $class;
return $self->init(@_);
}

sub init {
my $self= shift;
$self->{ style }= shift;
$self->{ item }= shift;
$self->{ price }= shift;
$self->{ sizes }= [ @_ ];
return $self;
}



$ perl -MData::Dumper -MMy_Product -wle'
my $p= My_Product::->new("printed", "T-shirt", 42, "XXL", "M");
print Dumper($p);
$p->init("white", "paper", 42.1, "A4", "Letter");
print Dumper($p);
'
$VAR1 = bless( {
'item' => 'T-shirt',
'style' => 'printed',
'price' => 42,
'sizes' => [
'XXL',
'M'
]
}, 'My_Product' );

$VAR1 = bless( {
'item' => 'paper',
'style' => 'white',
'price' => '42.1',
'sizes' => [
'A4',
'Letter'
]
}, 'My_Product' );


Next step would be to let init take a hashref as parameter, and/or used
named parameters. Or just check out Moose.
 
J

Justin C

The error is in "=> @sizes", you probably meant "=> \@sizes".

Thank you, I have it working now.

named parameters. Or just check out Moose.

I've just Googled that, I think I should really understand what I'm
doing before I put another layer between me and what I want to do. I'm
sure that, once I understand it, a tool like Moose will be useful... And
they have a TextMate bundle, so I'm half sold on the idea already!

Justin.
 
J

Justin C

Justin C wrote:
) I've been reading various OO tutorials and other references on the web
) (I found <URL: http://www.perlmonks.org/?node_id=218778> more useful
) than perlboot and perltoo - though they are more clear to me now). To
) see if I'm understanding correctly I'm writing something that has little
) use other than educating me.

Your problem has nothing to do with OO.

I realise that, but I didn't know how to represent my problem with
showing what I had done.

Here's a simple program that demonstrates the same problem:

sub foo {
my @sizes = @_;
my $hash = {
SIZES => @sizes,
};
return $hash;
}
my $hash = foo(1, 2, 3);
for my $item ($hash->{SIZES}) { print $item }

To find the answer to your problem, read up on references (perlreftut ?).

Oh no, not again! That document *really* makes my brain hurt... though I
always seem to be a bit better off before each time I've read it (or
bits of it).

Simply put: you can't use an array as a value in a hash, and when you do it
will get expanded to a list.

I think my problem was not understanding what I was creating with the
object, now I see that it's a hash it all makes more sense.

What you want is either: { SIZES => \@sizes } or: { SIZES => [@sizes] }

That's done the trick, thank you.

Be sure to read up on perldoc perlreftut and you'd also do good to read
some more about basic Perl.

The most read book I have ever owned is the Llama, though, in this
instance, I think the book may be too basic.

Thank you for your reply, you've helped clarify several points in my
mind.

Justin.
 
R

Randal L. Schwartz

Justin> The most read book I have ever owned is the Llama, though, in this
Justin> instance, I think the book may be too basic.

Yes, you now need the Alpaca, the Llama sequel. It covers (surprise!)
references and objects, right where you need them.

print "Just another Perl hacker,"; # the original!
 
J

Justin C

Justin> The most read book I have ever owned is the Llama, though, in this
Justin> instance, I think the book may be too basic.

Yes, you now need the Alpaca, the Llama sequel. It covers (surprise!)
references and objects, right where you need them.

print "Just another Perl hacker,"; # the original!

Is that a sales pitch Randal? Actually, it probably is a good idea. I
found the llama easy going enough, paced right for me, and, most
importantly I understood it!

I'll add it to my Christmas list.

Justin.
 
J

Justin C

Justin> The most read book I have ever owned is the Llama, though, in this
Justin> instance, I think the book may be too basic.

Yes, you now need the Alpaca, the Llama sequel. It covers (surprise!)
references and objects, right where you need them.

I've just had a good "Look Inside" the Alpaca on Amazon, looks right up
my street. Maybe I won't wait until Christmas. Thanks for the very
targetted ad campaign! ;)

Justin.
 

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,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top