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

I have a few programs in my environment that has the following values hard coded.

Port Number - 1000 host name - abc01.xyz.com username - gvenkat password - ganesh99.

This is the format that has been hard coded.

//Existing Format my $port = 1000; if ( ! $opt_p ){ $port = 1000; } else { $port = $opt_p; } $dbh = DBI->connect("DBI:mysql:database=$dbnam;host=abc01.xyz.com;port +=$port",'gvenkat','ganesh99') //

I want to be able to put the portnumber,hostname,username,password values in a header file and read it from there so that the values are not visible in the actual perl modules.

I'm fairly new to perl and any help would be appreciated.

Replies are listed 'Best First'.
Re: Read from a header file like C
by marto (Cardinal) on Aug 05, 2016 at 14:41 UTC

    There are many ways to use config files within perl, one popular way is with YAML.

    appconf.yaml:

    dsn: 'foo' user: 'userid' password: 'supersecret'

    configtest.pl:

    #!/usr/bin/perl use strict; use warnings; use YAML::XS 'LoadFile'; my $config = LoadFile('appconf.yaml'); my $dsn = $config->{dsn}; my $user = $config->{user}; my $password = $config->{password}; print "dsn: $dsn - user: $user - password: $password\n";

    Update: forgot the output:

    dsn: foo - user: userid - password: supersecret
Re: Read from a header file like C
by toolic (Bishop) on Aug 05, 2016 at 14:28 UTC
    Consider one of the Config modules on CPAN:
Re: Read from a header file like C
by Your Mother (Archbishop) on Aug 05, 2016 at 19:16 UTC

    Don't do it directly in Perl if you're using MySQL. Use their option file; described in DBD::mysql, and look for mysql_read_default_file. File, often named .my.cnf, looks something like (not tested, obviously)–

    [client] port=1000 host=abc01.xyz.com user=gvenkat password=ganesh99. default-character-set=utf8

    Connection–

    my $dbh = DBI->connect("DBI:mysql:$dbnam;mysql_read_default_file=/home +/gvenkat/.my.cnf");

    Lock the file permissions down to 400, owned by the process user that your script uses.

Re: Read from a header file like C
by kennethk (Abbot) on Aug 05, 2016 at 14:46 UTC
    Please read How do I post a question effectively?. In particular, please wrap code and inputs in <code> tags so avoid mangling of whitespace.[Update: corrected in OP; thank you]

    This sounds very much like an XY Problem. What are you trying to accomplish through this obfuscation? It seems unlikely that you will be in an environment where perl runs with different permissions than the individual who is perusing your script. There is value in abstracting common constants that are shared across scripts, but that should probably be done with modules, e.g.

    package Gvenkat5; use strict; use warnings; use DBI; require Exporter; @EXPORT_OK = 'connect'; sub connect { my $port = shift || 1000; my $dbnam = ''; return DBI->connect("DBI:mysql:database=$dbnam; host=abc01.xyz.com; port=$port", 'gvenkat', 'ganesh99') }
    and
    use Gvenkat5 'connect'; my $dbh = connect($ARGV[0]);
    or, for literal values, YAML or equivalent as suggested.

    #11929 First ask yourself `How would I do this without a computer?' Then have the computer do it the same way.

Re: Read from a header file like C
by Marshall (Canon) on Aug 05, 2016 at 16:35 UTC
    I looked around on my ActivePerl 5.20 machine to see what modules would already be there without me having to install anything. Turns out the super light-weight Config::Tiny ships with the distribution. In the doc, more sophisticated versions are mentioned. The code is similar to the YAML example, except the format is in Windows .ini format.
    #!user/bin/perl use strict; use warnings; use Data::Dumper; use Config::Tiny; my $file=<<END; [DBname] Port Number = 1000 host name = abc01.xyz.com username = gvenkat password = ganesh99 END my $Config = Config::Tiny->new; $Config = Config::Tiny->read( \$file ); my $portnum = $Config->{DBname}->{'Port Number'}; print "$portnum\n"; my $hostname = $Config->{DBname}->{'host name'}; print "$hostname\n"; my $username = $Config->{DBname}->{'username'}; print "$username\n"; my $password = $Config->{DBname}->{'password'}; print "$password\n"; my $href = $Config->{DBname}; print Dumper $href; __END__ 1000 abc01.xyz.com gvenkat ganesh99 $VAR1 = { 'username' => 'gvenkat', 'Port Number' => '1000', 'host name' => 'abc01.xyz.com', 'password' => 'ganesh99' };
    I'd store any other config stuff in the DB. Looks like the purpose is just to "get going" without having to modify the code itself.

    Update: I looked at the post from Your Mother at Re: Read from a header file like C. That seems to be the way to go for MySQL. Similar format to the above.

Re: Read from a header file like C
by marto (Cardinal) on Aug 05, 2016 at 15:33 UTC
Re: Read from a header file like C
by crusty_collins (Friar) on Aug 05, 2016 at 15:59 UTC
    You can do that with a suprisingly small amount of code. What I use is a hash ref to store the variables,
    sub getEnv { my $file = shift(@_); my $ref = shift(@_); unless (-f $file) { print "Could not find $file.\n"; exit(1); } open (FILE, "< $file"); while (<FILE>) { chomp; next if /^\s*\#/; next unless /=/; my ($key, $variable) = split(/=/,$_,2); $variable =~ s/\s+//g; $key =~ s/\s+//g; $ref->{config}->{$key} = $variable; } close FILE; }
    Config File
    port=100 host=some.host.com
    "We can't all be happy, we can't all be rich, we can't all be lucky – and it would be so much less fun if we were. There must be the dark background to show up the bright colours." Jean Rhys (1890-1979)