*almost* correct: the return values for $csv->header is a list, not a scalar:
my $csv = Text::CSV_XS->new; # Or Text::CSV
my @hdr = $csv->header ($if, { detect_bom => 1 });
# No need for $csv->column_names, as that is implicit in ->header
Personally I'd go for the easiest solution, where all of that is integrated:
use Text::CSV_XS qw( csv );
my $aoh = csv (in => $dbfile, sep => "\t", bom => 1);
If you need the order of the header later, you can keep that too:
my $aoh = csv (in => $dbfile, sep => "\t", bom => 1, kh => \my @hdr);
Enjoy, Have FUN! H.Merijn