Re: qr and subroutines



On Fri, 12 Jan 2007 14:18:24 +0100, Robert 'phaylon' Sedlacek
<rs@xxxxxx> wrote:

[SNIP]
}

Wait a second. First, don't use & in front of build_url unless you
really know what it is doing. Second: Your $tmp_regex is not a regex,
it's a string. Third: In your function you don't use $tmp_regex as
regex, but as substitute.


OK, after reading up, I understand no "&" when calling function in
this way, thanks.
I shouldn't have referred to the string as "regex", but I was really
referring to the 3'rd example, which was "regex" and "string
replacement" all in one go. I agree, incorrect in definition.

[SNIP]



The solutions:
- Use a regex where you want a regex, use a string where you want a
string.
- You can pass more than one argument.


<untested>

my $search = qr/index\.php/;
my $replace = 'admin/index.php?admin=22&sid=';

my $new_uri
= rework_uri('http://example.com/index.php', $search, $replace);

sub rework_uri {
my ($uri, $search, $replace) = @_;
$uri =~ s/$search/$replace/;
$uri .= $sid;
return $uri;
}

</untested>

I agree, and I understand that I can do it this way, but it's STILL "3
lines of code", which is no less than what I had originally - so I
don't obtain an advantage of brevity in re-using code through a
subroutine. I just wanted to do something like that all in one
statement, that passes everything to the subroutine.

Mind you, there is an advantage in doing it that way - by passing
"regex" and "replacement" string, a degree of flexibility is obtained,
so that has to be considered a win. Thanks mate.


AND consequently, considering your advice, what about this:

my $input_url = 'http://xyz.com.au/forum/index.php';
my $tmp_regex = '';



$tmp_regex = qr/index\.php/;
my $login_url = build_url( $tmp_regex, 'admin/index.php?sid=', 1 );



sub build_url {
my ( $tmp_regex, $replace_string, $sid_flag ) = @_;
my $tmp_url = $input_url;
$tmp_url =~ s/$tmp_regex/$replace_string/;
$tmp_url .= $s_id if ( $sid_flag == 1 );
return $tmp_url;
}


So, I get the code in the body of the program down to two lines, each
time I need to perform the action, and further, gain the flexibility
of supplying the qr/regex/ AND the replacement string, and a flag to
add the $s_id or not :-)

Does it get any better than this?





#!/usr/bin/perl

use strict;
use warnings;

use WWW::Mechanize;
my $mech = WWW::Mechanize->new( autocheck => 1 );

use WWW::Mechanize::Frames;
my $mech_f = WWW::Mechanize::Frames->new();

my $input_url = 'http://xyz.com.au/forum/index.php';
my $name = 'username';
my $password = 'password';
my $button = 'login';
my $tmp_regex = '';

$mech->get( $input_url );

print_title();
authenticate();

my $raw_mech = $mech->content;

my $s_id = $raw_mech;
$s_id =~ tr/\n/ /;
$s_id =~ s/^.*admin\/index\.php\?sid=([0-9a-z]*)">.*$/$1/;

$tmp_regex = qr/index\.php/;
my $login_url = build_url( $tmp_regex, 'admin/index.php?sid=', 1 );

$tmp_regex = qr/index\.php/;
my $logout_url = build_url( $tmp_regex, 'login.php?logout=true&sid=',
1 );

$mech->get( $login_url );

print_title();
authenticate();

$tmp_regex = qr/index\.php/;
my $admin_url = build_url( $tmp_regex, 'admin/index.php?admin=1&sid=',
1 );

$mech_f->get( $admin_url );

print_title();

my @frames = $mech_f->get_frames();

$raw_mech = "";
$raw_mech = $mech->content;

print "$login_url\n";
print "$logout_url\n";
print "$admin_url\n";

#print $frames[0]->content;
#print $frames[1]->content;

logout();
exit 0;


#==================================================================#

sub authenticate {
$mech->set_fields( $name => '' );
$mech->set_fields( $password => '' );
$mech->click;
}

sub print_title {
my $raw_mech = $mech->content;
my $page_title = $raw_mech;
$page_title =~ tr/\n/ /;
$page_title =~ s|^.*<title>(.*)</title>.*$|$1|i;
$page_title =~ s/^/PAGE TITLE: /;
print "\n$page_title\n";
}

sub build_url {
my ( $tmp_regex, $replace_string, $sid_flag ) = @_;
my $tmp_url = $input_url;
$tmp_url =~ s/$tmp_regex/$replace_string/;
$tmp_url .= $s_id if ( $sid_flag == 1 );
return $tmp_url;
}

sub logout {
$mech->get( $logout_url );
}
.