Aditya Acharya
Aditya Acharya

Reputation: 51

How to create own module for reuse in Perl?

I wish to create my own module and I want to use that module name for further use. The main concept is: Create a module which should contain subroutines for line count, word-count and character count, and in main program I should use that module and I should read the file and the output should show me total number of lines, total number of words and total number of characters in that file.

package Countsample;

use strict;
use base"Exporter";
use 5.010;

our @EXPORT=qw/line_count/;

sub line_count
{my $line=@_;
return $line;
}

1;

This above doc is saved in Count.pm.

#!usr/bin/perl

use Countsample;
open FH,"text1.txt";
line_count();
print"$line\n";

The above code is saved in Count1.pl format.

I think this much information is enough to create, if you need any further information then let me know.

Kindly help me to create complete this task.

Upvotes: 1

Views: 173

Answers (2)

nlu
nlu

Reputation: 1963

Let's start with the module. It was already mentioned, that it is common practice to name the file as the package it contains.

And there is a reason for this: using use with a name builds on the expectation that there will be a file somewhere in the path list (@INC) for modules by that name containing a matching namespace declaration (package whatever). This connection makes possible, what Exporter does in the first place.

http://perldoc.perl.org/Exporter.html

A more indepth but still succinct explanation of this can be found here http://www.perlmonks.org/?node_id=102347

So the file would be named Countsample.pm:

package Countsample;

use strict;
use warnings;

use base "Exporter";
use 5.010;

our @EXPORT=qw/line_count/;

sub line_count
{
    my ($fd) = (@_);

    my $lines = 0;
    while (<$fd>) {
          $lines++
    }
    return $lines;
}

1;

I added use strict and use warnings to be notified about errors.

Then I changed the assignment of the arguments; the arguments in @_ are a list, so I assign those to a list on the left side (see the parentheses around $fd). You could use

my $fd = shift;

alternatively.

I chose to pass an open filehandle as an argument here, then count the lines, simply by reading the file linewise and returning the number of lines.

There are many ways to get the number of lines out of a file, just as a reference: http://www.perlmonks.org/?node_id=538824

The main program then looks like this:

#!/usr/bin/perl

use v5.14;
use strict;
use warnings;
use Countsample;

open (my $fd, "<", "text1.txt");
say line_count($fd);
close($fd);

See http://perldoc.perl.org/functions/open.html for the ways to open a file that are available and preferable.

Upvotes: 2

Dave Cross
Dave Cross

Reputation: 69224

You really need to work on your question asking. You're not giving us enough to go on. You need to tell us:

  • Exactly what you want to do
  • Exactly what you have done
  • Exactly what expected behaviour you are seeing (including any error messages)

Let's step through getting past some of your errors.

Firstly, when I ran your program, I got this.

$ ./Count1.pl
bash: ./Count1.pl: usr/bin/perl: bad interpreter: No such file or directory

Ok, so that's just a stupid typo. But because you haven't explained what problems you are getting, we don't know if that's the problem you're seeing or whether you've introduced the typo when posting your question.

But it's easy to fix. The shebang line needs to be #!/usr/bin/perl. I'm pretty sure you had exactly the same typo in your last question!

Now what happens when I run your code.

$ ./Count1.pl
Can't locate Countsample.pm in @INC (you may need to install the Countsample module) (@INC contains: ...)

This is because your package doesn't have the same name as your module file. Why would you do that? It just complicates your life.

Ok, so let's fix the use statement so it's looking for the right thing - use Count.

Now I get a different error.

$ ./Count1.pl
Undefined subroutine &main::line_count called at ./Count1.pl line 5.

That's going to be a little harder to track down. So to make my life easier I'll turn on use strict and use warnings in both of the files.

I now get this:

$ ./Count1.pl
Global symbol "$line" requires explicit package name at ./Count1.pl line 9.
Execution of ./Count1.pl aborted due to compilation errors.

That means I'll need to declare the variable $line at some point so I'll add my $line just after the use Count line.

And now I get this:

$ ./Count1.pl
Name "main::FH" used only once: possible typo at ./Count1.pl line 8.
Undefined subroutine &main::line_count called at ./Count1.pl line 9.

At which point, I'm afraid, I get bored of digging. Had you presented us with this version of the code, then I might have had some energy left to investigate from here. But because I've spent ten minutes finding silly typos and fixing pointless bugs, I've lost all enthusiasm.

It's important to realise that the people here are all volunteers. We're happy to help you solve your problems, but you need to do some of the work yourself. You need to ensure that we don't waste time fixing obvious things that you could have found yourself. And you need to be a lot clearer than you have been so far when explaining what the problem is.

Here's the version of you code that I got to. Perhaps someone else will have the enthusiasm to take it to the next stage.

Count.pm

package Countsample;

use strict;
use warnings;
use base "Exporter";
use 5.010;

our @EXPORT = qw/line_count/;

sub line_count {
  my $line = @_;
  return $line;
}

1;

Count1.pl

#!/usr/bin/perl

use strict;
use warnings;

use Count;
my $line;
open FH,"text1.txt";
line_count();
print "$line\n";

Update: The "undefined subroutine" error was because I forgot to change the name of the package in Count.pm. Having done that I now get:

$ ./Count1.pl 
Name "main::FH" used only once: possible typo at ./Count1.pl line 8.
Use of uninitialized value $line in concatenation (.) or string at ./Count1.pl line 10.

Which is the point at which you really need to start thinking about how your module works. What subroutines do you need? What parameters do they take? What do they return?

Upvotes: 1

Related Questions