[32414] in Perl-Users-Digest
Perl-Users Digest, Issue: 3681 Volume: 11
daemon@ATHENA.MIT.EDU (Perl-Users Digest)
Wed May 2 03:09:28 2012
Date: Wed, 2 May 2012 00:09:07 -0700 (PDT)
From: Perl-Users Digest <Perl-Users-Request@ruby.OCE.ORST.EDU>
To: Perl-Users@ruby.OCE.ORST.EDU (Perl-Users Digest)
Perl-Users Digest Wed, 2 May 2012 Volume: 11 Number: 3681
Today's topics:
Re: First Commercial Perl Program <rurban@cpanel.net>
Re: First Commercial Perl Program <m@rtij.nl.invlalid>
Re: First Commercial Perl Program <ben@morrow.me.uk>
Help with Hash Array <artmerar@yahoo.com>
Re: Help with Hash Array <rweikusat@mssgmbh.com>
Re: Help with Hash Array <glex_no-spam@qwest-spam-no.invalid>
Re: Help with Hash Array <glex_no-spam@qwest-spam-no.invalid>
Re: Help with Hash Array <artmerar@yahoo.com>
Re: Help with Hash Array <glex_no-spam@qwest-spam-no.invalid>
Quick Question on Including Files <artmerar@yahoo.com>
Re: Quick Question on Including Files <ben@morrow.me.uk>
Re: Quick Question on Including Files (Tim McDaniel)
Re: What is this module using? <rurban@cpanel.net>
Re: What is this module using? <ben@morrow.me.uk>
Re: What is this module using? <rurban@cpanel.net>
Digest Administrivia (Last modified: 6 Apr 01) (Perl-Users-Digest Admin)
----------------------------------------------------------------------
Date: Tue, 01 May 2012 10:55:52 -0500
From: Reini Urban <rurban@cpanel.net>
Subject: Re: First Commercial Perl Program
Message-Id: <jnp125$hme$1@speranza.aioe.org>
On 03/10/2012 01:18 PM, tbb!/fbr! wrote:
> I entered the professional perl programming world by being paid
> (that's what I call professional, though the code may be far from)
> for
> a very small perl script. The user basically wanted a config file
> which contained as the first line a username, the second line a
> password, and the remaining lines to be hotnames.
> ex.
> user
> pass
> 127.0.0.1
> 127.0.0.2
> Then I wrote the following script. It gathers the user, pass, and
> hostlist, and then establishes an ssh connection to query a 'device'
> and return the output in a file named after the host. Following is
> that program:
> #!/usr/bin/perl
> # Code by
> # For
> # dmon-1.6
> use warnings;
> use strict;
> use Net::SSH::Perl;
> my $cfgfile="./config";
> open CONFIG, "<", $cfgfile || die $!;
> chomp(my @cfgdat=(<CONFIG>));
> my $user=shift(@cfgdat);
> my $pass=shift(@cfgdat);
> my $extcmd="ls -l";
> my $stime=3;
> while (defined $stime) {
> foreach (@cfgdat) {
> my $ssh=Net::SSH::Perl->new($_);
> $ssh->login($user,$pass);
> my ($stdout,$stderr,$exit)=$ssh->cmd($extcmd);
> open OUTFILE, ">>", $_ || die $!;
> if ($stdout) {
> print OUTFILE $stdout;
> }
> if ($stderr) {
> print OUTFILE $stderr;
> }
> close OUTFILE;
> }
> sleep $stime;
> }
>
> I am just looking for critique. I have been a Unix Admin for over 15
> years, and have used perl for one off scripts, but I spent time and
> master Oreillys Learning Perl and Intermediate Perl (Mastering and
> Advanced Perl are next) and am now looking to solely become a
> commercial perl programmer. However, as I lack commercial experience,
> I probably lack a 'standard' way of approaching things, or at least
> don't know what experienced perl programmers know, which I'll learn
> as
> a function of time. Either way, if you have time, let me know how I
> could have done all this better, and maybe even a source of
> commercial
> perl programs I can look at and see how pro's do it.
> Ron
Overall this approach is non-sense, as you might probably know as sysadmin.
1. password in cleartext for ssh?
never do that. even if the customer is to stupid to understand that, you
should just refuse to do that and ssh-copy-id instead.
if the target machine has ssh, copy your key over to it.
only if its some antique router with telnet only, I saw plaintext
passwords attempts, but then at least store them encrypted.
2. stupid config format
there's a established format for this type of problem, which is
basically the ssh connection format.
user@hostname1
user@hostname2
3. why perl when a simple shell script is much simplier and short?
for h in `cat .config`; do
ssh $h ls -l
done
oh my
--
Reini
------------------------------
Date: Tue, 1 May 2012 19:22:32 +0200
From: Martijn Lievaart <m@rtij.nl.invlalid>
Subject: Re: First Commercial Perl Program
Message-Id: <oni579-q2q.ln1@news.rtij.nl>
On Tue, 01 May 2012 10:55:52 -0500, Reini Urban wrote:
> 1. password in cleartext for ssh?
> never do that. even if the customer is to stupid to understand that, you
> should just refuse to do that and ssh-copy-id instead.
And what does a private key stored in plaintext buy you over a password
stored in plaintext?
(Yes, there is an advantage, but it is not obvious. Do you know it?)
M4
------------------------------
Date: Tue, 1 May 2012 23:09:02 +0100
From: Ben Morrow <ben@morrow.me.uk>
Subject: Re: First Commercial Perl Program
Message-Id: <ug3679-jhp1.ln1@anubis.morrow.me.uk>
Quoth Martijn Lievaart <m@rtij.nl.invlalid>:
> On Tue, 01 May 2012 10:55:52 -0500, Reini Urban wrote:
>
> > 1. password in cleartext for ssh?
> > never do that. even if the customer is to stupid to understand that, you
> > should just refuse to do that and ssh-copy-id instead.
>
> And what does a private key stored in plaintext buy you over a password
> stored in plaintext?
>
> (Yes, there is an advantage, but it is not obvious. Do you know it?)
It can be revoked, obviously. This means, as a corollary, that you
should never use the same private key on more than one machine.
As a matter of general security, a randomly-generated key is also not
subject to dictionary attacks, which a user-chosen password generally
will be. This is not relevant here, of course.
(In general I don't consider ssh keys particularly secure, and would
rather use Kerberos, but that isn't usually possible across
authentication domains.)
Ben
------------------------------
Date: Mon, 30 Apr 2012 13:40:25 -0700 (PDT)
From: ExecMan <artmerar@yahoo.com>
Subject: Help with Hash Array
Message-Id: <cdcde8e7-9b47-4b3e-b09b-a0d6febb0f2a@e42g2000yqa.googlegroups.com>
Hi,
I have a somewhat complex hash array, below. I want to know how to
access individual items within the inner hash.
With the example below, say I need the SUBJECT: $subj =
$SERVICES{'tactical'}->{subject};
However, say I need to get the COMMAND from the ALERT array with the
name SENDBUY. The value I am looking for is: trader.pl -B
But I am not sure how to turn the ALERT item into a hash so I can
access it by value, rather than by an array index.
Can anyone help??
%SERVICES = (
'tactical' => {
'service' => "tactical",
'url' => "tacticaltrader",
'from' => "Tactical Trader <tacticaltrader\@mail.com>",
'mailer' => "Tactical Trader Mailer",
'subject' => "Tactical Trader Summary",
'alert' => [
{ 'name' => "GENERATE", 'html' =>
"sid=group_id=29&ctype=0", 'command' => "eod-trader.pl -t -M",},
{ 'name' => "GENERATEBUY", 'html' =>
"sid=group_id=29&ctype=1", 'command' => "trader.pl -t -B -M",},
{ 'name' => "GENERATESELL", 'html' =>
"sid=group_id=29&ctype=2", 'command' => "trader.pl -t -S -M",},
{ 'name' => "SEND", 'html' =>
"sid=group_id=29&ctype=0", 'command' => "eod-trader.pl",},
{ 'name' => "SENDBUY", 'html' =>
"sid=group_id=29&ctype=1", 'command' => "trader.pl -B",},
{ 'name' => "SENDSELL", 'html' =>
"sid=group_id=29&ctype=2", 'command' => "trader.pl -S",},
{ 'name' => "GENERATEINTRA",'html' =>
"sid=group_id=29&ctype=3", 'command' => "trader.pl -t -I -M",},
{ 'name' => "SENDINTRA", 'html' =>
"sid=group_id=29&ctype=3", 'command' => "trader.pl",},
],
},
)
------------------------------
Date: Mon, 30 Apr 2012 22:10:00 +0100
From: Rainer Weikusat <rweikusat@mssgmbh.com>
Subject: Re: Help with Hash Array
Message-Id: <87obq99b9z.fsf@sapphire.mobileactivedefense.com>
ExecMan <artmerar@yahoo.com> writes:
>
> I have a somewhat complex hash array, below. I want to know how to
> access individual items within the inner hash.
>
> With the example below, say I need the SUBJECT: $subj =
> $SERVICES{'tactical'}->{subject};
>
> However, say I need to get the COMMAND from the ALERT array with the
> name SENDBUY. The value I am looking for is: trader.pl -B
>
> But I am not sure how to turn the ALERT item into a hash so I can
> access it by value, rather than by an array index.
[see original for data structure]
Assuming you just want to search for first matching the alert:
-----------
# insert your definition here
sub search_alert
{
my ($srvs, $cmd) = @_;
$cmd eq $_->{name} and return $_
for (@{$srvs->{alert}});
}
$buy = search_alert($SERVICES{tactical}, 'SENDBUY');
print($buy->{command}, "\n") if $buy;
-----------
If you need to access alerts regularly both by position (or 'in
order') and by command/ name, you migh want to consider putting them
into the in-order 'alert array' and additionally, putting them into a
hash indexed by name. If you can have more then one pending alert
with a particular name, something more complicated would need to be
done here.
Example 'add an alert' routine for the simpler case (untested)
----------
sub add_alert
{
my ($alert, $srvs) = @_;
$srvs->{alerts_by_name}{$alert->{name}} = $alert;
push(@{$srvs->{alerts_in_order}}, $alert);
}
---------
------------------------------
Date: Mon, 30 Apr 2012 17:06:50 -0500
From: "J. Gleixner" <glex_no-spam@qwest-spam-no.invalid>
Subject: Re: Help with Hash Array
Message-Id: <4f9f0cfa$0$73609$815e3792@news.qwest.net>
On 04/30/12 15:40, ExecMan wrote:
> Hi,
>
> I have a somewhat complex hash array, below. I want to know how to
> access individual items within the inner hash.
>
> With the example below, say I need the SUBJECT: $subj =
> $SERVICES{'tactical'}->{subject};
No need for the '->' there..
my $subj = $SERVICES{'tactical'}{ 'subject' };
>
> However, say I need to get the COMMAND from the ALERT array with the
> name SENDBUY. The value I am looking for is: trader.pl -B
>
> But I am not sure how to turn the ALERT item into a hash so I can
> access it by value, rather than by an array index.
You don't show how you're creating %SERVICES, however...
If the value for 'name' is *always* unique, then you could
use that value as a key, instead of storing things as an array. e.g.
$name = 'GENERATE';
$SERVICES{ 'tactical' }{ 'alert' }{ $name } = {
html => 'sid=group_id=29&ctype=0',
command => 'eod-trader.pl -t -M',
};
Which would let you access the various values directly:
print "command=",
$SERVICES{'tactical' }{ 'alert' }{ 'GENERATE' }{ 'command' },
"\n";
Using your current data structure it's not so bad...
use Data::Dumper;
for my $rec ( @{ $SERVICES{ 'tactical' }{ 'alert' } } )
{
if( $rec->{ 'name' } eq 'SENDBUY' )
{
print 'command = ', $rec->{ 'command' }, "\n";
}
}
>
> Can anyone help??
>
> %SERVICES = (
> 'tactical' => {
> 'service' => "tactical",
> 'url' => "tacticaltrader",
> 'from' => "Tactical Trader<tacticaltrader\@mail.com>",
> 'mailer' => "Tactical Trader Mailer",
> 'subject' => "Tactical Trader Summary",
> 'alert' => [
> { 'name' => "GENERATE", 'html' =>
> "sid=group_id=29&ctype=0", 'command' => "eod-trader.pl -t -M",},
> { 'name' => "GENERATEBUY", 'html' =>
> "sid=group_id=29&ctype=1", 'command' => "trader.pl -t -B -M",},
> { 'name' => "GENERATESELL", 'html' =>
> "sid=group_id=29&ctype=2", 'command' => "trader.pl -t -S -M",},
> { 'name' => "SEND", 'html' =>
> "sid=group_id=29&ctype=0", 'command' => "eod-trader.pl",},
> { 'name' => "SENDBUY", 'html' =>
> "sid=group_id=29&ctype=1", 'command' => "trader.pl -B",},
> { 'name' => "SENDSELL", 'html' =>
> "sid=group_id=29&ctype=2", 'command' => "trader.pl -S",},
> { 'name' => "GENERATEINTRA",'html' =>
> "sid=group_id=29&ctype=3", 'command' => "trader.pl -t -I -M",},
> { 'name' => "SENDINTRA", 'html' =>
> "sid=group_id=29&ctype=3", 'command' => "trader.pl",},
> ],
> },
> )
------------------------------
Date: Mon, 30 Apr 2012 17:14:26 -0500
From: "J. Gleixner" <glex_no-spam@qwest-spam-no.invalid>
Subject: Re: Help with Hash Array
Message-Id: <4f9f0ec2$0$63194$815e3792@news.qwest.net>
On 04/30/12 17:06, J. Gleixner wrote:
[...]
> Using your current data structure it's not so bad...
>
> use Data::Dumper;
^^^ Ignore that.. I meant to use that, to show the structure
of $rec, but figured showing the code to get the value might
be better.
>
> for my $rec ( @{ $SERVICES{ 'tactical' }{ 'alert' } } )
> {
> if( $rec->{ 'name' } eq 'SENDBUY' )
> {
> print 'command = ', $rec->{ 'command' }, "\n";
> }
> }
------------------------------
Date: Mon, 30 Apr 2012 21:52:05 -0700 (PDT)
From: ExecMan <artmerar@yahoo.com>
Subject: Re: Help with Hash Array
Message-Id: <ed145c98-7895-44d3-a2e1-a3e504054db2@d4g2000vbn.googlegroups.com>
On Apr 30, 5:06=A0pm, "J. Gleixner" <glex_no-s...@qwest-spam-no.invalid>
wrote:
> On 04/30/12 15:40, ExecMan wrote:
>
> > Hi,
>
> > I have a somewhat complex hash array, below. =A0I want to know how to
> > access individual items within the inner hash.
>
> > With the example below, say I need the SUBJECT: =A0$subj =3D
> > $SERVICES{'tactical'}->{subject};
>
> No need for the '->' there..
>
> my $subj =3D $SERVICES{'tactical'}{ 'subject' };
>
>
>
> > However, say I need to get the COMMAND from the ALERT array with the
> > name SENDBUY. =A0The value I am looking for is: =A0trader.pl -B
>
> > But I am not sure how to turn the ALERT item into a hash so I can
> > access it by value, rather than by an array index.
>
> You don't show how you're creating %SERVICES, however...
>
> If the value for 'name' is *always* unique, then you could
> use that value as a key, instead of storing things as an array. =A0e.g.
>
> $name =3D 'GENERATE';
> $SERVICES{ 'tactical' }{ 'alert' }{ $name } =3D {
> =A0 =A0 html =A0 =A0=3D> 'sid=3Dgroup_id=3D29&ctype=3D0',
> =A0 =A0 command =3D> =A0'eod-trader.pl -t -M',
>
> };
>
> Which would let you access the various values directly:
>
> print "command=3D",
> =A0 =A0 $SERVICES{'tactical' }{ 'alert' }{ 'GENERATE' }{ 'command' },
> =A0 =A0 "\n";
>
> Using your current data structure it's not so bad...
>
> use Data::Dumper;
>
> for my $rec ( @{ $SERVICES{ 'tactical' }{ 'alert' } } )
> {
> =A0 =A0if( $rec->{ 'name' } eq 'SENDBUY' )
> =A0 =A0{
> =A0 =A0 =A0print 'command =3D ', $rec->{ 'command' }, "\n";
> =A0 =A0}
>
> }
>
> > Can anyone help??
>
> > %SERVICES =3D (
> > =A0 =A0'tactical' =3D> =A0{
> > =A0 =A0 =A0'service' =3D> =A0"tactical",
> > =A0 =A0 =A0'url' =A0 =A0 =3D> =A0"tacticaltrader",
> > =A0 =A0 =A0'from' =A0 =A0=3D> =A0"Tactical Trader<tacticaltrader\@mail.=
com>",
> > =A0 =A0 =A0'mailer' =A0=3D> =A0"Tactical Trader Mailer",
> > =A0 =A0 =A0'subject' =3D> =A0"Tactical Trader Summary",
> > =A0 =A0 =A0'alert' =A0 =3D> =A0[
> > =A0 =A0 =A0 =A0 { 'name' =3D> =A0"GENERATE", =A0 =A0 'html' =3D>
> > "sid=3Dgroup_id=3D29&ctype=3D0", 'command' =3D> =A0"eod-trader.pl -t -M=
",},
> > =A0 =A0 =A0 =A0 { 'name' =3D> =A0"GENERATEBUY", =A0'html' =3D>
> > "sid=3Dgroup_id=3D29&ctype=3D1", 'command' =3D> =A0"trader.pl -t -B -M"=
,},
> > =A0 =A0 =A0 =A0 { 'name' =3D> =A0"GENERATESELL", 'html' =3D>
> > "sid=3Dgroup_id=3D29&ctype=3D2", 'command' =3D> =A0"trader.pl -t -S -M"=
,},
> > =A0 =A0 =A0 =A0 { 'name' =3D> =A0"SEND", =A0 =A0 =A0 =A0 'html' =3D>
> > "sid=3Dgroup_id=3D29&ctype=3D0", 'command' =3D> =A0"eod-trader.pl",},
> > =A0 =A0 =A0 =A0 { 'name' =3D> =A0"SENDBUY", =A0 =A0 =A0'html' =3D>
> > "sid=3Dgroup_id=3D29&ctype=3D1", 'command' =3D> =A0"trader.pl -B",},
> > =A0 =A0 =A0 =A0 { 'name' =3D> =A0"SENDSELL", =A0 =A0 'html' =3D>
> > "sid=3Dgroup_id=3D29&ctype=3D2", 'command' =3D> =A0"trader.pl -S",},
> > =A0 =A0 =A0 =A0 { 'name' =3D> =A0"GENERATEINTRA",'html' =3D>
> > "sid=3Dgroup_id=3D29&ctype=3D3", 'command' =3D> =A0"trader.pl -t -I -M"=
,},
> > =A0 =A0 =A0 =A0 { 'name' =3D> =A0"SENDINTRA", =A0 =A0'html' =3D>
> > "sid=3Dgroup_id=3D29&ctype=3D3", 'command' =3D> =A0"trader.pl",},
> > =A0 =A0 =A0],
> > =A0 =A0},
> > )
>
>
Well, it is only unique within each ALERT array. Each SERVICE,
although they have the same ALERT names, the values will be different
for HTML and COMMAND. How can I reference the ALERT part by a key for
the NAME?
Thanks!
------------------------------
Date: Tue, 01 May 2012 10:05:48 -0500
From: "J. Gleixner" <glex_no-spam@qwest-spam-no.invalid>
Subject: Re: Help with Hash Array
Message-Id: <4f9ffbcc$0$52267$815e3792@news.qwest.net>
On 04/30/12 23:52, ExecMan wrote:
> On Apr 30, 5:06 pm, "J. Gleixner"<glex_no-s...@qwest-spam-no.invalid>
> wrote:
>> On 04/30/12 15:40, ExecMan wrote:
>>
>>> Hi,
>>
>>> I have a somewhat complex hash array, below. I want to know how to
>>> access individual items within the inner hash.
>>
>>> With the example below, say I need the SUBJECT: $subj =
>>> $SERVICES{'tactical'}->{subject};
>>
>> No need for the '->' there..
>>
>> my $subj = $SERVICES{'tactical'}{ 'subject' };
>>
>>
>>
>>> However, say I need to get the COMMAND from the ALERT array with the
>>> name SENDBUY. The value I am looking for is: trader.pl -B
>>
>>> But I am not sure how to turn the ALERT item into a hash so I can
>>> access it by value, rather than by an array index.
>>
>> You don't show how you're creating %SERVICES, however...
>>
>> If the value for 'name' is *always* unique, then you could
>> use that value as a key, instead of storing things as an array. e.g.
>>
>> $name = 'GENERATE';
>> $SERVICES{ 'tactical' }{ 'alert' }{ $name } = {
>> html => 'sid=group_id=29&ctype=0',
>> command => 'eod-trader.pl -t -M',
>>
>> };
>>
>> Which would let you access the various values directly:
>>
>> print "command=",
>> $SERVICES{'tactical' }{ 'alert' }{ 'GENERATE' }{ 'command' },
>> "\n";
[...]
>
> Well, it is only unique within each ALERT array. Each SERVICE,
> although they have the same ALERT names, the values will be different
> for HTML and COMMAND. How can I reference the ALERT part by a key for
> the NAME?
That sounds fine. As I mentioned above...
As long as there isn't another 'name', that's the same, within alert..
e.g. if something like this doesn't happen:
>>> %SERVICES = (
>>> 'tactical' => {
>>> 'service' => "tactical",
>>> 'url' => "tacticaltrader",
>>> 'from' => "Tactical Trader<tacticaltrader\@mail.com>",
>>> 'mailer' => "Tactical Trader Mailer",
>>> 'subject' => "Tactical Trader Summary",
>>> 'alert' => [
>>> { 'name' => "GENERATE", 'html' =>
>>> "sid=group_id=29&ctype=0", 'command' => "eod-trader.pl -t -M",},
{ 'name' => "GENERATE", 'html' => "something",
'command' => "something",},
Then you can use what I posted. Use the value of what's in 'name'
( e.g. GENERATE ) as a key within the 'alert' hash, instead of an
array. Depending on what else you're doing, you might not need
the 'alert array', you need an 'alert hash', or you can make
another data structure... maybe 'alert_h' and store the name
as the key, as I showed above.
Try it and if you have questions, show how you're building %SERVICES.
It's probably a matter of changing a push, to do something like my
initial response.
------------------------------
Date: Tue, 1 May 2012 17:15:19 -0700 (PDT)
From: ExecMan <artmerar@yahoo.com>
Subject: Quick Question on Including Files
Message-Id: <900a6926-abb0-4e24-921b-667538177392@ri8g2000pbc.googlegroups.com>
Hi,
I have created a file with a data structure in it. I want to include
that file into a number of scripts.
I have code like this:
my %SERVICES;
if (-e "hash_config") {
require "hash_config";
}
But it is not working?? The structure is just empty. The structure
is like the one I created with everyone's help:
%SERVICES = (
'tactical' => {
'service' => "tactical,
'url' => "tacticaltrader",
'from' => "Tactical Trader <tacticaltrader\@mail.com>",
'mailer' => "Tactical Trader Mailer",
'subject' => "Tactical Trader Summary",
'alert' => {
'GENERATE' => { 'html' =>
"sid=SCt78s8Uf4Hml80&group_id=29&ctype=0", 'command' => "eod-trader.pl
-t -M",},
'GENERATEBUY' => { 'html' =>
"sid=SCt78s8Uf4Hml80&group_id=29&ctype=1", 'command' => "trader.pl -t -
B -M",},
'GENERATESELL' => { 'html' =>
"sid=SCt78s8Uf4Hml80&group_id=29&ctype=2", 'command' => "trader.pl -t -
S -M",},
'SEND' => { 'html' =>
"sid=SCt78s8Uf4Hml80&group_id=29&ctype=0", 'command' => "eod-
trader.pl",},
'SENDBUY' => { 'html' =>
"sid=SCt78s8Uf4Hml80&group_id=29&ctype=1", 'command' => "trader.pl -
B",},
'SENDSELL' => { 'html' =>
"sid=SCt78s8Uf4Hml80&group_id=29&ctype=2", 'command' => "trader.pl -
S",},
'GENERATEINTRA' => { 'html' =>
"sid=SCt78s8Uf4Hml80&group_id=29&ctype=3", 'command' => "trader.pl -t -
I -M",},
'SENDINTRA' => { 'html' =>
"sid=SCt78s8Uf4Hml80&group_id=29&ctype=3", 'command' => "trader.pl",},
},
},
);
Help anyone? How do I make this an include so I can reference it?
Thanks!
------------------------------
Date: Wed, 2 May 2012 03:34:13 +0100
From: Ben Morrow <ben@morrow.me.uk>
Subject: Re: Quick Question on Including Files
Message-Id: <52j679-mus1.ln1@anubis.morrow.me.uk>
Quoth ExecMan <artmerar@yahoo.com>:
>
> I have created a file with a data structure in it. I want to include
> that file into a number of scripts.
>
> I have code like this:
>
> my %SERVICES;
>
> if (-e "hash_config") {
> require "hash_config";
> }
>
> But it is not working?? The structure is just empty.
The variable you created above, 'my %SERVICES', is not visible outside
the file where you declared it. This is part of the point of 'my': since
the variable isn't visible outside that file, you can have a variable
called %SERVICES in some other file without worrying about conflicts.
However, for what you are trying to to, it gets in the way a little.
There are several possible solutions here. The cleanest, IMHO, is to use
'do' instead of 'require'. Unlike 'require', 'do' returns the last
expression evaluated in the file, so you can write it like this:
# Always keep your filenames in variables. That way, when you want
# to move the config file, you only have to change the name in one
# place.
my $config = "hash_config";
my %SERVICES;
if (-e $config) {
%SERVICES = do $config;
}
Then you want your config file to *just* contain the data structure,
without any variable assignment, like this
tactical => {
service => "tactical",
url => "tacticaltrader",
...
},
...
Alternatively, if you particularly want to use 'require', you can make
%SERVICES an 'our' rather than a 'my' variable. 'our' variables are true
globals, visible throughout the entire program, so you can then assign
to one from a required file:
my $config = "hash_config";
our %SERVICES;
if (-e $config) {
require $config;
}
with the config file as you had it before.
You should also be aware that 'strict' and 'warnings' also only apply to
the current file (actually, to the current block scope). If you want
them to apply to the included file, and if it's a complicated data
structure you probably do, then you need to put them in again at the top
of that file.
If you had done this before, you would have got a 'strict' error about
%SERVICES, since that variable hadn't been declared in that file. If you
%choose the second option above, you will also need to declare %SERVICES
%with 'our' in the config file:
use warnings;
use strict;
our %SERVICES = (
...
);
The fact that you use 'our' means that both files see the same variable:
if you had used 'my' in both files, they would have instead seen
*different* variables which happened to have the same name.
You may also want to consider using a general-purpose data format,
rather than a Perl data structure. Either YAML::XS or JSON::XS would be
good choices here (don't use the modules without 'XS' in their names,
they're not as reliable, particularly YAML).
Ben
------------------------------
Date: Wed, 2 May 2012 06:41:30 +0000 (UTC)
From: tmcd@panix.com (Tim McDaniel)
Subject: Re: Quick Question on Including Files
Message-Id: <jnqkuq$ods$1@reader1.panix.com>
In article <52j679-mus1.ln1@anubis.morrow.me.uk>,
Ben Morrow <ben@morrow.me.uk> wrote:
> if (-e $config) {
> %SERVICES = do $config;
> }
>
>Then you want your config file to *just* contain the data structure,
>without any variable assignment, like this
>
> tactical => {
> service => "tactical",
> url => "tacticaltrader",
> ...
> },
> ...
If you use this syntax, I think the parentheses around the list have
to be supplied somewhere, though I've not tested it. That is, I think
it has to be either
%SERVICES = (do $config);
or the config file has to be
(
tactical => {
service => "tactical",
url => "tacticaltrader",
...
},
...
)
I looked at perlfunc do and came up with this test program.
It has an error-checking scheme that nearly requires a scalar return
value (otherwise, an error return in
my %x = (do "./103a.pl");
would cause warnings
Odd number of elements in hash assignment
Use of uninitialized value in list assignment
and result in a hash of
'' => undef
).
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#! /usr/bin/perl
use strict;
use warnings;
use Data::Dumper;
my $x = do "./103a.pl";
warn "couldn't parse file: $@" if $@;
warn "couldn't do file: $!" unless defined $x;
warn "couldn't run file" unless $x;
my %x = %{$x};
print Data::Dumper->Dump([\%x], [qw[x]]), "\n";
exit 0;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[this is 103a.pl]
use strict;
use warnings;
{
a => 'b',
c => 'd',
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
This does error checking: see what happens if you put a syntax error
in the included file (here, 103a.pl).
It does not require "our" variables.
--
Tim McDaniel, tmcd@panix.com
------------------------------
Date: Mon, 30 Apr 2012 08:38:54 -0500
From: Reini Urban <rurban@cpanel.net>
Subject: Re: What is this module using?
Message-Id: <jnm4lc$fd2$1@speranza.aioe.org>
On 04/18/2012 06:32 PM, Ben Morrow wrote:
>
> Quoth Eli the Bearded<*@eli.users.panix.com>:
>> In comp.lang.perl.misc, Ben Morrow<ben@morrow.me.uk> wrote:
>>> Quoth tmcd@panix.com:
>>>> Looking at the docs, it appears that Devel::Modlist reports on *all*
>>>> the modules used in an entire script. Is there some way I can
>>>> determine the modules used, directly or transitively, merely by the
>>>> current module?
>>>
>>> perl -d:Modlist -mMy::Module -e1 ?
>>
>> That's not necessarily going to work. Consider:
>>
>> perl -d:Modlist -mCPAN -e1
>>
>> When I run that it doesn't mention Storable, LWP::*, or Time::*
>> but all three were used by CPAN just seconds before when I ran
>> "install Devel::Modlist":
>
> True. Modules loaded at runtime are inherently harder, since you have to
> run the program (with all possible inputs) to see them.
>
> A CORE::GLOBAL::require hook which checks caller() looks like the best
> answer, to me. You probably want to check (caller)[1] as well as
> (caller)[0], or just check [1] while being careful to step back over
> string evals until you find a real file.
For an easier way, I'd rather print the %INC keys in an END block, as
require stores the loaded module names there.
perl -mCPAN -e'END{print(join qq(\n),keys %INC)}'
This does not print the package names per se, but the relative paths of
all loaded modules.
s{/}{::}g; s{\.p[lm]$}{}; will do pretty printing of the names.
--
Reini
------------------------------
Date: Mon, 30 Apr 2012 14:58:58 +0100
From: Ben Morrow <ben@morrow.me.uk>
Subject: Re: What is this module using?
Message-Id: <2ei279-ct31.ln1@anubis.morrow.me.uk>
Quoth Reini Urban <rurban@cpanel.net>:
> On 04/18/2012 06:32 PM, Ben Morrow wrote:
> >
> > A CORE::GLOBAL::require hook which checks caller() looks like the best
> > answer, to me. You probably want to check (caller)[1] as well as
> > (caller)[0], or just check [1] while being careful to step back over
> > string evals until you find a real file.
>
> For an easier way, I'd rather print the %INC keys in an END block, as
> require stores the loaded module names there.
Read the OP. Tim (the OP) was asking for a way to find modules required
(recursively) only by one particular module, not modules required by the
whole program. Devel::Modlist is basically a cleaned-up version of
'print %INC in an END block', and Tim was looking for an alternative.
Ben
------------------------------
Date: Tue, 01 May 2012 10:44:33 -0500
From: Reini Urban <rurban@cpanel.net>
Subject: Re: What is this module using?
Message-Id: <jnp0cu$fjr$1@speranza.aioe.org>
On 04/30/2012 08:58 AM, Ben Morrow wrote:
>
> Quoth Reini Urban<rurban@cpanel.net>:
>> On 04/18/2012 06:32 PM, Ben Morrow wrote:
>>>
>>> A CORE::GLOBAL::require hook which checks caller() looks like the best
>>> answer, to me. You probably want to check (caller)[1] as well as
>>> (caller)[0], or just check [1] while being careful to step back over
>>> string evals until you find a real file.
>>
>> For an easier way, I'd rather print the %INC keys in an END block, as
>> require stores the loaded module names there.
>
> Read the OP. Tim (the OP) was asking for a way to find modules required
> (recursively) only by one particular module, not modules required by the
> whole program. Devel::Modlist is basically a cleaned-up version of
> 'print %INC in an END block', and Tim was looking for an alternative.
Oops, you are right, yes.
--
Reini
------------------------------
Date: 6 Apr 2001 21:33:47 GMT (Last modified)
From: Perl-Users-Request@ruby.oce.orst.edu (Perl-Users-Digest Admin)
Subject: Digest Administrivia (Last modified: 6 Apr 01)
Message-Id: <null>
Administrivia:
To submit articles to comp.lang.perl.announce, send your article to
clpa@perl.com.
Back issues are available via anonymous ftp from
ftp://cil-www.oce.orst.edu/pub/perl/old-digests.
#For other requests pertaining to the digest, send mail to
#perl-users-request@ruby.oce.orst.edu. Do not waste your time or mine
#sending perl questions to the -request address, I don't have time to
#answer them even if I did know the answer.
------------------------------
End of Perl-Users Digest V11 Issue 3681
***************************************