1

I need help regarding handling of Perl variables. Here I am getting input as a hash. I now need to send this hash variable to another subroutine. How can pass data as an argument to another subroutine? The code below shows how I am approaching this:

if ($csData->{'CUSTOMER_INVOICE_DETAILS'})
{
    $c->log->debug("API Response:". Dumper $csData->{'CUSTOMER_INVOICE_DETAILS'});
    my $Charges = [];
    my @customerCharges = $csData->{'CUSTOMER_INVOICE_DETAILS'};
    foreach(@customerCharges)
    {
        my ($customername,$customeramount) = split /:/;
        my $charge_hash = ({
        customername       => $customername,
        customeramount     => $customeramount
        });
        push(@$Charges, $charge_hash);
    }
my @ReturnCharges = $self->API->get_customer_charges($Charges, $Customer->customerid, $params->{'invoiceid'});

The other subroutine where this data is being received is as follows:

sub get_customer_charges
{
    my $self = shift;
    my ($charge, $CustomerId, $INID) = @_;

    my $http_request = {
            action       => 'GetTariff',
            customerid   => $CustomerId,
            csid         => $INID,  
            };
    my $markups = $self->APIRequest($http_request);

    ###Charge Level ID Inserting As 10
    my @ChargeLevels;
    my @BaseLevelID;
    foreach my $ch (@$charge)
    {
        my ($customername,$customeramount) = split(':', $ch->{'customername'}, $ch->{'customername'});
        my $chargelevel = join(':', $ch->{'customername'}, $ch->{'customeramount'}, '10');
        push(@BaseLevelID, $chargelevel);
    }
    push(@ChargeLevels, @BaseLevelID);
    return @ChargeLevels;
}

When I print to the server log for CUSTOMER_INVOICE_DETAILS variable I am getting the following values:

API Response:$VAR1 = {
      'Product' => '34.04',
      'basetax' => '2.38',
      'vattax' => '4.36'
    };

After sending data to second subroutine the data coming in server log for second subroutine variable is as following:

Charges in API:$VAR1 = 'HASH(0xb75d6d8)::10';

Can anyone help how could I send the hash data from one subroutine to another?

G. Cito
  • 6,210
  • 3
  • 29
  • 42
  • 1
    The lines with `split` and `join` are suspicious. – choroba Mar 27 '15 at 10:37
  • Hi chorobra please ignore split. And join is using I need to assign another value as 10 for existing array so that I have used join. – Jallipalli Phanindra Mar 27 '15 at 10:52
  • But it seems the join is responsible for the incorrect output. – choroba Mar 27 '15 at 10:54
  • Okay choroba let me explain in simple now I have hash data as like this API Response:$VAR1 = { 'Product' => '34.04', 'basetax' => '2.38', 'vattax' => '4.36' }; Now I need output as API Response:$VAR1 = { 34.04:2.38:4.36:10 }; But this conversion process should be done another subroutine – Jallipalli Phanindra Mar 27 '15 at 10:56
  • http://www.perlmonks.org/?node_id=1121510 – choroba Mar 27 '15 at 14:43
  • In `get_customer_charges()` what is the third argument to `split` on the line `my ($customername,$customeramount) = split(':', $ch->{'customername'}, $ch->{'customername'});` doing? – G. Cito Mar 27 '15 at 16:53

2 Answers2

1

Given your comments and that your source is:

API Response:$VAR1 = {
      'Product' => '34.04',
      'basetax' => '2.38',
      'vattax' => '4.36'
    };

And you're looking for:

API Response:$VAR1 = { 34.04:2.38:4.36:10 };

(and somehow you're getting:

Charges in API:$VAR1 = 'HASH(0xb75d6d8)::10';

This suggests this may be as simple as using the values system call. values extracts an array of all the values in the hash. Something like this (guessing a bit on which part of your code needs it).

my @list_of_values = values ( %{$csData->{'CUSTOMER_INVOICE_DETAILS'}} ); 
Sobrique
  • 52,974
  • 7
  • 60
  • 101
  • Okay Thanks Sobrique for solution but here is another problem that I need to send the values with keys because in another subroutine that where this values are receiving there I need to check with keys and the process the data and then final output should be like that. – Jallipalli Phanindra Mar 27 '15 at 13:44
  • @JallipalliPhanindra I can't think of why you might **really** need to send an array instead of a hash instead of just converting the hash as part of your subroutine ... as @Sobrique notes `values` will essentially create a list/array of values "on the fly" from the hash structure so the solution could be very simple. – G. Cito Mar 27 '15 at 17:14
1

You say you want to "convert" a hash to an array, but your issue seems more complex and subtle so simple conversion is not likely what will solve your problem. Something in your subroutine is returning a hash reference when the rest of your code does not expect it to do so. If the data-structure you are passing contains the correct information but not in the form you expect, then you can either change the code to produce it in the expected form (e.g. to return an ARRAY) or change your subroutine so that it is able to handle the data that it is passed correctly.

As for "converting a hash" per se, if your data structure doesn't contain complex nested references and all you want to do is "convert" your hash to an array or list, then you can simply assign the hash to an array. Perhaps I'm not understanding your question but if this kind of simple "flattening" is all you want then you could try:

my $customer_purchase = {
     'Product' => '34.04',
     'basetax' => '2.38',
     'vattax' => '4.36'
};

my @flat_customer_purchase = %{ $customer_purchase };
say "@flat_customer_purchase" ;

Output:

basetax 2.38 Product 34.04 vattax 4.36

You can then supply the hash data as the "array" to the second subroutine. e.g. treat @flat_customer_purchase as a list:

use List::AllUtils ':all';
say join " ", pairkeys  @flat_customer_purchase
# basetax Product vattax
say join " ", pairvalues @flat_customer_purchase
# 2.38 34.04 4.36

etc.

NB: this assumes that for some reason you must pass an array. The example of running the pairvalues routine simply replicates @Sobrique's suggestion to use values directly on the hash you are passing but in my answer this grabs the values pairs from the array instead of the hash.

My sense is that there is more to the question. If API Response is a more complicated hash/object or, if for some other reason this basic perl doesn't work, then you will have to supply more information. You need to find out where your unexpected hash reference is coming from before you can decide how to handle it. You might find this SO discussion helpful:

Community
  • 1
  • 1
G. Cito
  • 6,210
  • 3
  • 29
  • 42