473,218 Members | 1,418 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes and contribute your articles to a community of 473,218 developers and data experts.

Creating custom Modules

Kelicula
176 Expert 100+
This is NOT a complete OO perl tutorial

However I thought it could be beneficial to explain some of the basic concepts, and allow some users to simplify the software design process.

I have found it to be extremely useful and beneficial to create my own "custom" modules. It (among many other things) allows you to type less. Or to make your keystrokes matter more, however you look at it. (If you do even look at it.)

Things the reader should be familiar with before reading this:
  • References
  • writing and using subroutines
  • The main three data "types" in perl

First of all you will hear alot of new terms, in dealing with OO perl. (That's object oriented) But don't be discouraged that's only the third virtue of a perl programmer "Hubris". We LOVE to have fancy names for things that noone else understands, and get paid more by our boss because of it.


Object- An object is simply a data type. It is much like a hash (if you want it to be) or an array, or a subroutine. An object is a reference to information stored in the computer memory. It is a scalar version of a multidimensional entity. But basically an object just provides you with "properties", and "methods". If you had a "girlfriend" object, it (she hopefully) would have properties: hair color, eye color, height, sex appeal (crossing my fingers here). She also would have methods, which are simply "actions" that she can perform. Or "subroutines" associated with her. She may have a "hold my hand" method, when invoked would cause her to seek you out in a crowd of strangers, and ....(drum roll) hold your hand.
The advantage of having an object is that you now know what types of things it can do, and you have access to all its properties.
Right there in one tidy place.


Class- A class is simply a "package", or a definition of what an object will be, and what kind of things it can do. If it ever it comes into existence.
Objects belong to classes. A girlfriend object would not come from the same class as a "sister" object. (unless you've from WV heheheee.. j/k)

Package- A package is a file. It is a perl script that defines a class. You write your packages, and put them in the Perl/lib directory. Then you can use them in your other scripts with the "use" keyword.

Let's see an example

Many of you will be familiar with the CGI module so let's look at a simple script and pick it apart.
Expand|Select|Wrap|Line Numbers
  1. #!/usr/bin/perl 
  2.  
  3. use strict;
  4. use CGI;
  5.  
  6. my $q = CGI->new();
  7.  
  8. print $q->redirect( -url =>'somewhere', -cookie => 'chocolatechip');
  9.  
  10.  
  11.  
Now what is happening here is:
We are associating our new script with the CGI package, or script, or file, or "Class". So now we have access to it's constructor method. A constructor method is simply the subroutine that makes an object "come to life". That is done with perls "bless" function. More on that later...

Then, (this is important) we create a CGI object called "$q". You see we didn't have a CGI object before this point, we just had a "blueprint" for an object of the CGI class.

Next we invoke the "redirect" method of our object. Which (as methods do) preforms the task of changing our location.

Expand|Select|Wrap|Line Numbers
  1.  
  2. print $q->redirect( -url =>'somewhere', -cookie => 'chocolatechip');
  3.  
  4.  

OK, so let's get dirty

Let's create a package.
This is done with the package keyword. You must first carefully consider what to name your package, because this will also be the name of your class, and the name of your file. Packages have the .pm extension. So create a text file (in your favorite text editor, but NOT Word, or any program that adds rich character formatting. We want plain ASCII text) and name it Girlfriend.pm
Always use a first letter capitol to name your package, perl reserves lower case packages for pragmas, like "strict".

Then type this in your new file:
Expand|Select|Wrap|Line Numbers
  1. package Girlfriend;
  2.  
  3.  
  4. 1;
  5.  
Save this file in the perl "lib" directory. On windows it's C:/Perl/lib.

THAT'S IT!!
You are now ready to "use" your new package.
Notice that we didn't need to list the path to Perl. We also don't need to CHMOD 755 the Girlfriend.pm file either. However you DO need to include the "1;" at the end so that another script can "use" this file. The last statement MUST be a true value. This is the easiest way to achieve that.

You can now create another script and type;
Expand|Select|Wrap|Line Numbers
  1.  
  2. #!/usr/bin/perl
  3.  
  4. use strict;
  5. use Girlfriend;
  6.  
  7.  
At the top of it.

"Well this package is useless", you say.
That's right, we haven't given the Girlfriend object any properties, or methods. (sounds familiar)

Let's fix that.

Start by defining a "constructor" method. Go back to the Girlfriend.pm file and add.

Expand|Select|Wrap|Line Numbers
  1.  
  2.  
  3. sub new {
  4.  
  5. my $class = @_;
  6.  
  7. my $self  = {};
  8. $self->{hairColor} = undef;
  9. $self->{height} = undef;
  10. $self->{friends} = [];
  11.  
  12. return bless($self, $class);
  13. }
  14.  
  15.  
Ah Ha!! There is the magic.
return bless($self, $class);

This reads, associate these properties with any object of the Girlfriend class.

Now in the other script add.
Expand|Select|Wrap|Line Numbers
  1.  
  2. my $jane = Girlfriend->new();
  3.  
Now we have an object.

We can populate it's properties easily.
Expand|Select|Wrap|Line Numbers
  1.  
  2. $jane->{hairColor} = "brown";
  3. $jane->{friends} = ["Sally", "Jim", "Angie"];
  4.  
  5.  
We could also write a method of girlfriend.
After the "new" sub add:
Expand|Select|Wrap|Line Numbers
  1.  
  2. sub smile {
  3.  
  4. print ":-)";
  5. }
  6.  
  7.  
Then to use it in the other script.

Expand|Select|Wrap|Line Numbers
  1. $jane->smile;
  2.  
  3.  
This would print ":-)" to STDOUT.

Notice that when we added values for the properties, they were added to the $jane object of the Girlfriend "class". NOT to the class itself.
We can create other Girlfriend objects too. (although it's not advisable hehheee)

Expand|Select|Wrap|Line Numbers
  1.  my $sara = Girlfriend->new();
  2. $sara->{height} = "TooTall";
  3.  
  4. etc...
  5.  
Then we can have two objects, with different properties, that share to same "structure" or class. However methods may act differently on them depending on what their properties are. Alter the smile sub like this.

Expand|Select|Wrap|Line Numbers
  1.  
  2. sub smile {
  3. my $this = @_;
  4.  
  5. if ($this->{height} =~ /TooTall/){
  6.   print ":-(";
  7. }
  8. else{
  9. print ":-)";
  10.   }
  11. }
  12.  
Now in our other script if we call on the smile method, and "TooTall" is NOT the value of height, we get a smile otherwise a frown.

We would now get a smile from this:
Expand|Select|Wrap|Line Numbers
  1.  
  2. $jane->smile;
  3.  
But a frown from this:
Expand|Select|Wrap|Line Numbers
  1.  
  2. $sara->smile;
  3.  
That's called Polymorphism.

Did you notice the $this variable?
You see when you call on a "class method" the first argument sent to the sub is the object you're working on.

So the argument list would be: $jane.
If you add something else like:
Expand|Select|Wrap|Line Numbers
  1.  
  2. $jane->smile('Hello');
  3.  
  4.  
The argument list would be:
"$jane", "Hello".

Remember that $jane is a reference to an object so we can access it's properties in the sub eg:
Expand|Select|Wrap|Line Numbers
  1. $this->{height};
  2.  
  3.  
You can access a class method directly via:
Expand|Select|Wrap|Line Numbers
  1.  
  2. Girlfriend::smile();
  3.  
  4.  
But it's NOT recommended.





OK well that's enough of OO perl talk.
There are a lot of good tutorials out there to teach you the in's and out's already.

Some of which are located at the bottom of this article.

Let me give you an example of using this to reduce typing, and simplify coding/debugging.

Let's say you have a repetitive task that always needs accomplished.
Use a subroutine you say!!

Yes, but what if this task occurs in every script. You would still have to write that "sub" in every script.

Let's say you want to know if a user is logged in or not, and if they are you want to know certain things about them, all of which is stored in a database.

You could create a "User" module.

Expand|Select|Wrap|Line Numbers
  1. package User;
  2.  
  3. use strict;
  4. use DBI;
  5.  
  6. my $database = "the database";
  7. my $handle = "yourHandle";
  8. my $pass = "yourPassword";
  9.  
  10. my $dbh = DBI->connect("DBI:mysql:$database:localhost", $handle, $password) || die "Error: $DBI::errstr";
  11.  
  12.  
  13. sub new {
  14.  
  15. my ($class, $id) = @_;
  16.  
  17. my $sth = $dbh->prepare(qq~ SELECT * FROM users WHERE id = ? ~);
  18. $sth->execute($id);
  19.  
  20. my $user = $sth->fetchrow_hashref;
  21. $sth->finish;
  22.  
  23. return bless($user, $class);
  24.  
  25. }
  26.  
  27. $dbh->disconnect;
  28.  
  29. 1;
  30.  
Now in your scripts you can easily check if their logged in, and if they are, have access to all the columns in the "users" table record, that is associated with their "id" like this. (Assuming you are storing their id number in a cookie.)

Expand|Select|Wrap|Line Numbers
  1.  
  2. #!/usr/bin/perl
  3.  
  4. use strict;
  5. use CGI;
  6. use User;
  7.  
  8. my $q = CGI->new();
  9.  
  10. if(my $v = $q->cookie('name'){
  11.    my $user = User->new($v);
  12. }
  13.  
  14.  
  15. # Asumming they were loggin in....
  16.  
  17. print "Hello, $user->{username}, I see you have been a member since: $user->{joined}, would you like to update your email address? We have: $user->{email}";
  18.  
  19.  
That's if you were using a mysql database, and had the columns "username", "joined", and "email" in your users table.

Go ahead try it yourself!!

I didn't even get into writing a method for the User module.

Be sure to check out these links below:

Tom's OO tutorial

Excellent pdf!!
Perl training Aussie style
Feb 4 '08 #1
3 7362
Kelicula
176 Expert 100+
Please expound!!

I left A LOT out.But I just wanted to get the ball rollin, so to speak...
Feb 4 '08 #2
KevinADC
4,059 Expert 2GB
I just skipped through fast, but I noticed the last code snippet has one or two errors in it. Missing a ')' after cookie('name') and $user is scoped to the enclosing block and will not be available to the rest of the script.

Should be:

Expand|Select|Wrap|Line Numbers
  1. #!/usr/bin/perl
  2. use strict;
  3. use CGI;
  4. use User;
  5. my $q = CGI->new();
  6. my $user;
  7. if (my $v = $q->cookie('name')) {
  8.    $user = User->new($v);
  9. }
  10. # Asumming they were loggin in....
  11. print "Hello, $user->{username}, I see you have been a member since: $user->{joined}, would you like to update your email address? We have: $user->{email}";
The HTTP header is also missing, but maybe I'm being too nit-picky mentioning that.

Regards,
Kevin(ADC)
Feb 4 '08 #3
Kelicula
176 Expert 100+
I just skipped through fast, but I noticed the last code snippet has one or two errors in it. Missing a ')' after cookie('name') and $user is scoped to the enclosing block and will not be available to the rest of the script.

Should be:

Expand|Select|Wrap|Line Numbers
  1. #!/usr/bin/perl
  2. use strict;
  3. use CGI;
  4. use User;
  5. my $q = CGI->new();
  6. my $user;
  7. if (my $v = $q->cookie('name')) {
  8.    $user = User->new($v);
  9. }
  10. # Asumming they were loggin in....
  11. print "Hello, $user->{username}, I see you have been a member since: $user->{joined}, would you like to update your email address? We have: $user->{email}";
The HTTP header is also missing, but maybe I'm being too nit-picky mentioning that.

Regards,
Kevin(ADC)

That's what I get for staying up late. :(

I guess I should point out, that this tutorial is NOT the kind where you can copy, and paste the code, but, more about the concepts.

I just kinda made the code up, as I was writing it, it's not been debugged, or executed.

I also, left out, "inheritance", "package variables", and exporting into name spaces, weak vs. strong references, destructor methods, using "@ISA", and "our" the __PACKAGE__ variable, interface vs. inheritance polymorphism etc...

But I did try to focus more on reusing code, instead of creating full blown packages.
Hopefully it's enough to get someones feet wet and then maybe decide to learn more...(Please see the excellent links at the bottom!!)

Thanks Kevin!
Feb 4 '08 #4

Sign in to post your reply or Sign up for a free account.

Similar topics

4
by: NutJob | last post by:
Hello, I'm faced with the following problem: I have a (secondary) thread that monitors a socket for incoming message traffic using the select.select() function. Besides that I also have the...
0
by: Jai | last post by:
Dear All Creating Custom Controls but Not User Controls,How to create custom controls,i.e Extending the functionality of the Existing Controls.(Web Custom Controls). Previously i have...
4
by: Alvo von Cossel I | last post by:
hi, i have been asked to make a good-looking app for a friend. i have an options form with a big tabstrip in it. 1. how can i customize it e.g. change from the standard system style...
3
by: Kyle Fitzgerald | last post by:
I've started a web control library project and can build my own controls to add to the toolbox in the .NET environment. The problem I'm having is I want to create a control just like the HTML...
8
by: Aaron | last post by:
I'm coming from C++ programming 5 years ago into VB.NET, so please be patient with me. In C++, I was able to create a "library" of functions and procedures that I would commonly use in various...
0
by: Julien | last post by:
Hi ! I'm creating a custom control, in which I would render an image with client-side script code to display/hide a calendar control which also belong to my custom control. In this control I've...
0
by: Nenefta | last post by:
Good afternoon everyone, I would like to create a custom GridViewand use that in the rest of my project, so all GridViews look the same. I thought it would be as easy as creating a usercontrol...
0
by: Ric | last post by:
I have a mandate from a customer to create custom bubble and gannt charts that are viewable in their Web browser. We explored some of the charting tools and controls but because of the complexity...
1
by: Abdo Haji-Ali | last post by:
Previously I used to create user controls if I wanted to use a specific set of controls in multiple pages, however I want to deploy my control in other applications so I thought of creating custom...
0
by: VivesProcSPL | last post by:
Obviously, one of the original purposes of SQL is to make data query processing easy. The language uses many English-like terms and syntax in an effort to make it easy to learn, particularly for...
3
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 3 Jan 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). For other local times, please check World Time Buddy In...
0
by: jianzs | last post by:
Introduction Cloud-native applications are conventionally identified as those designed and nurtured on cloud infrastructure. Such applications, rooted in cloud technologies, skillfully benefit from...
0
by: mar23 | last post by:
Here's the situation. I have a form called frmDiceInventory with subform called subfrmDice. The subform's control source is linked to a query called qryDiceInventory. I've been trying to pick up the...
0
by: abbasky | last post by:
### Vandf component communication method one: data sharing ​ Vandf components can achieve data exchange through data sharing, state sharing, events, and other methods. Vandf's data exchange method...
2
by: jimatqsi | last post by:
The boss wants the word "CONFIDENTIAL" overlaying certain reports. He wants it large, slanted across the page, on every page, very light gray, outlined letters, not block letters. I thought Word Art...
0
by: fareedcanada | last post by:
Hello I am trying to split number on their count. suppose i have 121314151617 (12cnt) then number should be split like 12,13,14,15,16,17 and if 11314151617 (11cnt) then should be split like...
0
by: stefan129 | last post by:
Hey forum members, I'm exploring options for SSL certificates for multiple domains. Has anyone had experience with multi-domain SSL certificates? Any recommendations on reliable providers or specific...
1
by: davi5007 | last post by:
Hi, Basically, I am trying to automate a field named TraceabilityNo into a web page from an access form. I've got the serial held in the variable strSearchString. How can I get this into the...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.