1753796 Members
7129 Online
108799 Solutions
New Discussion юеВ

Re: perl sub routines

 
SOLVED
Go to solution
steven Burgess_2
Honored Contributor

perl sub routines

Hi Everyone,

I had a thread open the other day as I had a problem passing variables to a sub routine. Whilst this has been resolved, I now have a problem where I need to pass 3 variables, with the 3rd being a line of data. Such as

default 10.100.2.248 UG 0 en0 - -

I get the line by parsing a file and creating a n variable with the following

s/(#.*|^MACHINE.*$|^.*CONFIG.* $type)//g;

chomp;

$data = $_;

I have other variables that have been initialised

I call my subroutine

&insert_record(($hostid, $date, $data));

The sub routine looks like the following

my (@record)=(@_);

my $stc;

$stc = $dbh->prepare ("INSERT INTO tblConfig (hostid,date,config) VALUES(?,?,?)");

$stc->execute ("$record[0],$record[1],$record[2]");

$stc->finish ();
}


However, when I print the value of @record. I only get my first 2 values and not my line of data.

I am currently looking at nested data structures, to see if I can do it that way

Any help appreciated

TIA

Steve
take your time and think things through
4 REPLIES 4
James R. Ferguson
Acclaimed Contributor
Solution

Re: perl sub routines

Hi Steve:

Run this, and ask yourself what is returned by the substitution:

# perl -wnle 's/(#.*|^MACHINE.*$|^.*CONFIG.* $type)//g;chomp;print "[ $1 ] [$_] \n"'

That is, enter things like:

MACHINE123
nomore
MACHINE

...and observe where the captured/non-captured output is returned...

Regards!

...JRF...
H.Merijn Brand (procura
Honored Contributor

Re: perl sub routines

I read that post after you got the `fix'

First of all, some things are done overly complicated, as context matters in perl:

my (@list) = (@other_list);

is only adding line noise, as both sides are list context

Using leading & for function calls is severely discouraged, as it has unwanted side effects. This still exists for some backward compatability with perl4 and the possibility to deep-optimize sub calls, something you will probably not be doing in the next 5 years :)

The execute statement is wrong, as you pass all arguments to it as one single string

--8<---
sub db_insert
{
my ($hostid, $date, $config) = @_;

my $stc = $dbh->prepare ("INSERT INTO tblConfig (hostid, date, config) VALUES (?, ?, ?)");
$stc->execute ($hostid, $date, $config);
$stc->finish ();
} # db_insert

Would be the right thing to do, but ...

1. The finish is optional. (I also always use it for clarity, but still)
2. The prepare is done *inside* the routine, causing it to be prepared over and over and over again. That is bad!

BTW, chomp and assign can go in one statement, which would make your simplified flow look like

---8<---
use strict;
use warnings;
use DBI;

my $dbh = DBI->connect (....);
my $sti = $dbh->prepare ("INSERT INTO tblConfig (hostid, date, config) VALUES (?, ?, ?)");

sub db_insert
{
my ($hostid, $date, $config) = @_;

$sti->execute ($hostid, $date, $config);
} # db_insert

my $hostid = 12345;
my $date = 20060907;

while (<>) {
s/(#.*|^MACHINE.*$|^.*CONFIG.* $type)//g;
chomp ($data = $_);
db_insert ($hostid, $date, $data);
}

$sti->finish ();
$dbh->commit;
-->8---

And, as db_insert as sub now only has one line, why not move that line to inside the while loop and get rid of the sub.

Enjoy, Have FUN! H.Merijn
Enjoy, Have FUN! H.Merijn
H.Merijn Brand (procura
Honored Contributor

Re: perl sub routines

I read that post after you got the `fix'

First of all, some things are done overly complicated, as context matters in perl:

my (@list) = (@other_list);

is only adding line noise, as both sides are list context

Using leading & for function calls is severely discouraged, as it has unwanted side effects. This still exists for some backward compatability with perl4 and the possibility to deep-optimize sub calls, something you will probably not be doing in the next 5 years :)

The execute statement is wrong, as you pass all arguments to it as one single string

--8<---
sub db_insert
{
my ($hostid, $date, $config) = @_;

my $stc = $dbh->prepare ("INSERT INTO tblConfig (hostid, date, config) VALUES (?, ?, ?)");
$stc->execute ($hostid, $date, $config);
$stc->finish ();
} # db_insert

Would be the right thing to do, but ...

1. The finish is optional. (I also always use it for clarity, but still)
2. The prepare is done *inside* the routine, causing it to be prepared over and over and over again. That is bad!

BTW, chomp and assign can go in one statement, which would make your simplified flow look like

---8<---
use strict;
use warnings;
use DBI;

my $dbh = DBI->connect (....);
my $sti = $dbh->prepare ("INSERT INTO tblConfig (hostid, date, config) VALUES (?, ?, ?)");

sub db_insert
{
my ($hostid, $date, $config) = @_;

$sti->execute ($hostid, $date, $config);
} # db_insert

my $hostid = 12345;
my $date = 20060907;

while (<>) {
s/(#.*|^MACHINE.*$|^.*CONFIG.* $type)//g;
chomp ($data = $_);
db_insert ($hostid, $date, $data);
}

$sti->finish ();
$dbh->commit;
-->8---

And, as db_insert as sub now only has one line, why not move that line to inside the while loop and get rid of the sub.

Enjoy, Have FUN! H.Merijn
Enjoy, Have FUN! H.Merijn
steven Burgess_2
Honored Contributor

Re: perl sub routines

Hi Guys

Thanks for the replies. Reading over the responses highlights that I need to take perl from the beginning and not try to dive in without fully understanding what is being done and why.

I am trying to learn a whole lot in a relatively short space of time. I need to get my Msc assignment handed in by monday and have bitten off more than I can chew !!

Thanks again

Probably more to come

Steve
take your time and think things through