Reputation: 293
How can I break down the values and return them separately so I can access them separately?
I have a forum system with a database that keeps track of all posts in a thread. I have a sub called notice_value
:
sub notice_value {
my ($self,$prefid,$value,$others_post,$clients_post,$assigned_tasks) = @_;
$self->{PREFS}->{$prefid} = { VALUE => $value,
OTHERS_POST => $others_post,
CLIENTS_POST => $clients_post,
ASSIGNED_TASKS => $assigned_tasks };
return $self->{PREFS}->{$prefid};
}
EDIT- original notice_value
sub notice_value {
my $self = shift;
my $prefid = shift;
$self->{PREFS}->{$prefid} = shift if(@_);
return $self->{PREFS}->{$prefid};
}
-------------------------------------------------------------
Which retrieves the user's preferences, one of which is the markup type VALUE
. When I call on the markup type I use $self->markup
it calls on this - sub markup_type
which is a method in Taskman::Post
:
sub markup_type {
my $self = shift;
$self->{MARKUP_TYPE} = shift if(@_);
$self->{MARKUP_TYPE};
}
My problem is that I only want to retrieve the VALUE
from notice_value but instead it returns the whole thing like so -- When I dumped $self
I got:
$VAR1 = bless( {
'POST_TYPE_ID' => 1,
'MINUTES' => '0',
'DEADLINE' => '2014-05-19 18:04:00',
'ESTIMATE' => 300,
'COMMENT' => 'sd',
'POSTER' => 1286,
'STATE_ID' => 14,
'CONTRACTID' => 546,
'PRIORITY' => '3',
'MARKUP_TYPE' => {
'VALUE' => 1,
'OTHERS_POST' => 1,
'CLIENTS_POST' => 1,
'ASSIGNED_TASKS' => 1
},
'TID' => 23133,
'OWNER' => '1286'
}, 'Taskman::Post' );
I want to be able to access the other values(OTHERS_POST
,CLIENTS_POST
,ASSIGNED_TASKS
) separately as well for other functions.
I'm kind of new to Perl and am a little confused on how to break up the notice_value
sub so that I can retrieve what I want from it more efficiently and correctly. If you can show an example too that would be great.
EDIT
this is the sub that calls on the notice_value
:
sub __populate {
my $self = shift;
my $sth = $self->{dbh}->prepare("select prefid, value, others_post, clients_post, assigned_tasks from user_preferences where userid=?");
$sth->execute($self->userid);
while(my $href = $sth->fetchrow_hashref()) {
$self->notice_value($href->{PREFID}, $href->{VALUE}, $href->{OTHERS_POST}, $href->{CLIENTS_POST}, $href->{ASSIGNED_TASKS});
}
$sth->finish();
}
the original __populate
only had:
$self->notice_value($href->{PREFID}, $href->{VALUE});
Upvotes: 2
Views: 237
Reputation: 107040
I noticed that your dump has Taskman::Post
on the end of the dump. This means that this is a Taskman::Post
object, and thus should have methods that will pull out the various piece of data that it contains. There might be a markup method that will pull out the information in this object.
The question is where did this object come from. Was this something you wrote? Is this a Perl module installed with your system. Was it written correctly, so that it includes POD documentation.
Try the following command:
$ perldoc Taskman::Post
If this works, it will pull up information on how to access the data contained in this Taskman::Post
object that you've retrieved.
If nothing comes up, then try this command:
$ perldoc -l Taskman::Post
This will tell you if the Taskman::Post module is installed and where it exists on your system. You may have to look at this source to finagle the various methods it contains. These methods will be subroutines inside this module. Subroutines that start with an underscore are considered private and you shouldn't use them directly.
If this doesn't work, you'll need to find where this class is defined. Sometimes, people define non-module classes for use in a single program. For example, I write a program to track my employees. I create an Employee class, but instead of installing in as a separate Perl module, I simply append it to my Perl program. Look for:
package Taskman::Post
in the code. If you find it, see if the code contains POD documentation. You'll see =pod
or =head1
throughout the document. If so, you can try:
$ perldoc program.pl
Where program.pl
is your Perl program.
Getting back to your subroutine, are you writing this as a class? I keep seeing $self
all around. This usually means that you're working with an object, so the question is what type of object is $self
. For example, what does:
print "The reference \$self " . ref( $self ) . "\n";
print out?
Again, you shouldn't be manipulating an object as if it's just a reference to a hash. In fact, some developers write what are called inside out classes to prevent people from doing Data::Dumper
and manipulating their classes without going through the correct methods.
I found your post a bit confusing because it sounds like you're writing non-object oriented code, but your data looks object oriented.
Are you writing object oriented code? Do you know how Perl object oriented programming works?
If you're working with everything as objects. Try to get your methods straighten out. In your markup_type
subroutine, what type of object is $self
. Print out ref $self
and see what type of object it is.
This should help clarifying what you're working with, and should help you understand what you're actually pulling out.
Upvotes: 1
Reputation: 3382
It looks to me like you want $thing->notice_value(@all_those_arguments)->{VALUE}
.
This is because the return value is
{ VALUE => $value,
OTHERS_POST => $others_post,
CLIENTS_POST => $clients_post,
ASSIGNED_TASKS => $assigned_tasks }
and $thing->notice_value(@all_those_arguments)
returns just this value. Will that work for you?
Upvotes: 0
Reputation: 6378
TL;DR broad guess/conclusion to a broad question: fix the return value of notice_value
or the fix the way that value is used in other functions.
This question is very general and does not offer much sample code: in fact it can't post sample code almost by definition due to the wide scope of the question. It might be better to post the question as one focused on general debugging strategies (though I am not sure how well accepted those kinds of queries are on SO) or - once you have narrowed down your problem - post more specific questions about techniques for fixing what is going wrong.
And a number of things could be going wrong: shouldn't the return value of your notice_value
subroutine be something like return $self->{PREFS}->{$prefid}->{VALUE};
? i.e. if - guessing from the name - the subroutine is supposed to "notice" the "value" of the hash/object's MARKUP
key anonymous hash key called VALUE
(i.e. it is a "getter" method/function that does nothing but access values). The way it gets those values (defreferencing, accessing database etc.) is left as a implementation detail for the function. If dereferencing a data structure full of preferences is not working, and your expected behaviour changes when you change the function that access your preferences, then you are right on the right track to focus there :)
If I create a function as follows and pass it an array (leaving out the object you pass in, so I'm leaving out the $self
):
sub notice_value{
my ($prefid,$value,$others_post,$clients_post,$assigned_tasks) = @_;
$_->{PREFS}->{$prefid} = { VALUE => $value,
OTHERS_POST => $others_post,
CLIENTS_POST => $clients_post,
ASSIGNED_TASKS => $assigned_tasks };
return $_->{PREFS}->{$prefid};
}
Now some preference and data gunk:
my @pref_and_data_goo = qw( 21323 42 213 214 2 );
Now let's see what the function does with that it creates a PREFS
hash key and gives it an an anonymous hash as its value:
notice_value(@pref_and_data_goo)
$HASH1 = {
ASSIGNED_TASKS => 2,
CLIENTS_POST => 214,
OTHERS_POST => 213,
VALUE => 42
};
What about the value of the VALUE
key (I'm easily confused by the naming scheme here) or other keys in PREFS
key's anonymous hash:
notice_value(@pre_and_data_goo)->{VALUE}
42
notice_value(@pre_and_data_goo)->{ASSIGNED_TASKS}
214
If you want wrap up notice_value
so it only returns the value of the VALUE
key you need to tell the code of that function how to get at that nested anonymous hash key.
Now to pass a hash/object to your other function markup_type
with a quick cut and paste to the re.pl
(thus the odd markup e.g. re.pl$
and >
):
re.pl$ my $whacky_hash = {
> 'POST_TYPE_ID' => 1,
> 'MINUTES' => '0',
> 'DEADLINE' => '2014-05-19 18:04:00',
> 'ESTIMATE' => 300,
> 'COMMENT' => 'sd',
> 'POSTER' => 1286,
> 'STATE_ID' => 14,
> 'CONTRACTID' => 546,
> 'PRIORITY' => '3',
> 'MARKUP_TYPE' => {
> 'VALUE' => 42,
> 'OTHERS_POST' => 1,
> 'CLIENTS_POST' => 1,
> 'ASSIGNED_TASKS' => 1
> },
> 'TID' => 23133,
> 'OWNER' => '1286'
> }
re.pl$ sub markup_type {my $self = shift;
> $self->{MARKUP_TYPE} = shift if(@_);
> $self->{MARKUP_TYPE}; }
re.pl$ markup_type($whacky_hash)
$HASH1 = {
ASSIGNED_TASKS => 1,
CLIENTS_POST => 1,
OTHERS_POST => 1,
VALUE => 1
};
re.pl$ sub markup_type2 {my $self = shift ;
> $self->{MARKUP_TYPE}->{VALUE}; }
re.pl$ markup_type2($whacky_hash)
42
Are you sure a change similar to this doesn't work? If you change your markup_type
function to:
sub markup_type {
my $self = shift ;
$self->{MARKUP_TYPE}->{VALUE};
}
you should get the value you want returned from that function. If this breaks other code then track down where it is used and try to find the most suitable place to try changing things. Unfortunately there's not much we can do to help you directly.
Your notice_value
function takes a long set of assignments as an argument:
my ($self,$prefid,$value,$others_post,$clients_post,$assigned_tasks) = @_;
I tend not to like functions that have long list assignments since it can be hard to track values back to where they came from. Is $value
supposed to be a hash reference or a code reference to the return value of markup_type
or something else again? That is probably just me being easily confused since many people prefer list assignment style. Still though, this function takes a lot of arguments if all it is supposed to do is to notice_value
? Are your trying If you check how notice_value
gets and uses its arguments you'll be able to spot the source of the error more easily. Your EDIT addition still leaves me wondering: why $href->{VALUE}
is used rather than $href->{MARKUP_TYPE}->{VALUE}
.
Upvotes: 1