WWW::Mechanize, and example using OOP
Before learning how to write our classes, let's take a look at an example of using a Perl module which was written in Object Oriented style.
We are looking at the WWW::Mechanize module that makes it easy to send HTTP requests to web servers. I am quite sure you have encountered many similar modules, but for our purposes this would be a fine example.
This is the full code in a file called demo.pl
.
use strict;
use warnings;
use feature 'say';
our $VERSION = '0.01';
use WWW::Mechanize;
my $url = shift @ARGV or die "Usage $0 URL";
# say $WWW::Mechanize::VERSION;
my $mech = WWW::Mechanize->new(autocheck => 0);
my $res = $mech->get($url);
say $res->status_line;
say $mech->status();
say $mech->res->status_line;
say '';
$mech->dump_headers();
say '';
if ($mech->success) {
print $mech->content;
}
We can use it on the command line by passing a URL as a parameter. httpbin.org is a nice web site that can help us verify if your HTTP client works correctly.
In the first example we send a request that is expected to return a JSON structure describing our request.
- The first 3 printed line are the status of the response in 3 different ways.
- Then we have some 15 line of text which is the header sent by the server to our client.
- Then we can see a JSON structure showing the content the server sent us back. In this particular request the server sends back details about our request. So for example we can see that the the User-Agent field was WWW-Mechanize/2.19 the module we used.
$ perl demo.pl https://httpbin.org/get
200 OK
200
200 OK
Connection: close
Date: Sun, 22 Jun 2025 12:40:45 GMT
Server: gunicorn/19.9.0
Content-Length: 271
Content-Type: application/json
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: *
Client-Date: Sun, 22 Jun 2025 12:38:26 GMT
Client-Peer: 34.198.95.5:443
Client-Response-Num: 1
Client-SSL-Cert-Issuer: /C=US/O=Amazon/CN=Amazon RSA 2048 M02
Client-SSL-Cert-Subject: /CN=httpbin.org
Client-SSL-Cipher: ECDHE-RSA-AES128-GCM-SHA256
Client-SSL-Socket-Class: IO::Socket::SSL
Client-SSL-Version: TLSv1_2
{
"args": {},
"headers": {
"Accept-Encoding": "gzip",
"Host": "httpbin.org",
"User-Agent": "WWW-Mechanize/2.19",
"X-Amzn-Trace-Id": "Root=1-6857f9cd-788661eb40c56ecd14d4d272"
},
"origin": "46.120.8.126",
"url": "https://httpbin.org/get"
}
In the second example we ask the server to pretend there was an uncaught exception in the server that resulted in a "500 Internal Server Error".
$ perl demo.pl https://httpbin.org/status/500
500 INTERNAL SERVER ERROR
500
500 INTERNAL SERVER ERROR
Connection: close
Date: Sun, 22 Jun 2025 12:41:15 GMT
Server: gunicorn/19.9.0
Content-Length: 0
Content-Type: text/html; charset=utf-8
Access-Control-Allow-Credentials: true
Access-Control-Allow-Origin: *
Client-Date: Sun, 22 Jun 2025 12:38:56 GMT
Client-Peer: 18.209.97.55:443
Client-Response-Num: 1
Client-SSL-Cert-Issuer: /C=US/O=Amazon/CN=Amazon RSA 2048 M02
Client-SSL-Cert-Subject: /CN=httpbin.org
Client-SSL-Cipher: ECDHE-RSA-AES128-GCM-SHA256
Client-SSL-Socket-Class: IO::Socket::SSL
Client-SSL-Version: TLSv1_2
Details of the code
Let's go over the important parts of the code:
We load the module. There is no need to list the function we would like to import as we don't import any functions.
use WWW::Mechanize;
In Perl the thin arrow operator is used for method calls. (In most other languages the dot .
is used for that, but in Perl the .
was already used by string concatenation and thus a different symbol had to be selected.
In this expression we call the new
method of the WWW::Mechanize
class. It is the constructor. We pass some parameters to initialize the instance. What this expression returns, what we assign to the $mech
variable
is an instance (object) of the WWW::Mechanize
class.
my $mech = WWW::Mechanize->new(autocheck => 0);
In the next line we call the get
method on the instance (object) passing some parameter to it. It returns a different object. Specifically this call returns an instance
of the HTTP::Response class. I assume, that internally the get
method does some work then calls the constructor of
the HTTP::Response class and then returns the created instance.
my $res = $mech->get($url);
The next 3 lines show the status of the request in 3 different ways. Normally you'd use only one of them, but here I wanted to show different ways of using OOP.
- In the first line we use the
status_line
method of theHTTP::Response
instance we got back from theget
call. - In the second line we use the
status
method of the originalWWW::Mechanize
instance. This one only shows the status number, without the text. - Finally we see a chained call. Apparently the
res
method of theWWW::Mechanize
instance returns the sameHTTP::Response
instance as we got from theget
call earlier. We don't need to store it in a variable, we can immediately call its method.
say $res->status_line;
say $mech->status();
say $mech->res->status_line;
Reading the code further we see 3 additional method calls.
That's it for our little demonstration of OOP.
We also have a file called Makefile.PL
. It is useful to defined the dependencies of our little project.
use strict;
use warnings;
use ExtUtils::MakeMaker;
WriteMakefile(
NAME => 'Demo',
AUTHOR => q{Gabor Szabo <szabgab@cpan.org>},
VERSION_FROM => 'demo.pl',
ABSTRACT => 'Demo',
( $ExtUtils::MakeMaker::VERSION >= 6.3002
? ( 'LICENSE' => 'perl' )
: () ),
PL_FILES => {},
PREREQ_PM => {
'WWW::Mechanize' => 0,
'Test::More' => 1,
},
dist => { COMPRESS => 'gzip -9f', SUFFIX => 'gz', },
clean => { FILES => 'Demo-*' },
);