Beefy Boxes and Bandwidth Generously Provided by pair Networks
go ahead... be a heretic
 
PerlMonks  

Finding Location of Hash Structure?

by mdskrzypczyk (Novice)
on Jul 23, 2015 at 15:00 UTC ( [id://1136011]=perlquestion: print w/replies, xml ) Need Help??

mdskrzypczyk has asked for the wisdom of the Perl Monks concerning the following question:

Hello Monks, for the past couple of days I've been seeking wisdom while I have been attempting to refactor and cleanup a company's perl automation code. I've run into a very odd predicament... There seems to be this hash throughout the automation scripts called CONTACTS, and I've searched high and low through the modules and scripts that are use'd and require'd with no avail to it's location. Is there some method that I can find what script or module this hash originates from? Maybe a line of code that will print out it's origin? Thank you for any suggestions.

Replies are listed 'Best First'.
Re: Finding Location of Hash Structure?
by AnomalousMonk (Archbishop) on Jul 23, 2015 at 16:14 UTC

    Ah, the joys of debugging global variables! Iron-clad employment insurance!! You'll be working on this until the end of time — or until the company goes under, not unlikely if they've got a lot of code like this.

    Here's one approach, not necessarily the best: track down the package the hash lives in (assuming it's a package global):

    c:\@Work\Perl\monks>perl -wMstrict -le "no strict qw(refs vars); no warnings; ;; package Foo; %CONTACTS = ('hello' => 'sailor'); ;; package Bar; $ZOT{'autovivified'} = 'bam'; ;; package main; ;; my $rx_pkg = qr{ \A (?: [[:alpha:]] [[:alnum:]]* ::)+ \z }xms; ;; print qq{'$_'} for grep m{ $rx_pkg }xms, keys %main:: ; print ''; ;; print qq{'$_' has 'CONTACTS'} for grep exists ${$_}{CONTACTS}, grep m{ $rx_pkg }xms, keys %main:: ; print ''; ;; print qq{'$_' has 'ZOT'} for grep exists ${$_}{ZOT}, grep m{ $rx_pkg }xms, keys %main:: ; print ''; ;; print $Foo::CONTACTS{'hello'}; print $Bar::ZOT{'autovivified'}; " 'version::' 'utf8::' 're::' 'CORE::' 'DynaLoader::' 'mro::' 'strict::' 'Win32CORE::' 'Bar::' 'Regexp::' 'UNIVERSAL::' 'Foo::' 'main::' 'Carp::' 'Win32::' 'PerlIO::' 'IO::' 'Exporter::' 'Internals::' 'warnings::' 'DB::' 'Foo::' has 'CONTACTS' 'Bar::' has 'ZOT' sailor bam
    Note that:
    • This code only runs if some strictures are disabled (no strict qw(refs vars);) — and it doesn't hurt to disable warnings also — you may have to turn all these off locally;
    • This shows the package the hash lives in, but how it got there is another story;
    • The example code shows hash definition in Foo, autovivification in Bar. For your purposes, they amount to the same thing.

    Updates:

    1. Added
          no strict qw(refs vars);
          no warnings;
      statements to example code.
    2. Check out Packages and Symbol Tables in perlmod.
    3. Actually, on re-reading the docs, I think
          my $rx_pkg = qr{ \A (?: [[:alpha:]_] \w* ::)+ \z }xms;
      would be a better definition of the package name regex.


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

Re: Finding Location of Hash Structure?
by choroba (Cardinal) on Jul 23, 2015 at 16:11 UTC
    If the code doesn't use strict vars, the global hash will spring into existence when it's first used, so no declaration is needed. Try searching
    grep -r 'CONTACTS.*=' .

    to find code that populates the hash.

    لսႽ† ᥲᥒ⚪⟊Ⴙᘓᖇ Ꮅᘓᖇ⎱ Ⴙᥲ𝇋ƙᘓᖇ
Re: Finding Location of Hash Structure?
by Laurent_R (Canon) on Jul 23, 2015 at 17:41 UTC
    Hm, not entirely sure it will work for your case, but you could try to run the program under the Perl debugger, add a watchpoint on the hash:
    DB<1> w %CONTACTS
    and then issue the c command to run the program. It should presumably stop the first time the hash is modified/populated.
Re: Finding Location of Hash Structure?
by flexvault (Monsignor) on Jul 23, 2015 at 15:19 UTC

    mdskrzypczyk,

    When you use a hash:

    $Hash{"HashID"} = 0;
    but when you define it:
    my %Hash = (); # or just 'my %Hash;'
    so maybe you should look for '%CONTACTS'.

    Regards...Ed

    "Well done is better than well said." - Benjamin Franklin

      How have you looked in your code? When you do grep -rn 'CONTACTS' * in the root directory of your code, every result is $CONTACTS{...}?

      Upate: show complete command
      The way forward always starts with a minimal test.
      I've been looking for the declaration somewhere in the files and have not managed to find it anywhere
        Perl doesn't require declarations.
        Some piece of code puts data in %CONTACTS, some other piece of code uses it. This is kind of a bad programming style, but you run into it a lot in legacy code. You'll just have to look for anything that looks like it's storing data in there.
Re: Finding Location of Hash Structure?
by Anonymous Monk on Jul 23, 2015 at 16:09 UTC

    How are you searching? An eyeball search, or a grep search? You could be grepping for my %CONTACTS in code that uses our %CONTACTS, or my (%CONTACTS), or %Foo::CONTACTS = (...), or use vars qw/%CONTACTS/;. Lots of search terms that could apply.

    Maybe this is code that uses tie to tie %CONTACTS to a database.

    At the top level of your code's directory structure try:

    grep -rin 'tie %CONTACTS' .

    ...and see what you get. It could be nothing. But since nothing else has worked out yet, it doesn't hurt to try.

Re: Finding Location of Hash Structure?
by flexvault (Monsignor) on Jul 23, 2015 at 16:10 UTC

    mdskrzypczyk,

    Using <code> ... </code>, please show an example of how 'CONTACTS' is used.

    It may help us help you.

    Regards...Ed

    "Well done is better than well said." - Benjamin Franklin

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1136011]
Approved by 1nickt
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others having a coffee break in the Monastery: (4)
As of 2024-04-26 05:54 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found