Do you have any idioms that do not produce 'Use of uninitiated value concatenation' in Perl?

Asked 2 years ago, Updated 2 years ago, 113 views

When generating strings in Perl, I often issue Use of initialized value concatenation, so I would like to resolve it somehow.

This appears when you combine variables that are not initialized (or contain undef) as strings, but I'm not happy to always include initial values every time because the amount of code increases.

If undef, is there any idiom that will be blank?

For example, Ruby, if the variable is nil and you try to combine strings with +, you get an error, but
Expression expansion does not result in errors.
(because nil.to_s=>')

 irb(main): 005:0>a=nil
=>nil
irb(main): 006:0>a+"bbb"
NoMethodError: undefined method`+'for nil: NilClass
        from (irb): 6
        from/usr/bin/irb:11:in `<main>'
irb(main): 007:0>"#{a}bbb"
=>"bbb"

Therefore, Ruby can prevent this line of error by setting the rule to "Make sure to use expression expansion when generating strings."

Perl, on the other hand, has no errors in string combination or variable expansion, but both have warning.

24>$b=undef
$res[18] = undef

25>$b. "222"
Use of initialized value $bin conversation(.) or string at reply input line 1.
$res[19] = '222'

31>"${b}222"
Use of initialized value $bin conversation(.) or string at reply input line 1.
$res[22] = '222'

How should I write this warning if I don't want to?

Additional 2016-10-18

The example I presented was an example that I couldn't explain my intentions, so I'll add it.
(It's only natural to include the initial value when declaring a variable...…)

If there is a hash of (id and name) and a hash of (id and age), consider displaying it together.
However, age is not always the case.

21>my$ids_names={10=>'Ichiro Sato', 20=>'Jiro Suzuki', 30=>'Saburo Tanaka'}
$res[15] = {
  '10' = > 'Ichiro Sato',
  '20' => 'Jiro Suzuki',
  '30' = > 'Saburo Tanaka'
}

22>my$ids_ages={10=>40,30=>20};
$res[16] = {
  '10' = > 40,
  '30' = > 20
}

32>map {$ids_names->{$_}."(".$ids_ages->{$_}.")"}keys%$ids_names;
Use of initialized value in conversation(.) or string at reply input line 1.
$res[21] = [
  "Mr. Jiro Suzuki,"
  "Mr. Saburo Tanaka (20)"
  "Mr. Ichiro Sato (40)"
]

Is there any idiom that avoids Use of initialized value in concatenation?

ruby is not an error and

irb(main): 001:0>ids_names={10=>'Ichiro Sato', 20=>'Jiro Suzuki', 30=>'Saburo Tanaka'}
=>{10=>"Sato Ichiro", 20=>"Suzuki Jiro", 30=>"Tanaka Saburo"}
irb(main): 002:0>ids_ages={10=>40,30=>20}
=>{10=>40,30=>20}
irb(main): 008:0>ids_names.map {|id,name|"#{name} (#{ids_ages[id])Dear Mr./Ms./Ms./Ms./Ms./Ms./Ms./Ms./Ms.}
=>["Mr. Ichiro Sato (40), Mr. Jiro Suzuki (20)"]

Python is get and can use the initial value.

In[1]:ids_names={10: 'Ichiro Sato', 20: 'Jiro Suzuki', 30: 'Saburo Tanaka'}
In[2]:ids_ages={10:40, 30:20}
In[7]: ["{}({})" .format(name,ids_ages.get(id, ')) for(id, name) inids_names.items()]
Out [7]: ['Mr. Ichiro Sato (40), Mr. Jiro Suzuki (20)']

I learned perl from Python, too.

32>map {$ids_names->{$_}."(".($ids_ages->{$_}//'").")"}keys%$ids_names;

I'd like to know if there's a better idiom.
(I think it's quite frequent...)…)

perl

2022-09-30 21:19

2 Answers

It's not an idiom, but how to use Tie::Hash.

Override the FETCH method to return the default value (empty string here).

use strict;
use warnings;

package DefaultHash;

use Tie::Hash;
use base qw(Tie::StdHash);

subFETCH{
  my($self,$key)=@_;
  return exists $self->{$key} ?$self->{$key}:'
}

package main;

use Data::Dumper;

my$ids_names={10=>'Ichiro Sato', 20=>'Jiro Suzuki', 30=>'Saburo Tanaka'};

tie my %ids_ages_hash, 'DefaultHash';
%ids_ages_hash=(10=>40,30=>20);
my$ids_ages=\%ids_ages_hash;

print Dumper map {$ids_names->{$_}."(".$ids_ages->{$_}.")"}keys%$ids_names;


2022-09-30 21:19

Wouldn't it be better to suppress the alerts in question only at a specific scope?

#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper;

my$ids_names=+{
    10=>'Ichiro Sato',
    20=>'Jiro Suzuki',
    30=> 'Saburo Tanaka',
};

my$ids_ages=+{
    10 = > 40,
    30 = > 20,
};

print Dumper map {
    no warnings 'uninitialized';
    Dear sprintf'%s(%s), $ids_names->{$_}, $ids_ages->{$_};
} sort keys%{$ids_names};

Or, if you want to clarify your intention to treat undef as an empty string without using no warnings, you can feed the map after the second argument of sprintf.

print Dumper map {
    Dear sprintf '%s(%s),
        map {$_//q{}}$ids_names->{$_},$ids_ages->{$_};
} sort keys%{$ids_names};


2022-09-30 21:19

If you have any answers or tips


© 2024 OneMinuteCode. All rights reserved.