Gossamer Forum
Home : General : Perl Programming :

Got me stumped.....

(Page 2 of 2)
> >
Quote Reply
Re: Got me stumped..... In reply to
That's a typo. I forgot to change that to "$#old".

that should be:
Code:
if ($#new != $#old) { #was a element removed (same num elements if not)
--Drew
Quote Reply
Re: Got me stumped..... In reply to
I had a feeling that's what it was.

Why does it need to check the last value of the array?

EDIT:
Sorry I just saw that grep pushes the value to the end....ignore me.

Paul
Installations:http://wiredon.net/gt/
Support: http://wiredon.net/forum/

Quote Reply
Re: Got me stumped..... In reply to
That line checks to see if there are the same number of elements in the @new and @old array (less code than creating another variable...). If the number of elements is the same, then the record wasn't removed, so it skips the rewrite part.

--Drew
Quote Reply
Re: Got me stumped..... In reply to
Thanks.

Paul
Installations:http://wiredon.net/gt/
Support: http://wiredon.net/forum/

Quote Reply
Re: Got me stumped..... In reply to
Yep it works great thanks....

I'm using grep in the subscribe sub now also, to check if they are already subscribed as opposed to if they don't exist, in the unsubscribe sub.

Paul
Installations:http://wiredon.net/gt/
Support: http://wiredon.net/forum/

Quote Reply
Re: Got me stumped..... In reply to
In the spirit of there's more then one way to do this, try this out:

Code:
use Fcntl ':flock';

# Usage: unsubscribe ('email@address.com');
sub unsubscribe {
my $email = shift;

# Read email file into $data.
open (DB, "< $email_db_path$email_db") or die "Can't read open: $!";
flock (DB, LOCK_SH);
read (DB, my $data, -s DB);
close DB;

# Check to see if the string $email followed by a pipe is in this file.
# and we see that we can remove the line.
if ((index ($data, "$email|") >= 0) and ($data =~ s/^$email.+\n//m)) {
open (DB, "> $email_db_path$email_db") or die "Can't write open: $!";
flock (DB, LOCK_EX);
print DB $data;
close DB;
print "Location: $redirect_unsub\n\n";
}
# If index returned -1, that means it didn't match.
else {
error ("Could not unsubscribe!");
return;
}
}

# Usage: subscribe ('email@address.com', 'name');
sub subscribe {
my ($email, $name) = @_;

# Read email file into $data.
open (DB, "< $email_db_path$email_db") or die "Can't read open: $!";
flock (DB, LOCK_SH);
read (DB, my $data, -s DB);
close DB;

# Check to see thtat the user already isn't subscribed.
if ((index ($data, "$email|") >= 0) and ($data =~ s/^$email\|.+\n//m)) {
error ("Already subscribed!");
return;
}

# Nope, add the user in.
open (DB, "> $email_db_path$email_db") or die "Can't write open: $!";
flock (DB, LOCK_EX);
print DB $data, "$email|$name\n";
close DB;
print "Location: $redirect_sub\n\n";
}
the index function is a lot more efficent then a reg ex, and using read is upto 9x faster in reading in a file then slurping it into an array.

If you have questions about this, feel free to ask!

Cheers,

Alex

--
Gossamer Threads Inc.
Quote Reply
Re: Got me stumped..... In reply to
Thankyou so much for taking the time to come up with that for me although I expect you rattled it off with no trouble.

That obviously is quite a bit different to the original version and I am not ashamed to say that I don't understand chunks of it.....lol......mainly because I've not used index or read like that before. After looking over it a few times I am now however beginning to understand it a little better.

In the unsubscribe sub you have this at the top..my $email = shift; but the email address passes to the script from the html form and either the unsubscribe or subscribe sub is called depending on which they select from the select list on the form page so how would shift work?

What is this line doing also?
read (DB, my $data, -s DB);

I know it is reading the data from the file but I'm not totally clear on what the code is doing within the brackets.

Anyway thanks again, you have all helped me a great deal.....

Paul
Installations:http://wiredon.net/gt/
Support: http://wiredon.net/forum/

Quote Reply
Re: Got me stumped..... In reply to
perldoc -f read

Smile

Quote Reply
Re: Got me stumped..... In reply to
Thanks, I will do that too but Alex did say I could ask....

In Reply To:
If you have questions about this, feel free to ask!
Paul
Installations:http://wiredon.net/gt/
Support: http://wiredon.net/forum/

Quote Reply
Re: Got me stumped..... In reply to
Well sure, but you should always get in the habit of checking the docs first, and asking questions only if you don't understand what's in there. Not the other way around.

It's a good habit because there won't always be someone around, and you'll need to pull out the bits and pieces you need.

Trust me, many long hours pouring though docs in my day Wink

--mark

Quote Reply
Re: Got me stumped..... In reply to
I do trust you and I do try as much as I can to read relevant info on the net before I post but sometimes I can't find what I'm looking for and sometimes I forget..(hehe).

I accept your point.

Paul
Installations:http://wiredon.net/gt/
Support: http://wiredon.net/forum/

Quote Reply
Re: Got me stumped..... In reply to
In Reply To:
In the unsubscribe sub you have this at the top..my $email = shift; but the email address passes to the script from the html form and either the unsubscribe or subscribe sub is called depending on which they select from the select list on the form page so how would shift work?
I'm not sure bot I assume that the code provided by Alex needs a 'main sub'. Just to trigger the subscribe and unsubscribe subs! Maybe something like:

Code:
sub main {
# --------------------------------------------------------
$|++; # Flush Output.
my %in = &parse_form;
my $action = $in{'action'};
my $email = $in{'email'};
my $name = $in{'name'};
($email =~ /.+@.+\..+/) or &error ("The email address: '$email' doesn't look like a real email address.") and return;
($name =~ /[A-Za-z]+/) or &error ("Please enter a name as well as an email address.") and return;

CASE: {
($action eq "subscribe") and do { &subscribe ('$email', '$name'); last CASE; };
($action eq "unsubscribe") and do { &unsubscribe('$email'); last CASE; };

&display_form();
};
}
Just have a look at the subscribe.cgi included with Links2.0 Wink

Quote Reply
Re: Got me stumped..... In reply to
In Reply To:
What is $#data?
It's the index of the last element of the array. So, if @data contains 3 elements, $#data will be equal to 2.

Of course, this all changes if you start playing with $[ - which you shouldn't do, so let's not worry about that!

Jason

Jason Rhinelander
Gossamer Threads
jason@gossamer-threads.com
Quote Reply
Re: Got me stumped..... In reply to
Hi,

Sorry, that post of mine was easy to misunderstand. I knew what $#data meant but was asking where $#data had come from because it wasnt in my original code. Sorry for the confusion.

Paul
Installations:http://wiredon.net/gt/
Support: http://wiredon.net/forum/

Quote Reply
Re: Got me stumped..... In reply to
In Reply To:
Code:
map { print } @array;
is the same thing as:
Code:
foreach (@array) { print;}
Actually, it's not the same - it's more like this:
Code:
my @return; foreach (@array) { push @return, print } @return;
It's optimized to be much faster than that, of course, but the point is that map and grep have a return value that you should be using - if you aren't using it, for (@array) makes more sense as it is definately faster (just how much varies, but just to loop through the list and do something with the data it will always be faster).

(Both of those loops above would be far better replaced with just a print @array; but to show how a map works it's a good example)

Some examples of when using map() makes sense:

Code:
@new_list = map { "prefix$_" } @old_list
@new_list contains all the elements of @old_list, prefixed with "prefix"
Code:
@new_list = grep { substr($_, 0, 1) ne 'a' } @old_list
@new_list now contains all the elements of @old_list EXCEPT those that being with the character 'a'.
Code:
%hash = map { ($_ => 1) } @list;
%hash now contains all the elements of @list as keys, and the values are all 1. You can use something like this to test if something exists in an array with:
Code:
if ($hash{$value}) { ... }
Jason Rhinelander
Gossamer Threads
jason@gossamer-threads.com
> >