Beefy Boxes and Bandwidth Generously Provided by pair Networks
We don't bite newbies here... much
 
PerlMonks  

= for lists and hashes?

by skazat (Chaplain)
on Mar 20, 2002 at 20:42 UTC ( [id://153127]=perlquestion: print w/replies, xml ) Need Help??

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

Yo yo yo yo yo!

I have a config module with all sorts of nice variables and hashes and arrays. Now, we've created a way to override stuff in the default config module by eval'ing a file that can contain some of the same variables in the config module. This file is evaled at the top of the module and everything below looks like this:
$foo ||= 'something default and generic"; $bar ||= 'something else common place and a good guess';

This works fine and dandy until I hit a hash or an array, and then I get a polite error, such as:

Can't modify array dereference in logical or assignment (||=)

Which just makes me all frowny. Is there an easy way to have the same sort of functionality that I have with ||= and variables for hashes and arrays? I understand that ||= may work differently within a list context, but I don't know what to use in its place.

thanks for the wisdom,

-justin simoni
!skazat!

Replies are listed 'Best First'.
Re: = for lists and hashes?
by RMGir (Prior) on Mar 20, 2002 at 21:01 UTC
    Is there anything that keeps you from saying
    %myHash = ( key1 => 'common Value1', key2 => 'common Value2' ) unless keys %myHash;
    ? Since you're eval'ing the file anyways, there's nothing to keep you from using any perl construct you want, is there?

    You could even hit it key by key, doing

    $myHash{key1} ||= 'common Value1'; $myHash{key2} ||= 'common Value2';

    --
    Mike
      just for completeness: you can also say...
      @myArray = ('common Value1', 'common Value2', ) unless scalar @myArray;

      NOTE: This type of solution breaks down if the user sets @myArray (or %myHash) to an empty array in their conf file (but your existing system of setting scalars breaks down the same way if they have $foo = 0; in their conf file)

        and this will work great for arrays!

        Right now, I can't think of a reason we'd be creating empty arrays... yet ;)

        Thanks!

         

        -justin simoni
        !skazat!

      This will work great for hashes:

      unless keys %myHash;

      I'd hate to hit it key by key, since I have hashes that are almost 100 keys long :)

      uggh.

      Thanks

       

      -justin simoni
      !skazat!

Re: = for lists and hashes?
by Trimbach (Curate) on Mar 20, 2002 at 21:44 UTC
    Default values for hashes are easy (and the common idiom for configs...):
    #!/usr/bin/perl -w my %defaults = (name => "George", age => 26); my %config = (age => 18); my %hash = (%defaults, %config); print "$_ : $hash{$_}\n" foreach (keys %hash);
    Any keys defined in %config will overwrite any keys in %defaults, but if the key isn't in %config the default will prevail. If I'm not mistaken this in the Perl Cookbook somewhere.

    Don't know how you'd only set part of an array without setting all of it without doing something ugly and iterating through each item in each array and seeing where there's a config value and where there's a default.

    Gary Blackburn
    Trained Killer

      I see what you're doing,

      I use that method too in a different project, but I'd really like the hashes and friends to be named the same in the Config module and the config file, that way, we don't get confused. There's more than one hash in the config, but if all I had was name => value pairs, this would be the way to go.

      Thanks

       

      -justin simoni
      !skazat!

        I use that method too in a different project, but I'd really like the hashes and friends to be named the same in the Config module and the config file, that way, we don't get confused.

        I cannot stress enough the potential danger in this. Besides the obvious fact that someone could break security on the owning UID for that file and insert malicious code, there is another, more dire possible effect: you may have to maintain this code.

        What you are currently doing is very fragile, almost completely unscalable, and quite unreadable to someone looking at the code without the benefit of having been there from the beginning. It is far better to develop a regular habit of using a configuration file that is not itself code. Not only does that make for fewer maintenance headaches, it opens the possibility of sharing config resources between applications, moving parts of the application to more modular designs, and a general sense of ease in the world at large.

        If you are not fond of the idea of writing Yet Another Configuration Parser, I recommend starting with examination of AppConfig, Config::General, ParsePlainConfig and XML::Config. Not surprisingly, given Perl's strong text-manipulation abilities, there has been quite a lot of work done in terms of flexible configuration tools.

        --rjray

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others scrutinizing the Monastery: (1)
As of 2024-04-25 04:27 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found