I’m using DBI to connect to Sybase to grab records in a hash_ref element. The DBI::Sybase driver has a nasty habit of returning records with trailing characters, specifically \x00 in my case. I’m trying to write a function to clean this up for all elements in the hashref, the code I have below does the trick, but I can’t find a way to make it leaner, and I know there is away to do this better:
#!/usr/bin/perl
my $dbh = DBI->connect('dbi:Sybase:...');
my $sql = qq {SELECT * FROM table WHERE age > 18;};
my $qry = $dbh->selectall_hashref($sql, 'Name');
foreach my $val(values %$qry) {
$qry->{$val} =~ s/\x00//g;
}
foreach my $key(keys %$qry) {
$qry->{$key} =~ s/\x00//g;
foreach my $val1(keys %{$qry->{$key}}) {
$qry->{$key}->{$val1} =~ s/\x00//g;
}
foreach my $key1(keys %{$qry->{$key}}) {
$qry->{$key}->{$key1} =~ s/\x00//g;
}
While I think that a regex substitution is not exactly an ideal solution (seems like it should be fixed properly instead), here’s a handy way to solve it with
chomp.chompwill remove a single trailing value equal to whatever the input record separator$/is set to. When used on a hash, it will chomp the values.As you will note, we do not need to use the values directly, as they are aliased. Note also the use of a block around the
local $/statement to restrict its scope.For a more manageable solution, it’s probably best to make a subroutine, called recursively. I used
chompagain here, but you can just as easily skip that and uses/\x00//g. Ortr/\x00//d, which basically does the same thing.chompis only safer in that it only removes characters from the end of the string, likes/\x00$//would.