Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Beginners help to creating their first perl module!

Status
Not open for further replies.

cgilover

Programmer
Oct 8, 2004
32
0
0
US
I'm trying to create my first perl module and I have zero knowledge of what I'm trying to do.

I want to make it simple but something I'll likely use, so I decided on a meta tag parser. The module will use LWP::Simple and parse a given $url and strip ALL meta content into a hash then export the hash into the script so the admin/script user can do whatever the heck they want with it.

I can do the parts of LWP::Simple and parsing of the page into a hash just fine, I've done this countless times before.

My question is, since they are using my module "MetaParser.pm" , the module needs a way to GET the $url from the script. LWP::Simple does it like my $content = get("$url");

I want to do a similar function and maybe call it my $content = getm("$url");

Can anyone help me figure out how to setup getm(); to work?

Secondly, I am storing all the meta tag content in a hash (meta name => meta content). I need to know how I can export this hash into the script EASILY. I don't want to do main::MetaParser.. or whatever that is. There's got to be an easy way to get my hash into the script.

Thirdly, is there a way to instead of using my $content = getm("$url"); to use my %content = getm("$url"); and have the hash they just created actually be the hash that the script makes with the content? I think this would be a better bet, otherwise the scalar $content would be useless throughout the script. It would be nice if they could do it this way and have %content already set up.

This isn't much so far, but this is what I have:

Module:
Code:
package TestPrint;
use Exporter;
@ISA = 'Exporter';
@EXPORT_OK = qw(test_print);
use strict;


sub test_print
{
   use LWP::Simple;  

return;
}

1;

__END__

Script:
Code:
#!/usr/bin/perl

use warnings;
use strict;

use TestPrint qw(test_print);

&test_print;

 
You basically have to create a sub routine within your "MetaParser.pm" script and grab the variable i.e. "$url" using ($), such as in simple.pm. Might be worth taking a look at simple.pm, I'm using windows, it can be found at the following path: c:\perl\site\lib\lwp\simple.pm, here's an extract on how the sub routine get() is coded:

Code:
sub get ($)
{
    %loop_check = ();
    goto \&_get;
}

sub _get
{
    my $url = shift;
    my $ret;
    if (!$FULL_LWP && $url =~ m,^[URL unfurl="true"]http://([/URL][^/:\@]+)(?::(\d+))?(/\S*)?$,) {
	my $host = $1;
	my $port = $2 || 80;
	my $path = $3;
	$path = "/" unless defined($path);
	return _trivial_http_get($host, $port, $path);
    }
    else {
        _init_ua() unless $ua;
	if (@_ && $url !~ /^\w+:/) {
	    # non-absolute redirect from &_trivial_http_get
	    my($host, $port, $path) = @_;
	    require URI;
	    $url = URI->new_abs($url, "[URL unfurl="true"]http://$host:$port$path");[/URL]
	}
	my $request = HTTP::Request->new(GET => $url);
	my $response = $ua->request($request);
	return $response->is_success ? $response->content : undef;
    }
}

I haven't ever built my own modules before but I know they work in a similar structure to standard perl scripts, they're just more clever than my scripts!!

Rob Waite
 
I build a lot of my own modules since I never know when I might need the same functionality twice. I can tell you how many times I thought I would never need a subroutine again and find myself rewriting it.

I preferr to have modules that are OOP in nature. I dont like my name space trampled with keywords from other modules. It just makes debugging larger application too difficult. As a suggestion you can do both types in you module. The older way of exporting subroutines and the new of using an OOP interface.

package TestPrint;
use Exporter;
@ISA = 'Exporter';
@EXPORT_OK = qw(test_print);
use strict;

I see that you have asked your potential users to explicitly ask for the name of your subroutine. That helps you can also do the below code to add OOP functionality.

sub new{
my $pkg = shift;
my $obj = {@_};

my %$obj =(%$columns, %$obj);
$obj = bless {%$obj},$pkg || die 'unable to bless object!';
return $obj;
}


Now in the documentation just add support for it

OOP interface contructor
require TestPrint;
#Constructor without arguments
my $OBJECT = new TestPrint;

#call a method
$OBJECT->get();

This isolates your code from others code better and makes for a cleaner module






haunter@battlestrata.com
 
Sorry, I am even more confused.

Can any of you tell me what's wrong with my code now? Or from here tell me how I can make it work?

Module
Code:
package MetaParser;
use Exporter;
@ISA = 'Exporter';
@EXPORT_OK = qw(getm);
use strict;


 use LWP::Simple;

sub getm
{
   my $url = @_;

   print "url is $url";

return;
}

1;

__END__


Script
Code:
#!/usr/bin/perl

use warnings;
use strict;

use MetaParser qw(getm);

my $content = getm("[URL unfurl="true"]www.sulfericacid.com");[/URL]

print $content;


Maybe I don't understand how I'm supposed to get the results out of the module. I'm guessing it's not in $content like I think. All I want to do right now is get the input in getm(); back to them in a hash I guess for now. From there I will see if I can figure it out.

Thanks!
 
First off you are not access LWP::Simple correctly you need to read the docs more carefully. I will fill in the blanks

I will try to keep the code simple and follow your style except I will make it a object oriented.

new module:
Code:
package MetaParser;

use strict;
use LWP::Simple;


sub new{
my $pkg = shift;
my $obj  = {@_};

    $obj = bless {%$obj},$pkg || die 'unable to bless object!';
return $obj;
}

sub getm{
my $obj = shift;
my $url = shift;
my $content = get($url);
 die "Couldn't get it!" unless defined $content;
return $content;

}


1;


Accessing the module
Code:
my $parse   = new MetaParser;
my $content = $parse->getm('[URL unfurl="true"]www.someurl.com');[/URL]

You will notice that no code is exported. Infact the Exporter portion is completely removed. This just adds unecessary weight to your module and clutters others namespaces and makes debugging difficult.

Now I would suggest internalizing some of the functions so several calls dont have to be made to you module to get stuff done.


haunter@battlestrata.com
 
Oh wow, that works awesome. I am not a huge fan of OOP but it got rid of the exporter function and enables them to create any variable they want.

Can you explain what this is doing?

Code:
sub new{
my $pkg = shift;
my $obj  = {@_};

    $obj = bless {%$obj},$pkg || die 'unable to bless object!';
return $obj;
}

What is being blessed and what part of the script is using this?

Thanks!
 
You will need to read on the subject that you are asking. PERL comes with a rich set of documentation that you should get acquanted with. I cannot begin to explain the topic properly here but this link should help.



haunter@battlestrata.com
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top