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

Ok let say i have 4 sub routines like this:

my $dataFile = $ARGV[0]; tear_down($dataFile); sub tear_down{ my ($dataFile) = @_; open my $file, '<', $dataFile || die "$!"; my count = 3; for ( my $i = 1 ; $i <= $count ; $i++ ) { seek to bytes in file; read x bytes in file; } } sub parse_file_1{ my ($file) = @_; ...do stuff.... } sub parse_file_2{ my ($file) = @_; ...do stuff... } sub parse_file_3{ my ($file) = @_; ...do stuff... }
just say for example the first subroutine extracted 3 parts of a file. how would i pass those to the other three subroutines? Do i just put sub name like sub parse_file_1($var) and pass it like that? or maybe i am missing something totally lol. i have been able to use subs in the past but i would like to understand the logic a little better. any insight would be wonderful
  • Comment on using sub routines and solving an issue i have with passing variables
  • Download Code

Replies are listed 'Best First'.
Re: using sub routines and solving an issue i have with passing variables
by GrandFather (Saint) on Sep 30, 2014 at 20:40 UTC

    Sounds like the sort of place I'd use really light weight objects:

    use strict; use warnings; my $fileStr = <<FILE; =wibble The wibble section =plonk the plonk section =foo the foo section FILE open my $fin, '<', \$fileStr; my $obj = bless {fin => $fin}; $obj->parseStructure($fin); $obj->parseBlock('foo'); $obj->parseBlock('wibble'); $obj->parseBlock('bar'); sub parseStructure { my ($self) = @_; my $currBlock; while (1) { my $start = tell $fin; my $line = <$fin>; next if defined $line && $line !~ /^=(\w+)/; $self->{blocks}{$currBlock}{length} = $start - $self->{blocks}{$currBlock}{start} if defined $currBlock; $currBlock = $1; $self->{blocks}{$currBlock}{start} = $start if defined $line; last if eof $fin; } } sub parseBlock { my ($self, $blockType) = @_; if (!exists $self->{blocks}{$blockType}) { print "No '$blockType' blocks in file\n"; return; } seek $self->{fin}, $self->{blocks}{$blockType}{start}, 0; read $self->{fin}, my $block, $self->{blocks}{$blockType}{length}; print "$blockType:\n$block\n"; }

    Prints:

    foo: =foo the foo section wibble: =wibble The wibble section No 'bar' blocks in file
    Perl is the programming world's equivalent of English
      i just figured out something else i didnt know. you can name an array on the fly say for instance if you read a files name and want to make the filename the name of the array... take this into code consideration (which most of you probably already know this) i know this is off topic, but is there an easier method of labeling arrays?

      my $string = "awesome_array"; my $other_string = "another_awesome_array"; push (@$string, 1, 2, 3, 4, 5 ); foreach my $element(@awesome_array){ print "$element\n"; push (@$other_string, $element) } print @another_awesome_array;
      This rigth here is something that will help me alot on the script i am working on right now actually :) glad i figured this little tid bit out.

        Try that code with strictures (which you should always use: use strict; use warnings; - see The strictures, according to Seuss). It works without strictures because of some magic. That magic can make it very hard to write correct code and find errors when things go wrong.

        You can achieve similar results by replacing the magic with a hash:

        use strict; use warnings; my %arrays; push @{$arrays{awesome_array}}, 1 .. 5; for my $element(@{$arrays{awesome_array}}){ print "$element\n"; push @{$arrays{another_awesome_array}}, $element; } for my $arrayName (keys %arrays) { print "$arrayName: @{$arrays{$arrayName}}\n" }

        Prints:

        1 2 3 4 5 awesome_array: 1 2 3 4 5 another_awesome_array: 1 2 3 4 5
        Perl is the programming world's equivalent of English
      i do alot of files inside of other files work. so i need to be able to maybe disassemble the file in one sub, send each file to its own sub for further examining-ing. thanks for taking yoru time and writing up something, every bit helps :)
Re: using sub routines and solving an issue i have with passing variables
by GotToBTru (Prior) on Sep 30, 2014 at 19:53 UTC

    I think we need more information. You already know how to call a subroutine with a parameter, you do so in the second line of your program. What exactly is it you need help with?

    1 Peter 4:10
      actually if the first sub pulls out a section of a file and names it "$data" how would i pass $data to all three subs?
      sub tear_down{ my ($dataFile) = @_; open my $file, '<', $dataFile || die "$!"; my count = 3; for ( my $i = 1 ; $i <= $count ; $i++ ) { seek to bytes in file; read x bytes into $data ; parse_file_1($data) ###### but how would i loop so first $data goes to parse_file_1, seco +nd $data would go to parse_file_2 ect? ###### would i have to send it to another sub that could count each o +ne? and if count = 1 send to parse_file_1 ###### and if count=2 then send to parse_file_2 ect ect? cz nested lo +ops give me unexpected results alot of times } }
      im just trying to get my head around it is all :)
      EDIT: DERP i think i figured it out. cz the counter in the first sub could delegate which sub it goes to i am pretty sure. and then there still would only be if statements and not nested loops. or i could also add checks in each sub for the specific data coming to it. and just set it up so all data gets passed to all three subs for each loop. but that sounds like it would be a bad thing. i think if $count = x statements would be better
Re: using sub routines and solving an issue i have with passing variables
by Anonymous Monk on Oct 01, 2014 at 00:41 UTC

    Could what you are asking be accomplished by passing in your data structure into each of the subroutines as an additional parameter? E.g.

    sub parse1 { my ($filehandle,$data) = @_; # read from $filehandle and add to $data } sub parse2 { my ($filehandle,$data) = @_; # read from $filehandle and add to $data } # etc.

    Or perhaps better, each subroutine could return the piece of data it parsed from the file?

    my %data; $data{piece1} = parse1($fh); $data{piece2} = parse2($fh); sub parse1 { my ($filehandle) = @_; # read from $filehandle return $data; } sub parse2 { my ($filehandle) = @_; # read from $filehandle return $data; }

    But I think I may be misunderstanding the question, in which case it would help if you could explain some more and provide a small, working, self-contained example that demonstrates the question, along with some sample input and the expected output. How do I post a question effectively?

      well there are still afew things in which i am not to sure about. one of which is return function. does that return the data outside of the sub? i have had alot of spare time recently and i wanna learn all i can, i dont want to feel like an idiot for asking, but i read thru some of the perldocs and dont understand alot of the talk about it as i am better with written examples and a little explanation. let me better prepare my question. or should i say questionS <.<