I'm trying to get array in param, everything works well with single data, but not for array...
client-side (list of parameters sent from the browser):
list[1] null
list[2] 2
list[3] 10
list[4] null
server-side:
any ['get','post'] => '/save_list' => sub {
my $items = param ('list');
#result = null, mb is only the first element
#my $items = param ('list[]');
#result = null
#my #items = param ('list[]');
#result = empty
#my #items = param ('list');
#result = empty
};
Where Am I Wrong?
My version Dancer2-0.155004
The DSL keyword parameters will return a Hash::MultiValue object that you can use to access those in Dancer2.
any ['get','post'] => '/save_list' => sub {
my #items = parameters->get_all('list');
foreach my $item ( #items ) {
do_stuff($item);
}
};
Related
I want to iterate through the values of a big hash, and if any of the values of that hash are keys, I want to convert it into a comma separated list which can be parsed in 'query_form'.
Right now from the data below I have:
name=Bob&surname=Whitbread&customerErrors=HASH(Xa456) (for example)
Here's what I have so far:
sub convertArgsToQueryString {
my $class = shift;
my $args = shift;
return unless ($args && ref($args) eq 'HASH');
foreach my $key (values %$args) {
if (ref($key) eq 'HASH') {
# change to a comma separated list
}
}
my $dummyURL = URI->new('', 'http');
$dummyURL->query_form(%$args);
return $dummyURL->query;
}
Data:
my $data = {
'name' => 'Bob',
'surname' => 'Whitbread',
'customerErrors' => {
'error1' => 'paymentError',
'error2' => 'addressError'
},
};
Query Form:
name=Bob&surname=Whitbread&customerErrors=paymentError,addressError
This will do what you want
print join ",", values %{$data->{customerErrors}},"\n";
Although I would suggest, rather than error1 as hash keys, you'd be better off with an array:
my $data = {
'name' => 'Bob',
'surname' => 'Whitbread',
'customerErrors' => [ 'paymentError', 'addressError' ],
};
Scaling that out to be generic, you will find the ref function to be helpful:
foreach my $key ( keys %$data ) {
print "$key is a ", ref $data->{$key},"\n";
if ( ref $data->{$key} eq 'HASH' ) {
print join ",", values %{$data->{$key}};
}
else {
print $data -> {$key},"\n";
}
}
Or tersely:
print join "\&", map { #join iterated on &
join "=", $_, #join paired values on =
ref $data->{$_} eq 'HASH' #ternary to check reference type
? values %{ $data->{$_} } #extract values if HASH
: $data->{$_} #extract just value if not.
} keys %$data; #iterate keys of data
Which gives as output:
name=Bob&customerErrors=addressError=paymentError&surname=Whitbread
I have written a function that executes a command, parses the output based on the regex, and returns two values, status and ip. Function call returns both the values as expected. Instead of returning a scalar, I want to return hash ref. Can some one tell me how to do return a hash ref for the below function?
sub status {
my ($self,$int) = #_;
my $status = 0;
my $ip = 0;
my $cmd = 'cisco ios command ' . $interface;
my $out = $self->{sshObj}->exec($cmd);
foreach my $line ( $out ) {
if ( $line =~ m/Session\s+status:\s+(.*)/ ) {
$status = $1;
}
if ( $line =~ /(\d+.\d+.\d+.\d+)/ ) {
$ip = $1;
}
}
return ($status,$ip);
}
function call :
my ($status, $ip) =
$self->{'$tunnel_obj'}->status($self->{'outer_t_1'});
INFO ("status : $status");
INFO ("ip : $ip");
Output :
status : UP
ip : 172.10.78.33
Apart from my misgivings that I described in a comment above, I would use the code below
The change is essentially to replace $status and $ip with elements of hash %ret, and then return a reference to that hash
But I must say again that the for loop will be executed only once, and this code is wrong as it stands. I can correct it only if you say what modules you are dealing with
sub status {
my ( $self, $int ) = #_;
my $out = $self->{sshObj}->exec("cisco ios command $interface");
my %ret;
for ( $out ) {
$ret{status} = $1 if /Session\s+status:\s+(.*\S)/;
$ret{ip} = $1 if /(\d+.\d+.\d+.\d+)/;
}
\%ret;
}
Your function call would be
my $ret = $self->{$tunnel_obj}->status($self->{outer_t_1});
INFO("Status: $ret->{status}");
INFO("IP: $ret->{ip})");
I have this
sub test
{
my ($arg1, $arg2) = #_; # Argument list
code
return ($variable1, $variable2);
}
So, when i call this by
test('text1','text2');
concatenates the two return values in one. How can i call only one at a time?
my $output_choice_1 = ( test('text1','text2') )[0];
my $output_choice_2 = ( test('text1','text2') )[1];
or both at once:
my ( $output_choice_1, $output_choice_2 ) = test('text1','text2');
Though sometimes it makes for clearer code to return a hashref:
sub test {
...
return { 'choice1' => $variable1, 'choice2' => $variable2 };
}
...
my $output_choice_1 = test('text1','text2')->{'choice1'};
Are you asking how to assign the two values returned by a sub to two different scalars?
my ($var1, $var2) = test('text1', 'text2');
I wasn't really happy with what I found in google so posting my solution here.
Returning an array from a sub.
Especially the syntax with the backslash caused me headaches.
#!/usr/bin/perl
use warnings;
use strict;
use Data::Dumper;
sub returnArrayWithHash {
(my $value, my %testHash) = #_;
return ( $value, \%testHash );
}
my %testHash = ( one => 'foo' , two => 'bar' );
my #result = returnArrayWithHash('someValue', %testHash);
print Dumper(\#result) . "\n";
Returns me
$VAR1 = [
'someValue',
{
'one' => 'foo',
'two' => 'bar'
}
];
How to get the value of a parameter code using URI::URL Perl module?
From this link:
http://www.someaddress.com/index.html?test=value&code=INT_12345
It can be done using URI::URL or URI (I know the first one is kind of obsolete). Thanks in advance.
Create a URI object and use the query_form method to get the key/value pairs for the query. If you know that the code parameter is only specified once, you can do it like this:
my $uri = URI->new("http://www.someaddress.com/index.html?test=value&code=INT_12345");
my %query = $uri->query_form;
print $query{code};
Alternatively you can use URI::QueryParam whichs adds soem aditional methods to the URI object:
my $uri = URI->new("http://www.someaddress.com/index.html?test=value&code=INT_12345");
print $uri->query_param("code");
use URI;
my $uri = URI->new("http://someaddr.com/index.html?test=FIRST&test=SECOND&code=INT_12345");
my %query = $uri->query_form;
use Data::Dumper;
print Dumper \%query;
We can see:
$VAR1 = {
'test' => 'SECOND',
'code' => 'INT_12345'
};
Unfortunately, this result is wrong.
There is possible solution:
use URI::Escape;
sub parse_query {
my ( $query, $params ) = #_;
$params ||= {};
foreach $var ( split( /&/, $query ) ){
my ( $k, $v ) = split( /=/, $var );
$k = uri_unescape $k;
$v = uri_unescape $v;
if( exists $params->{$k} ) {
if( 'ARRAY' eq ref $params->{$k} ) {
push #{ $params->{$k} }, $v;
} else {
$params->{$k} = [ $params->{$k}, $v ];
}
} else {
$params->{$k} = $v;
}
}
return $params;
}
I am trying to output JSON from a perl script that accesses a mysql database.
How I can I loop through my query returns and turn that into JSON using the JSON module?
When I do this all I get is 1 return
while($query_handle->fetch()) {
$jsonStructure->{event};
$jsonStructure->{event}->{evid} = $evid;
$jsonStructure->{event}->{component} = $component;
$jsonStructure->{event}->{firstTime} = $firstTime;
$jsonStructure->{event}->{lastTime} = $lastTime;
$jsonStructure->{event}->{count} = $count;
$jsonStructure->{event}->{summary} = $summary;
$jsonStructure->{event}->{severity} = $severity;
}
Basically I have many events and don't know how to say event[0]...
Thank You
I think what you're looking for is this:
push #{ $jsonStructure->{events} }, {
evid => $evid,
component => $component,
...,
};
although even that is probably overkill, because you can probably do something like:
while (my $row = $dbh->fetchrow_hashref) {
push #{ $jsonStructure->{events} }, $row;
}
if all of the column names in the DB are the same as the field names you want in the JSON, and you want all columns, or:
my #keys = qw(evid component firstTime ...);
while (my $row = $dbh->fetchrow_hashref) {
my %hash;
#hash{#keys} = #$row{#keys};
push #{ $jsonStructure->{events} }, \%hash;
}
if you only want some columns, or:
# DB colname => JSON field name
my %mapping = (
event_id => 'evid',
component => 'component',
first_time => 'firstTime',
...,
);
while (my $row = $dbh->fetchrow_hashref) {
my %hash;
#hash{ values %mapping } = #$row{ keys %mapping };
push #{ $jsonStructure->{events} }, \%hash;
}
for a completely arbitrary mapping. Power of Perl and all that. :)