problem getting multiple values returned from a subroutine

I'm having problem getting multiple values returned from a subroutine.
Thanks in advance for pointers.

My codes:

#!/usr/bin/perl
use strict;
use warnings;

############################################################ ################
# Get required subroutines which need to be included. #
############################################################ ################
require "/home/sybase/scripts/pl/prod/global_dcapdsg001.pl";
require "/home/sybase/scripts/pl/prod/dataStage_dcapdsg001.pl";
my $po_file = '/ftpsite/as400/ms4/SH135.prt';
############################################################ #################
# MAIN
############################################################ #################
my ($company_header, $company_name, $period, $GLYear) = parse_title();
print "$company_header, $company_name, $period, $GLYear\n";

if ($company_header !~ /^\d{3}$/ or $GLYear !~ /^\d{4}$/ or $period !~ /^\d{1,2}$/ ){
die " comany or year or month does not look right\n" ;
}
#parse_report();
#insert_raw_to_prod();
#if ($Lawson_company eq '213'){ create_DELTA_after_load_ABSMC(); }

############################################################ #################
# SUB ROUTINE
############################################################ #################


sub parse_title{
# Determine what company, month, and year to load by parsing the report title

open IN, '<', $po_file or die "cannot open $po_file because $!\n";
my $found_C = 0;
my $found_P = 0;

while (my $line = <IN>) {
chomp;
if ($line =~ /^\*.*Company:.*\*$/){
#DataSample: * Company: 205 EDEN MEDICAL CENTER *
print "Line: $line \n";
my $company_header = substr($line,32,3);
my $company_name = substr($line,38,35);
print "Company: $company_header\nCompany Name: $company_name\n";
$found_C= 1 ;
}
if ($line =~ /^.*Inventory Items As Of Cutoff Period.*\d\d\d\d$/){
#Data Sample: Inventory Items As Of Cutoff Period 12 December 31, 2010
print "Line: $line\n";
my $period = substr($line,77,2);
print "Period: $period \n";
my $GLYear = substr($line,-5,4);
print "GLYear: $GLYear \n";
$found_P = 1;
}
#If found both company and period, no need to scan the rest of the file.
last if ($found_C == 1 and $found_P == 1);

}#end while
close IN;
#return($company_header, $company_name, $period, $GLYear);
return("$company_header", "$company_name", "$period", "$GLYear");
} #end sub

__END__

The problem is :
I expect to see: 361, WEST BAY SERVICE CENTER, 12, 2010 from the print statement above but only get , , , intead. What is wrong with my codes?

=below is a data sample


* Company: 361 SUTTER WEST BAY SERVICE CENTER *
* *
* Update Option: Y Run in Update *
* GL Posting Period: 12 Period 12 *
* GL Posting Year: C Current GL Year *
* Detail Transactions: Y Detail Transactions *
* *
* *
* *
************************************************************ *************************
^M^LSH135 Date 01/03/11 Company 361 - SUTTER WEST BAY SERVICE CENTER Page 1
Time 11:24 Received Not Invoiced Liability Report (Update)
Inventory Items As Of Cutoff Period 12 December 31, 2010
* Indicates Line Total

Process Level: 10 WEST BAY DISTRIBUTION CENTER

PO Number Received Not PO Currency Base Curre
ncy
Purch Fr Received Date Line Invoiced Qty Unit Cost Extended Amount Curr Extended A
mount
--------- ------------------------- ------ --------------------- --------------------- --- --------------- ----- ------------
-----

69149-0000 1 12.0000 15.3496 184.20 USD 18
4.20
D3A 10/27/10 361 551000 - 10810- 131601 LBL MED ADDED TO IV
Vendor: 321 MOORE WALLACE NORTH AMER INC Buyer:C25 HARRY BRADLEY



70595-0000 1 12.0000 15.3496 184.20 USD 18
4.20
D3A 12/17/10 361 551000 - 10810- 131601 LBL MED ADDED TO IV
Vendor: 321 MOORE WALLACE NORTH AMER INC Buyer:C25 HARRY BRADLEY


=end




--
To unsubscribe, e-mail: beginners-unsubscribe [at] perl.org
For additional commands, e-mail: beginners-help [at] perl.org
http://learn.perl.org/
loan tran [ Di, 01 Februar 2011 19:51 ] [ ID #2054365 ]

Re: problem getting multiple values returned from a subroutine

>>>>> "lt" == loan tran <loan_tr [at] yahoo.com> writes:

lt> I'm having problem getting multiple values returned from a subroutine.

lt> ############################################################ ################
lt> # Get required subroutines which need to be included. #
lt> ############################################################ ################
lt> require "/home/sybase/scripts/pl/prod/global_dcapdsg001.pl";
lt> require "/home/sybase/scripts/pl/prod/dataStage_dcapdsg001.pl";

don't use require and .pl files. use 'use' and .pm files. that allows
for importing subs which is easier to manage with multiple namespaces

lt> my ($company_header, $company_name, $period, $GLYear) = parse_title();

lt> ############################################################ #################
lt> # SUB ROUTINE
lt> ############################################################ #################

do you really need that block comment?

lt> sub parse_title{
lt> # Determine what company, month, and year to load by parsing the report title

lt> open IN, '<', $po_file or die "cannot open $po_file because $!\n";

you are using a global there. pass the file name as an argument. much
cleaner

lt> my $found_C = 0;
lt> my $found_P = 0;

lt> while (my $line = <IN>) {
lt> chomp;

that is chomping $_. you read into $line which isn't chomped

lt> if ($line =~ /^\*.*Company:.*\*$/){
lt> #DataSample: * Company: 205 EDEN MEDICAL CENTER *
lt> print "Line: $line \n";
lt> my $company_header = substr($line,32,3);
lt> my $company_name = substr($line,38,35);

using substr is a weak way to parse a line unless it really is fixed
fields. better to use a regex to extract all the parts you want.

lt> print "Company: $company_header\nCompany Name: $company_name\n";
lt> $found_C= 1 ;
lt> }
lt> if ($line =~ /^.*Inventory Items As Of Cutoff Period.*\d\d\d\d$/){
lt> #Data Sample: Inventory Items As Of Cutoff Period 12 December 31, 2010
lt> print "Line: $line\n";
lt> my $period = substr($line,77,2);
lt> print "Period: $period \n";
lt> my $GLYear = substr($line,-5,4);
lt> print "GLYear: $GLYear \n";
lt> $found_P = 1;
lt> }
lt> #If found both company and period, no need to scan the rest of the file.
lt> last if ($found_C == 1 and $found_P == 1);

lt> }#end while
lt> close IN;
lt> #return($company_header, $company_name, $period, $GLYear);

and why is that commented out? it looks fine.

lt> return("$company_header", "$company_name", "$period", "$GLYear");

that won't be any different with regard to returning multiple
values. but it is wrong to quote scalars when you don't need to.

lt> I expect to see: 361, WEST BAY SERVICE CENTER, 12, 2010 from the print statement above but only get , , , intead. What is wrong with my codes?

do your regexes work? do you see those debug prints in your if blocks?
if not, you exit the loop without ever setting the vars so you return
nothing useful.

uri

--
Uri Guttman ------ uri [at] stemsystems.com -------- http://www.sysarch.com --
----- Perl Code Review , Architecture, Development, Training, Support ------
--------- Gourmet Hot Cocoa Mix ---- http://bestfriendscocoa.com ---------

--
To unsubscribe, e-mail: beginners-unsubscribe [at] perl.org
For additional commands, e-mail: beginners-help [at] perl.org
http://learn.perl.org/
Uri Guttman [ Di, 01 Februar 2011 19:59 ] [ ID #2054366 ]

Re: problem getting multiple values returned from a subroutine

On 01/02/2011 18:51, loan tran wrote:
>
> I'm having problem getting multiple values returned from a subroutine.
> Thanks in advance for pointers.
>
> My codes:
>
<snip>
>
>
> sub parse_title{
> # Determine what company, month, and year to load by parsing the report title
>
> open IN, '<', $po_file or die "cannot open $po_file because $!\n";
> my $found_C = 0;
> my $found_P = 0;

You also need to declare here

my ($company_header, $company_name, $period, $GLYear);

as at present the variables are restricted to the block where they are
declared and calculated. By the time the return statement comes they are
out of scope and their values are lost.

> while (my $line =<IN>) {
> chomp;
> if ($line =~ /^\*.*Company:.*\*$/){
> #DataSample: * Company: 205 EDEN MEDICAL CENTER *
> print "Line: $line \n";
> my $company_header = substr($line,32,3);
> my $company_name = substr($line,38,35);

Just

$company_header = substr($line,32,3);
$company_name = substr($line,38,35);

is all that's needed here.

> print "Company: $company_header\nCompany Name: $company_name\n";
> $found_C= 1 ;
> }
> if ($line =~ /^.*Inventory Items As Of Cutoff Period.*\d\d\d\d$/){
> #Data Sample: Inventory Items As Of Cutoff Period 12 December 31, 2010
> print "Line: $line\n";
> my $period = substr($line,77,2);
> print "Period: $period \n";
> my $GLYear = substr($line,-5,4);
> print "GLYear: $GLYear \n";

Likewise, this should be

$period = substr($line,77,2);
print "Period: $period \n";
$GLYear = substr($line,-5,4);
print "GLYear: $GLYear \n";


> $found_P = 1;
> }
> #If found both company and period, no need to scan the rest of the file.
> last if ($found_C == 1 and $found_P == 1);
>
> }#end while
> close IN;
> #return($company_header, $company_name, $period, $GLYear);
> return("$company_header", "$company_name", "$period", "$GLYear");
> } #end sub
>
> __END__
>
> The problem is :
> I expect to see: 361, WEST BAY SERVICE CENTER, 12, 2010 from the
> print statement above but only get , , , intead. What is wrong with
> my codes?

I hope this helps you.

Rob

--
To unsubscribe, e-mail: beginners-unsubscribe [at] perl.org
For additional commands, e-mail: beginners-help [at] perl.org
http://learn.perl.org/
Rob Dixon [ Di, 01 Februar 2011 20:07 ] [ ID #2054367 ]

Re: problem getting multiple values returned from a subroutine

--- On Tue, 2/1/11, Uri Guttman <uri [at] StemSystems.com> wrote:

> From: Uri Guttman <uri [at] StemSystems.com>
> Subject: Re: problem getting multiple values returned from a subroutine
> To: "loan tran" <loan_tr [at] yahoo.com>
> Cc: beginners [at] perl.org
> Date: Tuesday, February 1, 2011, 10:59 AM
> >>>>> "lt" =3D=3D loan
> tran <loan_tr [at] yahoo.com>
> writes:
>
> =A0 lt> I'm having problem getting multiple values
> returned from a subroutine.
>
> =A0 lt>
> ############################################################ #############=
###
> =A0 lt> # Get required subroutines which need to be
> included.=A0 =A0 =A0 =A0 =A0 =A0 =A0
> =A0 =A0 =A0 =A0 #
> =A0 lt>
> ############################################################ #############=
###
> =A0 lt> require
> "/home/sybase/scripts/pl/prod/global_dcapdsg001.pl";
> =A0 lt> require
> "/home/sybase/scripts/pl/prod/dataStage_dcapdsg001.pl";
>
> don't use require and .pl files. use 'use' and .pm files.
> that allows
> for importing subs which is easier to manage with multiple
> namespaces
>
> =A0 lt> my ($company_header, $company_name, $period,
> $GLYear) =3D parse_title();
>
> =A0 lt>
> ############################################################ #############=
####
> =A0 lt> #=A0 SUB ROUTINE
> =A0 lt>
> ############################################################ #############=
####
>
> do you really need that block comment?
>
> =A0 lt> sub parse_title{
> =A0 lt>=A0 =A0 # Determine what company, month,
> and=A0 year to load by parsing the report title
>
> =A0 lt>=A0 =A0 open IN, '<', $po_file or die
> "cannot open $po_file because $!\n";
>
> you are using a global there. pass the file name as an
> argument. much
> cleaner
>
> =A0 lt>=A0 =A0 my $found_C
> =3D=A0=A0=A00;
> =A0 lt>=A0 =A0 my $found_P
> =3D=A0=A0=A00;
>
> =A0 lt>=A0 =A0 while (my $line =3D <IN>) {
> =A0 lt>=A0 =A0 =A0 chomp;
>
> that is chomping $_. you read into $line which isn't
> chomped
>
> =A0 lt>=A0 =A0 =A0 if ($line =3D~
> /^\*.*Company:.*\*$/){
> =A0 lt>=A0 =A0 =A0 #DataSample: *=A0
> =A0 Company:=A0 205=A0=A0=A0EDEN MEDICAL
> CENTER *
> =A0 lt>=A0 =A0 =A0 =A0 print "Line: $line
> \n";
> =A0 lt>=A0 =A0 =A0 =A0 my $company_header
> =3D substr($line,32,3);
> =A0 lt>=A0 =A0 =A0 =A0 my $company_name =3D
> substr($line,38,35);
>
> using substr is a weak way to parse a line unless it really
> is fixed
> fields. better to use a regex to extract all the parts you
> want.
>
> =A0 lt>=A0 =A0 =A0 =A0 print "Company:
> $company_header\nCompany Name: $company_name\n";
> =A0 lt>=A0 =A0 =A0 =A0 $found_C=3D 1 ;
> =A0 lt>=A0 =A0 =A0 }
> =A0 lt>=A0 =A0=A0=A0if ($line =3D~
> /^.*Inventory Items As Of Cutoff Period.*\d\d\d\d$/){
> =A0 lt>=A0 =A0 =A0 #Data Sample:=A0
> Inventory Items As Of Cutoff Period 12=A0 December 31,
> 2010
> =A0 lt>=A0 =A0 =A0 =A0 print "Line:
> $line\n";
> =A0 lt>=A0 =A0 =A0 =A0 my $period =3D
> substr($line,77,2);
> =A0 lt>=A0 =A0 =A0 =A0 print "Period:
> $period \n";
> =A0 lt>=A0 =A0 =A0 =A0 my $GLYear =3D
> substr($line,-5,4);
> =A0 lt>=A0 =A0 =A0 =A0 print "GLYear:
> $GLYear \n";
> =A0 lt>=A0 =A0 =A0 =A0 $found_P =3D 1;
> =A0 lt>=A0 =A0=A0=A0}
> =A0 lt>=A0 =A0=A0=A0#If found both
> company and period, no need to scan the rest of the file.
> =A0 lt>=A0 =A0=A0=A0last if ($found_C =3D=3D
> 1 and $found_P =3D=3D 1);
>
> =A0 lt>=A0 =A0 }#end while
> =A0 lt>=A0 =A0 close IN;
> =A0 lt>=A0 =A0 #return($company_header,
> $company_name, $period, $GLYear);
>
> and why is that commented out? it looks fine.
>
> =A0 lt>=A0 =A0 return("$company_header",
> "$company_name", "$period", "$GLYear");
>
> that won't be any different with regard to returning
> multiple
> values. but it is wrong to quote scalars when you don't
> need to.
>
> =A0 lt> I expect to see: 361, WEST BAY SERVICE
> CENTER, 12, 2010 from the print statement above but only get
> , , , intead. What is wrong with my codes?
>
> do your regexes work? do you see those debug prints in your
> if blocks?

Yes they do. Below is the program output:

Line: * Company: 361 SUTTER WEST BAY SERVICE CENTER =
*

Company: 361
Company Name: SUTTER WEST BAY SERVICE CENTER
Line: Inventory Items As Of Cutoff=
Period 12 December 31, 2010

Period: 12
GLYear: 2010
, , ,
comany or year or month does not look right



> if not, you exit the loop without ever setting the vars so
> you return
> nothing useful.
>
> uri
>
> --
> Uri Guttman=A0 ------=A0 uri [at] stemsystems.com=A0
> --------=A0 http://www.sysarch.com --
> -----=A0 Perl Code Review , Architecture, Development,
> Training, Support ------
> ---------=A0 Gourmet Hot Cocoa Mix=A0 ----=A0 http://bestfriendscocoa.com=
---------
> =0A=0A=0A

--
To unsubscribe, e-mail: beginners-unsubscribe [at] perl.org
For additional commands, e-mail: beginners-help [at] perl.org
http://learn.perl.org/
loan tran [ Di, 01 Februar 2011 20:14 ] [ ID #2054368 ]

Re: problem getting multiple values returned from a subroutine

At 10:51 -0800 01/02/2011, loan tran wrote:


>I'm having problem getting multiple values returned from a subroutine.
>Thanks in advance for pointers.

If you want help with a problem you should present the problem as
simply as possible in a runnable form and not require your helpers to
wade through acreas of irrelevant stuff. If you do that, the chances
are you'll be able to solve the problem yourself.

You are even more unlikely to get help when people who reply to your
post quote a hundred lines in order to write one line of their own
stuff. Such ignorance of list etiquette seems to be a common feature
of this list.

As someone has already pointed out, if you declare a (my) variable in
a while loop, that variable goes out of scope at the end of the loop.
The errors you got when you failed to run your script should have
made this obvious to you. You 'use strict' at the beginning of the
script in order to catch these errors, and you are then intended to
read the errors.

At the end of the subroutine return a scalar, in this case a
reference to the array, and dereference this in the main routine as
shown below.

#!/usr/local/bin/perl
use strict;
my $array_ref = &PARSE_TITLE();
my [at] array = [at] $array_ref;
print join ", ", [at] array;

sub PARSE_TITLE{
my ($company_header, $company_name, $period, $GLYear);
my $n;
while ($n < 1) {
($company_header, $company_name, $period, $GLYear) =
qw(CH CN P GLY);
$n++;
}
my [at] array = ($company_header, $company_name, $period, $GLYear);
return \ [at] array;
}

#JD

--
To unsubscribe, e-mail: beginners-unsubscribe [at] perl.org
For additional commands, e-mail: beginners-help [at] perl.org
http://learn.perl.org/
John Delacour [ Mi, 02 Februar 2011 10:34 ] [ ID #2054447 ]

Re: problem getting multiple values returned from a subroutine

Thank you Rob, Uri and John for your replies.
I've learned great things from them.
Thank to your pointers, my script is working properly.

--- On Wed, 2/2/11, John Delacour <johndelacour [at] gmail.com> wrote:

> From: John Delacour <johndelacour [at] gmail.com>
> Subject: Re: problem getting multiple values returned from a subroutine
> To: "loan tran" <loan_tr [at] yahoo.com>, beginners [at] perl.org
> Date: Wednesday, February 2, 2011, 1:34 AM
> At 10:51 -0800 01/02/2011, loan tran
> wrote:
>
>
> > I'm having problem getting multiple values returned
> from a subroutine.
> > Thanks in advance for pointers.
>
> If you want help with a problem you should present the
> problem as simply as possible in a runnable form and not
> require your helpers to wade through acreas of irrelevant
> stuff.=A0 If you do that, the chances are you'll be able
> to solve the problem yourself.
>
> You are even more unlikely to get help when people who
> reply to your post quote a hundred lines in order to write
> one line of their own stuff.=A0 Such ignorance of list
> etiquette seems to be a common feature of this list.
>
> As someone has already pointed out, if you declare a (my)
> variable in a while loop, that variable goes out of scope at
> the end of the loop. The errors you got when you failed to
> run your script should have made this obvious to you.=A0
> You 'use strict' at the beginning of the script in order to
> catch these errors, and you are then intended to read the
> errors.
>
> At the end of the subroutine return a scalar, in this case
> a reference to the array, and dereference this in the main
> routine as shown below.
>
> #!/usr/local/bin/perl
> use strict;
> my $array_ref =3D &PARSE_TITLE();
> my [at] array =3D [at] $array_ref;
> print join ", ", [at] array;
>
> sub PARSE_TITLE{
> =A0 my ($company_header, $company_name, $period,
> $GLYear);
> =A0 my $n;
> =A0 while ($n < 1) {
> =A0 =A0 ($company_header, $company_name, $period,
> $GLYear) =3D
> =A0 =A0 =A0 qw(CH CN P GLY);
> =A0 =A0 $n++;
> =A0 }
> =A0 my [at] array =3D ($company_header, $company_name,
> $period, $GLYear);
> =A0 return \ [at] array;
> }
>
> #JD
>
> -- To unsubscribe, e-mail: beginners-unsubscribe [at] perl.org
> For additional commands, e-mail: beginners-help [at] perl.org
> http://learn.perl.org/
>
>
> =0A=0A=0A

--
To unsubscribe, e-mail: beginners-unsubscribe [at] perl.org
For additional commands, e-mail: beginners-help [at] perl.org
http://learn.perl.org/
loan tran [ Mi, 02 Februar 2011 17:50 ] [ ID #2054449 ]
Perl » gmane.comp.lang.perl.beginners » problem getting multiple values returned from a subroutine

Vorheriges Thema: how do make certain that no input (keyboard + mouse paste) is outsideof 7-bit ASCII in a perl script
Nächstes Thema: Need help in Expect Module