skip to Main Content

I’m sure there is a "shortcut" to this problem – which I thought I’d solved, but which now doesn’t work. Suggestions please.

Having decoded the JSON object to "$codes", this works:

$codes->{"product"}->{"ad_id"}->{"$ad_id"}->{"singlePay"}=$singlePayments;
$codes->{"product"}->{"ad_id"}->{"$ad_id"}->{"trialPay"}=$trialPayments;
$codes->{"product"}->{"ad_id"}->{"$ad_id"}->{"subsPay"}=$subsPayments;

but it is somewhat repetative to add 10 entries in this way. I’m SURE I found a solution on SO – which I now can’t find. In my script, it is:

$codes->{"product"}->{"ad_id"}->{"$ad_id"}->{
"singlePay"=$singlePayments,
"trialPay"=$trialPayments,
"subsPay"=$subsPayments
};

But I get "Can’t modify constant item in scalar assignment …" I have also tried removing the quotes, and using "fat arrows" on the entries to add, but that doesn’t help. Probably a "schoolboy error", but where am I going wrong?

(As I operate between "PHP" and "Perl", perhaps this structure only works in PHP)

Also, I need to add another object to the entry, so tried "affs"={} and "affs:"={} within the brackets … but that created an error too. I could use the "long" line shown above, but be helpful to do it all in one operation. Here is the required existing structure:

"codes":{
     "product":{
          "ad_id":{
               "itemNo1":{
                    singlePay":"0.00",
                    "trialPay":"0.00",
                    "subsPay":"0.00",
                    "affs":{}
                }
          }
     }
}

2

Answers


  1. Chosen as BEST ANSWER

    See, I told ya it was "schoolboy". The line:

    $codes->{"product"}->{"ad_id"}->{"$ad_id"}->{
    

    Should have been:

    $codes->{"product"}->{"ad_id"}->{"$ad_id"}={
    

    (The last short arrow (->) before the curly bracket should have been an equal sign!! Only taken me three hours to spot that typo !!)


  2. To create a new hash/object, you could use the following:

    $codes->{ product }{ ad_id }{ $ad_id } = {
       singlePay => $singlePayments,
       trialPay  => $trialPayments,
       subsPay   => $subsPayments,
       affs      => { },
    };
    

    To add to an existing hash/object (creating it if it doesn’t exist) without clobbering any other existing fields, you could use the following:

    my $dst = $codes->{ product }{ ad_id }{ $ad_id } //= { };
    
    $dst->{ singlePay } = $singlePayments;
    $dst->{ trialPay  } = $trialPayments;
    $dst->{ subsPay   } = $subsPayments;
    $dst->{ affs      } = { };
    

    We could try other things, like a hash slice.

    $codes->{ product }{ ad_id }{ $ad_id }->@{qw(
       singlePay
       trialPay
       subsPay
       affs
    )} = (
       $singlePayments,
       $trialPayments,
       $subsPayments,
       { },
    );
    

    Not great.

    How about merging hashes?

    my $dst = $codes->{ product }{ ad_id }{ $ad_id } //= { };
    
    %$dst = ( %$dst,
       singlePay => $singlePayments,
       trialPay  => $trialPayments,
       subsPay   => $subsPayments,
       affs      => { },
    );
    

    More expensive, and still not really any better than the solution with which we started.

    Finally, how about a multi-variable foreach loop?

    my $dst = $codes->{ product }{ ad_id }{ $ad_id } //= { };
    
    for my ( $k, $v ) (  # 5.36+
       singlePay => $singlePayments,
       trialPay  => $trialPayments,
       subsPay   => $subsPayments,
       affs      => { },
    ) {
       $dst->{ $k } = $v;
    }
    

    This is clean, but it’s hard to see an advantage (with a fixed number of assignments). And it requires 5.36 which may not be available.

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search