Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Perl > Perl Misc > OO Perl : Struggling with hash data members in my Class

Reply
Thread Tools

OO Perl : Struggling with hash data members in my Class

 
 
Brett.R.Davis@gmail.com
Guest
Posts: n/a
 
      08-09-2006
I am writing my first Perl Class and have hit a brick wall.

What I need to do is have a class method copy a hash into the data
member %MY_HASH.

I have coded a constructor and a method my_hash which is *supposed* to
either:

1. return the HASH reference or
2. write a copy the contents of a hash into the MY_COLORS data member.

Then I wanted a second data member that uppon being written to with a
symbolic name, would use the MY_COLORS hash to provide the numberical
code for that COLOR as shown:

my $composite_colors={'green'=>1, 'blue'=>2, 'red'=>3 };
my $color_set=Chash->new();
$chash->my_colors($composite_colors);
$chash->color_code('blue');
print $chash{'color_code'};

The output should be:

2

However, I am never able to get the object $chash to take in the
$composite_colors reference, and copy it into the data member
MY_COLORS. I get comments like "odd number of elements in anonymous
hash". If I data dump the contents of the data member MY_COLORS it
shows that the $composite_colors hash is being copied in as a key to
the has instead of essentially becoming the MY_COLORS hash.

Any assistance would be greatly appreciated!!!!

Brett


Here is the code.

package Chash;

sub new {
my $proto = shift;
my $class = ref($proto) || $proto;
my $self = {};
$self->{MY_COLORS} = {};
$self->{COLOR_CODE} = undef;
bless($self, $class);
return $self;
}

sub my_colors {
my $self = shift;
if (@_) { $self->{MY_COLORS} = $_[0] }
return { $self->{MY_COLORS} };
}


sub color_code {
my $self = shift;
if (@_) {
if (ref $self->{MY_COLORS} eq "HASH") {
$self->{COLOR_CODE} = $self->{MY_COLORS}->{$_[0]};
}
else {
$self->{COLOR_CODE} = shift;
}
}
return $self->{COLOR_CODE};
}

 
Reply With Quote
 
 
 
 
Brett.R.Davis@gmail.com
Guest
Posts: n/a
 
      08-10-2006
Thank you for your response.
I think my simple color abstraction may have confused the issue.
Let me try to rephrase the problem - given a hash :

my %bar = { 'x'=>0xbeef, 'y'=>0xfeed };

and assuming a class Foo with the constructor below,
how do I put %bar into MY_HASH.

And then how do I get the contents of MY_HASH?

I can't seem to get this to work.

=-=-=-=--=-=-=-=-=-=-=-=-=-

Package My::Class::Foo;

use strict;
use warnings;
use Carp;

sub new {
my $proto = shift;
my $class = ref($proto) || $proto;
my $self = {};
$self->{MY_HASH} = {};
bless($self, $class);
return $self;
}

=-=-=-=-=-=-=-=--=-==-=-=-=-=-

 
Reply With Quote
 
 
 
 
Mumia W.
Guest
Posts: n/a
 
      08-10-2006
On 08/09/2006 05:36 PM, http://www.velocityreviews.com/forums/(E-Mail Removed) wrote:
> I am writing my first Perl Class and have hit a brick wall.
>
> What I need to do is have a class method copy a hash into the data
> member %MY_HASH.
>
> I have coded a constructor and a method my_hash which is *supposed* to
> either:
>
> 1. return the HASH reference or
> 2. write a copy the contents of a hash into the MY_COLORS data member.
>
> Then I wanted a second data member that uppon being written to with a
> symbolic name, would use the MY_COLORS hash to provide the numberical
> code for that COLOR as shown:
>
> my $composite_colors={'green'=>1, 'blue'=>2, 'red'=>3 };
> my $color_set=Chash->new();


I got your program to work, but I had to assign $color_set to
$chash before the line below.

> $chash->my_colors($composite_colors);
> $chash->color_code('blue');
> print $chash{'color_code'};
>
> The output should be:
>
> 2
>
> However, I am never able to get the object $chash to take in the
> $composite_colors reference, and copy it into the data member
> MY_COLORS.


The code you posted pretty much should work so long as $chash
is set to something meaningful. You have an annoying warning
that I'll show you how to get rid of.

> I get comments like "odd number of elements in anonymous
> hash". If I data dump the contents of the data member MY_COLORS it
> shows that the $composite_colors hash is being copied in as a key to
> the has instead of essentially becoming the MY_COLORS hash.
>
> Any assistance would be greatly appreciated!!!!
>
> Brett
>
>
> Here is the code.
>
> package Chash;
>
> sub new {
> my $proto = shift;
> my $class = ref($proto) || $proto;
> my $self = {};
> $self->{MY_COLORS} = {};
> $self->{COLOR_CODE} = undef;
> bless($self, $class);
> return $self;
> }
>
> sub my_colors {
> my $self = shift;
> if (@_) { $self->{MY_COLORS} = $_[0] }
> return { $self->{MY_COLORS} };


The line above produces an annoying warning; the line uses
$self->{MY_COLORS}, which contains only *one* value, a scalar
reference to a hash, as the data for an anonymous hash
(denoted by { ... }); hashes with an uneven number of elements
are usually messed up.

I don't know why you're creating an anonymous hash then
returning it; you already have a much better hash to return in
$self->{MY_COLORS}, so why not just return it? Perhaps you
were thinking of the {...} as a block. Anyway, change it:

return $self->{MY_COLORS};


> }
>
>
> sub color_code {
> my $self = shift;
> if (@_) {
> if (ref $self->{MY_COLORS} eq "HASH") {
> $self->{COLOR_CODE} = $self->{MY_COLORS}->{$_[0]};
> }
> else {
> $self->{COLOR_CODE} = shift;
> }
> }
> return $self->{COLOR_CODE};
> }
>


A. Sinan Unur showed you how to use some perl modules to do
this differently, and I think I'll do that too:

package My::Chash2;
use Class::Struct;
struct 'My::Chash2' => [ my_colors => '%' ];

sub color_code {
my $self = shift;
$self->my_colors(shift());
}

package main;

my $composite_colors={'green'=>1, 'blue'=>2, 'red'=>3 };
my $chash = My::Chash2->new();
$chash->my_colors($composite_colors);
print $chash->color_code('blue'), "\n";



__HTH__


 
Reply With Quote
 
Randal L. Schwartz
Guest
Posts: n/a
 
      08-10-2006
>>>>> "Brett" == Brett R Davis <(E-Mail Removed)> writes:

Brett> sub new {
Brett> my $proto = shift;
Brett> my $class = ref($proto) || $proto;

Please don't do this. See
<http://www.stonehenge.com/merlyn/UnixReview/col52.html> for a long discussion
about constructors, including the last few paragraphs which describe why not
to do that.

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

--
Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095
<(E-Mail Removed)> <URL:http://www.stonehenge.com/merlyn/>
Perl/Unix/security consulting, Technical writing, Comedy, etc. etc.
See PerlTraining.Stonehenge.com for onsite and open-enrollment Perl training!

--
Posted via a free Usenet account from http://www.teranews.com

 
Reply With Quote
 
Mumia W.
Guest
Posts: n/a
 
      08-10-2006
On 08/09/2006 08:08 PM, (E-Mail Removed) wrote:
> Thank you for your response.
> I think my simple color abstraction may have confused the issue.
> Let me try to rephrase the problem - given a hash :
>
> my %bar = { 'x'=>0xbeef, 'y'=>0xfeed };
>


You have problems with Perl syntax. Curly braces are used to
create blocks and anonymous hashes. Use parenthesis to create
arrays and non-anonymous hashes, e.g.

my %bar = ( 'x'=>0xbeef, 'y'=>0xfeed );


> and assuming a class Foo with the constructor below,
> how do I put %bar into MY_HASH.
>
> And then how do I get the contents of MY_HASH?
>
> I can't seem to get this to work.
>
> =-=-=-=--=-=-=-=-=-=-=-=-=-
>
> Package My::Class::Foo;
>
> use strict;
> use warnings;
> use Carp;
>
> sub new {
> my $proto = shift;
> my $class = ref($proto) || $proto;
> my $self = {};
> $self->{MY_HASH} = {};

%{$self->{MY_HASH}} = @_ if (@_);

> bless($self, $class);
> return $self;
> }
>
> =-=-=-=-=-=-=-=--=-==-=-=-=-=-
>


package main;

my $chash = My::Class::Foo->new(%bar)

However, I wouldn't bother writing a new() function for
something this simple, because it's so much easier to cheat:

use Class::Struct;
struct My::Class::Foo => [ my_colors => '%' ];

my %bar = ( 'x'=>0xbeef, 'y'=>0xfeed );
my $chash = My::Class::Foo->new( my_colors => \%bar);

=-=-=-=-=-=-=-=--=-==-=-=-=-=-
UNTESTED CODE
 
Reply With Quote
 
Brett.R.Davis@gmail.com
Guest
Posts: n/a
 
      08-10-2006
You said that you were able to get my original code to work.

Can you tell me specifically what it was - or was it the items you
specified in the message?

The class I presented was just for academic reasons. The actual class
I need to implement will be quite a bit more complicated.

Does the struct class you showed me allow for member functions?

Thanks

Mumia W. wrote:
> On 08/09/2006 05:36 PM, (E-Mail Removed) wrote:
> > I am writing my first Perl Class and have hit a brick wall.
> >
> > What I need to do is have a class method copy a hash into the data
> > member %MY_HASH.
> >
> > I have coded a constructor and a method my_hash which is *supposed* to
> > either:
> >
> > 1. return the HASH reference or
> > 2. write a copy the contents of a hash into the MY_COLORS data member.
> >
> > Then I wanted a second data member that uppon being written to with a
> > symbolic name, would use the MY_COLORS hash to provide the numberical
> > code for that COLOR as shown:
> >
> > my $composite_colors={'green'=>1, 'blue'=>2, 'red'=>3 };
> > my $color_set=Chash->new();

>
> I got your program to work, but I had to assign $color_set to
> $chash before the line below.
>
> > $chash->my_colors($composite_colors);
> > $chash->color_code('blue');
> > print $chash{'color_code'};
> >
> > The output should be:
> >
> > 2
> >
> > However, I am never able to get the object $chash to take in the
> > $composite_colors reference, and copy it into the data member
> > MY_COLORS.

>
> The code you posted pretty much should work so long as $chash
> is set to something meaningful. You have an annoying warning
> that I'll show you how to get rid of.
>
> > I get comments like "odd number of elements in anonymous
> > hash". If I data dump the contents of the data member MY_COLORS it
> > shows that the $composite_colors hash is being copied in as a key to
> > the has instead of essentially becoming the MY_COLORS hash.
> >
> > Any assistance would be greatly appreciated!!!!
> >
> > Brett
> >
> >
> > Here is the code.
> >
> > package Chash;
> >
> > sub new {
> > my $proto = shift;
> > my $class = ref($proto) || $proto;
> > my $self = {};
> > $self->{MY_COLORS} = {};
> > $self->{COLOR_CODE} = undef;
> > bless($self, $class);
> > return $self;
> > }
> >
> > sub my_colors {
> > my $self = shift;
> > if (@_) { $self->{MY_COLORS} = $_[0] }
> > return { $self->{MY_COLORS} };

>
> The line above produces an annoying warning; the line uses
> $self->{MY_COLORS}, which contains only *one* value, a scalar
> reference to a hash, as the data for an anonymous hash
> (denoted by { ... }); hashes with an uneven number of elements
> are usually messed up.
>
> I don't know why you're creating an anonymous hash then
> returning it; you already have a much better hash to return in
> $self->{MY_COLORS}, so why not just return it? Perhaps you
> were thinking of the {...} as a block. Anyway, change it:
>
> return $self->{MY_COLORS};
>
>
> > }
> >
> >
> > sub color_code {
> > my $self = shift;
> > if (@_) {
> > if (ref $self->{MY_COLORS} eq "HASH") {
> > $self->{COLOR_CODE} = $self->{MY_COLORS}->{$_[0]};
> > }
> > else {
> > $self->{COLOR_CODE} = shift;
> > }
> > }
> > return $self->{COLOR_CODE};
> > }
> >

>
> A. Sinan Unur showed you how to use some perl modules to do
> this differently, and I think I'll do that too:
>
> package My::Chash2;
> use Class::Struct;
> struct 'My::Chash2' => [ my_colors => '%' ];
>
> sub color_code {
> my $self = shift;
> $self->my_colors(shift());
> }
>
> package main;
>
> my $composite_colors={'green'=>1, 'blue'=>2, 'red'=>3 };
> my $chash = My::Chash2->new();
> $chash->my_colors($composite_colors);
> print $chash->color_code('blue'), "\n";
>
>
>
> __HTH__
>
>


 
Reply With Quote
 
Mumia W.
Guest
Posts: n/a
 
      08-10-2006
On 08/09/2006 10:49 PM, (E-Mail Removed) wrote:
> You said that you were able to get my original code to work.
>
> Can you tell me specifically what it was - or was it the items you
> specified in the message?
> [...]


Don't top post.

Everything was in the message: I assigned $color_set to
$chash, and I made my_colors() return $self->{MY_COLORS}.


 
Reply With Quote
 
Brett.R.Davis@gmail.com
Guest
Posts: n/a
 
      08-10-2006
OK - it worked!

I am a moron, and didn't have "-w" set in the script so I didn't notice
that I had { } around a hash reference like you said in the above post.
I originally had it as an anonymous hash.

By changing the return statement and fixing my hash declaration (used (
) instead of { } ) - it works!

Thank you

Brett

Mumia W. wrote:
> On 08/09/2006 10:49 PM, (E-Mail Removed) wrote:
> > You said that you were able to get my original code to work.
> >
> > Can you tell me specifically what it was - or was it the items you
> > specified in the message?
> > [...]

>
> Don't top post.
>
> Everything was in the message: I assigned $color_set to
> $chash, and I made my_colors() return $self->{MY_COLORS}.


 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
hash of hash of hash of hash in c++ rp C++ 1 11-10-2011 04:45 PM
Hash#select returns an array but Hash#reject returns a hash... Srijayanth Sridhar Ruby 19 07-02-2008 12:49 PM
class members vs instance members hdixon Python 3 07-09-2006 06:56 PM
hash in hash, iterating the members Depili Ruby 5 01-13-2006 03:06 AM
Can nested class members access private members of nesting class? CoolPint C++ 8 12-14-2003 02:30 PM



Advertisments