http://www.perlmonks.org?node_id=1203149


in reply to Searching between two hashes

Quite apart from the main concern of your post, the comparison of hashes, another thing that comes to mind is that the sight of those serried ranks of lexical variables marching down the page makes my brain hurt. Not to go all sundialsvc4 on you, but this looks like a guaranteed, copper-bottomed MaintenanceNightmare™.

One approach to this type of organizational problem is to define constant sets of tags. These tags, which can be, e.g., strings, can then be used as hash keys, header lines (when concatenated together), etc. A tag set never changes its order once defined. They can be used with hash slices to assign to and extract data from hashes as an ordered set. E.g.:

c:\@Work\Perl\monks>perl -wMstrict -MData::Dump -le "use constant INPUT_TAGS => ( 'Asset Name', 'Asset Application Id', 'Serial Number', 'Asset Type', 'Activity Status', ); ;; use constant OUTPUT_TAGS => ( 'Serial Number', 'Asset Type', 'Asset Name', ); use constant OUTPUT_FORMAT => '%30s'; ;; my $input_record = 'Northwest Gammage Flocculator,AAI-123,SN9876,Flocculator,Taking Up + Space'; ;; my %hash; @hash{ INPUT_TAGS() } = split ',', $input_record; dd \%hash; ;; print join ' | ', map sprintf(OUTPUT_FORMAT, $_), OUTPUT_TAGS; print join ' | ', map sprintf(OUTPUT_FORMAT, $_), @hash{ OUTPUT_TAGS( +) }; " { "Activity Status" => "Taking Up Space", "Asset Application Id" => "AAI-123", "Asset Name" => "Northwest Gammage Flocculator", "Asset Type" => "Flocculator", "Serial Number" => "SN9876", } Serial Number | Asset Type | + Asset Name SN9876 | Flocculator | Nor +thwest Gammage Flocculator
Note that to disambiguate a constant list for use with a hash slice, the  () (subroutine invocation) operator must be used (update:  & could be used as well, e.g.  &INPUT_TAGS (update: but see choroba's pertinent comment here)) to prevent Perl from interpreting something like  INPUT_TAGS as a string.

Another point is that rather than using a naive split, it's almost always better to use Text::CSV_XS or Text::CSV for extracting CSV-ish data.

Update: Corrected small code example error.


Give a man a fish:  <%-{-{-{-<

Replies are listed 'Best First'.
Re^2: Searching between two hashes
by choroba (Cardinal) on Nov 11, 2017 at 09:07 UTC
    Note that using & for constants prevents them from inlining:
    $ perl -MO=Deparse -e 'use constant C => "abc"; print C' use constant ('C', 'abc'); print 'abc'; -e syntax OK $ perl -MO=Deparse -e 'use constant C => "abc"; print &C' sub C () { 'abc' } use constant ('C', 'abc'); print &C; -e syntax OK
    ($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord }map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,