Beefy Boxes and Bandwidth Generously Provided by pair Networks
Syntactic Confectionery Delight
 
PerlMonks  

dereference hash key object in access method

by gctaylor1 (Hermit)
on Nov 09, 2008 at 06:25 UTC ( [id://722456]=perlquestion: print w/replies, xml ) Need Help??

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

I'm trying to dereference a hash key inside an access method and cannot figure out why it's failing. I keep getting this error "Can't use string ("5") as a HASH ref while "strict refs" in use at Music.pm line 19." If I manually assign the value in the method it works and in another method I can print the value using the same syntax. The big picture is that I want to pass one value to the constructor and then use that value along with an access method to populate the second value in the constructor. This is possible when I use the hard coded value in the method.
What concept is it that I am not understanding?

use strict; use warnings; package Music; sub new { my $class = shift; my $number1 = @_; my $number2 = &add_numbers; my $ref= { "Number_one" => $number1, "Number_two" => $number2 }; bless($ref, $class); } sub add_numbers { my $self = shift; my $value = $self->{"Number_one"} ; # my $value = 2; return $value; }; sub display_values{ my $self = shift; print "$self->{'Number_one'}\n"; print "$self->{'Number_two'}\n"; } 1;

This is the line in question from the sub add_numbers method:

my $value = $self->{"Number_one"} ;

Here's my user/driver program:

use strict; use warnings; use Music; my $value = Music->new(5); $value->display_values;

Any clues on what I need to study?

Replies are listed 'Best First'.
Re: dereference hash key object in access method
by GrandFather (Saint) on Nov 09, 2008 at 07:48 UTC
    What concept is it that I am not understanding?

    Several, and there are a number of things that you ought to do to make your code clearer, more robust and easier to maintain.

    First off, if you are going to accept a number of parameters in a sub you should:

    sub mySub { my ($param1, $param2, %bunchOfOptions) = @_;

    so that it is clear at a glance what the parameters are that are expected. Although Perl allows great freedom to pass parameters using a vast range of techniques (potentially in the same sub), it also allows you a wonderful range of techniques for shooting yourself in the foot. Make an effort to use a consistent parameter passing technique and your code will work much more reliably.

    The first major concept you have missed is that methods intended to be called on blessed references generally must be called on blessed references. In your constructor you call add_numbers before you even have a blessed reference let alone call it using the blessed reference. In fact there are very few occasions when you should call a sub using & in any case.

    The second important (and related) concept is that the object is the reference once it has been blessed. $ref contains the object. With your current design you the bless line should precede the add_numbers call.

    You ought to use explicit return values rather than relying on the last lvalue. It makes it much clearer that you are returning the value by intent rather than as a side effect. Putting it all together your code should look something like:

    use strict; use warnings; package Music; sub new { my ($class, $number1) = @_; my $self = bless {"Number_one" => $number1}, $class; $self->{"Number_two"} = $self->add_numbers (); return $self; } sub add_numbers { my ($self) = @_; return $self->{"Number_one"}; } sub display_values { my ($self) = @_; print "$self->{'Number_one'}\n$self->{'Number_two'}\n"; } 1;

    Perl reduces RSI - it saves typing
Re: dereference hash key object in access method
by ccn (Vicar) on Nov 09, 2008 at 06:35 UTC
    sub new { # @_ = ('Music', 5) my $class = shift; # @_ = (5) my $number1 = @_; # $number1 = 1 - array in scalar context r +eturns it's size! my $number2 = &add_numbers; # here you call sub add_numbers!

    &add_numbers call the sub with current argiment list @_. You already shifted object reference from it, so it contains only 5.

    Then

    sub add_numbers { # @_ = (5) my $self = shift; # $self = 5 !!! my $value = $self->{"Number_one"} ; # ERROR!

    see perlsub

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://722456]
Approved by McDarren
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others rifling through the Monastery: (4)
As of 2024-04-25 07:22 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found