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

Hello all, I'm trying to pass arguments in a subroutine. The first argument is passed successfully but the second doesn't work. Here is the code I wrote. any help would be greatly appreciated!

EXTRACT_FIRST_COLUMN(my $TEMPCSV = 'C:\temp\part1.csv', my $TEMPTXT = +'TEMP_AM.txt', my $FINALCSV = 'C:\temp\OUT.CSV'); EXTRACT_FIRST_COLUMN(my $TEMPCSV = 'C:\temp\part2.csv', my $TEMPTXT = +'TEMP_CA.txt', my $FINALCSV = 'C:\temp\OUT2.CSV'); sub EXTRACT_FIRST_COLUMN { my $csv = Text::CSV->new(); open (FILE,">","$TEMPTXT"); open (CSV, "<", $TEMPCSV); while (CSV>) { if $csv->parse($_)) { my @column = $csv-> fields(); print FILE "$column[0]\n"; } else { my #err = $csv->error_input; print "ERROR: Failed to parse line: $err"; } } close (FILE); open (OUTPUT2,">","$FINALCSV); my $file = $TEMPTXT; open (my $FH, "<", $file) or die $!; while <$fh>) { my $uri = $_; $uri =~ s/\s+//g; my ($name, $aliases, $addrtype, $length, @addrs) = gethostbyname $uri; my ($w,$x,$y,$z) = unpack('C4',$addr[0]); print OUTPUT2 "$w.$x.$y.$z\n"; } close (OUTPUT2); } sub EXTRACT_FIRST_COLUMN();

Replies are listed 'Best First'.
Re: Passing arguments in a subroutine
by davido (Cardinal) on Apr 12, 2015 at 05:43 UTC

    This isn't how you pass parameters in Perl. Parameters that are passed into subroutines are accessed within the subroutine through the @_ special array:

    sub foo { my( $bar, $baz ) = @_; print "\$bar contains <<$bar>>\n"; print "\$baz contains <<$baz>>\n"; } foo( "Hello,", "world!" );

    Please refer to perlintro#Writing-subroutines for more insight. And for almost everything you ever wanted to know about passing parameters into subroutines, there's perlsub.

    There are also a few syntax and misspelled variable errors:

    • while (CSV>) ...: Missing < from the <> operator.
    • if $csv->parse($_)) ...: Missing ( from if() condition.
    • open (OUTPUT2,">","$FINALCSV);: Missing closing quote from "$FINALCSV
    • while <$fh>) ...: Missing opening paren from while() construct.
    • my ($name, ......, @addrs)..., followed by unpack('C4', $addr[0]);: Misspelling of variable name. use strict; would have caught that under the 'vars' rule of strictures.

    In the future, please post actual code, copied and pasted, and make sure your code is compliant with use strict;, since strict will help you catch errors yourself without the intervention of the Monastery.


    Dave

Re: Passing arguments in a subroutine
by AnomalousMonk (Archbishop) on Apr 12, 2015 at 06:28 UTC

    Note that, interestingly enough, the way you are invoking your function will actually pass arguments to the function and, simultaneously, create (masking) lexical variables within the scope of the function invocation, although why you would want to do this is beyond me (unless you're trying to drive your maintainer absolutely bonkers). Where did you come up with this approach?

    c:\@Work\Perl\monks>perl -wMstrict -MData::Dump=pp -le "sub S { print qq{in S: args }, pp \@_; } ;; S(my $x = 'foo', my $y = 'bar'); print qq{outside S: \$x == $x, \$y == $y}; ;; sub S (); " Prototype mismatch: sub main::S: none vs () at -e line 1. in S: args ["foo", "bar"] outside S: $x == foo, $y == bar

    Update: Changed code example to include effect of late, prototyped subroutine declaration.

    Update 2: Oh, and BTW: Don't use Prototypes unless you're absolutely sure what they do. I.e., don't use prototypes. See Far More than Everything You've Ever Wanted to Know about Prototypes in Perl -- by Tom Christiansen.


    Give a man a fish:  <%-(-(-(-<

Re: Passing arguments in a subroutine
by vinoth.ree (Monsignor) on Apr 12, 2015 at 06:39 UTC
    use strict; use warnings; use Text::CSV; EXTRACT_FIRST_COLUMN(my $TEMPCSV = 'C:\temp\part1.csv', my $TEMPTXT = +'TEMP_AM.txt', my $FINALCSV = 'C:\temp\OUT.CSV'); EXTRACT_FIRST_COLUMN(my $TEMPCSV = 'C:\temp\part2.csv', my $TEMPTXT = +'TEMP_CA.txt', my $FINALCSV = 'C:\temp\OUT2.CSV'); sub EXTRACT_FIRST_COLUMN { my $csv = Text::CSV->new(); open (FILE,">","$TEMPTXT"); open (CSV, "<", $TEMPCSV); while (<CSV>) { if ($csv->parse($_)) { my @column = $csv-> fields(); print FILE "$column[0]\n"; } else { #my err = $csv->error_input; print "ERROR: Failed to parse line: $err"; } } close (FILE); open (OUTPUT2,">","$FINALCSV"); my $file = $TEMPTXT; open (my $FH, "<", $file) or die $!; while (<$fh>) { my $uri = $_; $uri =~ s/\s+//g; my ($name, $aliases, $addrtype, $length, @addrs) = get +hostbyname $uri; my ($w,$x,$y,$z) = unpack('C4',$addr[0]); print OUTPUT2 "$w.$x.$y.$z\n"; } close (OUTPUT2); } sub EXTRACT_FIRST_COLUMN();
    Here is the use strict; complaint
    "my" variable $TEMPCSV masks earlier declaration in same scope at sub.pl line 9.
    "my" variable $TEMPTXT masks earlier declaration in same scope at sub.pl line 9.
    "my" variable $FINALCSV masks earlier declaration in same scope at sub.pl line 9.
    Global symbol "$err" requires explicit package name at sub.pl line 21.
    Global symbol "$fh" requires explicit package name at sub.pl line 29.
    Global symbol "@addr" requires explicit package name at sub.pl line 33.
    Execution of sub.pl aborted due to compilation errors.
    

    All is well. I learn by answering your questions...
      ... use strict; complaint ...

      More like a death rattle, I would say.


      Give a man a fish:  <%-(-(-(-<