0

As a part of my course work I have been learning perl programming language for the first time in last the few weeks. I have been writing small functions and making function calls. I have written a function for string matching.

use strict;
use warnings;

sub find_multi_string {
    my ($file, @strings) = @_; 
    my $fh;
    open ($fh, "<$file");
    #store the whole file in an array
    my @array = <$fh>;

    for my $string (@strings) {
        if (grep /$string/, @array) {
            next;
        } else {
            die "Cannot find $string in $file";
        }   
    }   

    return 1;
}

find_multi_string('file name', 'string1','string2','string3','string4','string 5');

In the above script I'm passing the arguments in the function call. The script works. But I'd like to know if there is way to specify the file name and string1... string n in an array in the program itself and just make the function call.

find_multi_string();
2
  • Why? What are you trying to achieve? Commented Jul 14, 2014 at 21:56
  • Use autodie! Commented Jul 15, 2014 at 15:06

2 Answers 2

3

That would be a mistake, always pass parameters and return values to your subroutines.

What you're describing is essentially using subroutines solely to subdivide and document your code. If you were to do that, it would better to just remove the subroutine entirely and include a comment before the section of code.

Overall, your code looks good as is. You probably will want to use quotemeta though, and your logic can be simplified a little:

use strict;
use warnings;
use autodie;

sub find_multi_string {
    my ($file, @strings) = @_; 

    # Load the file
    my $data = do {
        open my $fh, "<", $file;
        local $/;
        <$fh>
    };

    for my $string (@strings) {
        if ($data !~ /\Q$string/) {
            die "Cannot find $string in $file";
        }   
    }   

    return 1;
}

find_multi_string('file name', 'string1','string2','string3','string4','string 5');
Sign up to request clarification or add additional context in comments.

1 Comment

Tranforming bare string into regexp with \Q is a waste of resources. Just use the index function because that will be much more efficient.
0

A few improvements of your original code:

  • use autodie
  • use 3-args open
  • as you want to check anywhere in the file, just load the file as a single string
  • if the matching string are just text without metacharacters from regexp, just use the index function

Your question is about passing the function arguments from your program. I suspect that you are looking for @ARGV. See perlvar.

Here is the modified code:

use strict;
use warnings;
use autodie;

sub find_multi_string {
    my ($file, @strings) = @_; 

    my $content = do {
        open my $fh, '<', $file;
        local $/;
        <$fh>
    };


    foreach (@strings) {
        die "Cannot find $string in $file" unless index($content, $_) >= 0;
    }   

    return 1;
}

find_multi_string(@ARGV);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.