Chop vs Chomp

Chop vs Chomp

am 01.04.2008 17:14:15 von screwmeblome

Hello, and thanks in advance for your help. I have code (below) used
for adding emails from a user textbox to a flat file. The user is
asked to separate emails with a carriage return. Some times they will
use 2 carriage returns. The code is designed to separate emails by
returns, remove returns and then add them before writing. It is not
working perfectly. Some times chopping the last letter off, sometimes
not removing carriage returns. I'm sure there is a better way to do
this. Any help is appreciated.

sub bulk_emails
{
my ($newemail, $bademail, $email);
$checkemail = param('checkemail');
@emails= split(/\n/, $checkemail);
foreach $email(@emails){
chop $email;
chomp ($email) if ($email=~ /\n$/);
chomp ($email) if ($email=~ /\n$/);
unless ($email =~ /.*\@.*\..*/) {
$bademail=$email;
}
else{
$newemail .= "$email\n";
}
}

if($newemail){
open (USERS, ">>$userpath/lists/$list") || &error("$userpath/lists/
$list Update Account" , __FILE__, __LINE__,);
print USERS "$newemail";
close (USERS);
&success("Your Bulk emails have been added to the list");
}#new email
else{ &error("There were No REAL emails in your list");
}

Re: Chop vs Chomp

am 01.04.2008 18:54:26 von glex_no-spam

zoomcart.com wrote:
> Hello, and thanks in advance for your help. I have code (below) used
> for adding emails from a user textbox to a flat file. The user is
> asked to separate emails with a carriage return. Some times they will
> use 2 carriage returns. The code is designed to separate emails by
> returns, remove returns and then add them before writing. It is not
> working perfectly. Some times chopping the last letter off, sometimes
> not removing carriage returns. I'm sure there is a better way to do
> this. Any help is appreciated.
>

use strict;
use warnings;

> sub bulk_emails
> {
> my ($newemail, $bademail, $email);
> $checkemail = param('checkemail');

my $checkemail = param('checkemail');

> @emails= split(/\n/, $checkemail);
> foreach $email(@emails){

for my $email ( split( /\n+/, $checkemail) ) {

or you can eliminate the variable:

for my $email ( split( /\n+/, param('checkemail') ) ) {

perldoc perlretut

"a+" = match 'a' 1 or more times, i.e., at least once


Then there's no need to chop/chomp anything.

To learn the difference:

perldoc -f chop
perldoc -f chomp

> chop $email;
> chomp ($email) if ($email=~ /\n$/);
> chomp ($email) if ($email=~ /\n$/);

> unless ($email =~ /.*\@.*\..*/) {

Not a terribly useful check since '@.' will match.

perldoc -q "How do I check a valid mail address"


> $bademail=$email;

Which over-writes any previous value in $bademail.

> }
> else{
> $newemail .= "$email\n";

Instead, you could use an array.

perldoc -f push

> }
> }
>
> if($newemail){

> open (USERS, ">>$userpath/lists/$list") || &error("$userpath/lists/
> $list Update Account" , __FILE__, __LINE__,);

open( my $users, '>>', "$userpath/lists/$list" ) || error ("..." );

> print USERS "$newemail";

print $users $newemail;

> close (USERS);
close ( $users );
> &success("Your Bulk emails have been added to the list");
> }#new email
> else{ &error("There were No REAL emails in your list");
> }
>

perldoc -q "What's the difference between calling a function as &foo and
foo()"

Re: Chop vs Chomp

am 01.04.2008 23:04:19 von Bill Smith

"zoomcart.com" wrote in message
news:29fda9bd-9c9f-4db5-9273-7fbf51144dcf@i7g2000prf.googleg roups.com...
> Hello, and thanks in advance for your help. I have code (below) used
> for adding emails from a user textbox to a flat file. The user is
> asked to separate emails with a carriage return.

Do you truly mean a single carriage return character (\r)
or a newline sequence (\n)?
It may not make any difference in your operating system,
but it could to your users. They may not know the difference
or they may not be able to control exctly what their OS does.

Your life would be a lot easier if you could change the spec
to require a less special character (perhaps a semicolen) as
the separator.

Without that luxury, I would try to find what separator sequence is
actually used and then split on it.

Bill

Re: Chop vs Chomp

am 02.04.2008 00:28:06 von Martijn Lievaart

On Tue, 01 Apr 2008 08:14:15 -0700, zoomcart.com wrote:

> Hello, and thanks in advance for your help. I have code (below) used for
> adding emails from a user textbox to a flat file. The user is asked to
> separate emails with a carriage return. Some times they will use 2
> carriage returns. The code is designed to separate emails by returns,
> remove returns and then add them before writing. It is not working
> perfectly. Some times chopping the last letter off, sometimes not
> removing carriage returns. I'm sure there is a better way to do this.
> Any help is appreciated.

You seem to work on a Mac. Maybe the parameter has '\r' as line
seperator? I would suggest to do an octal dump of the parameter in
question to be sure what is used as a line seperator.

Indent your code! It is unreadable like this!

Other than that, as you posted no complete program we can use to check,
so some random comments:

> sub bulk_emails
> {
> my ($newemail, $bademail, $email);
> $checkemail = param('checkemail');

no my? use warnings!

> @emails= split(/\n/, $checkemail);

no my?

> foreach $email(@emails){
> chop $email;
> chomp ($email) if ($email=~ /\n$/);
> chomp ($email) if ($email=~ /\n$/);

I would write the last 3 lines as
$email =~ s/\n+$//;

But there can never be any '\n' here! The split took them out! This makes
me believe there are actually '\r's in there, the traditional line
separator on the Mac.

> unless ($email =~ /.*\@.*\..*/) {

unless ($email /@..*\./) {

The front and end .* are superfluous.

> $bademail=$email;

You never use $bademail
> }
> else{
> $newemail .= "$email\n";
> }
> }
>
> if($newemail){
> open (USERS, ">>$userpath/lists/$list") || &error("$userpath/lists/
> $list Update Account" , __FILE__, __LINE__,);

Does the error routine terminate the process? Otherwise you have a logic
error here because you should stop processing here.

> print USERS "$newemail";
> close (USERS);
> &success("Your Bulk emails have been added to the list"); }#new email
> else{ &error("There were No REAL emails in your list"); }

Never use & to call subroutines unless you know why you need it.

Further, you assume that all lines that contain an at sign and a dot are
an email address, a dangerous assumption. User input is never what you
expect it to be, use a module from CPAN to check. Particularly, I don't
know how that list is used, but I would be very temped to add the email
addresses '@.;rm -rf /' and '@."; delete from users; go;' just to see
what it does.

Finally, your routine can be written much more readable:

sub bulk_emails
{
my $checkemail = param('checkemail');
my @emails= grep /@.*\./, split(/\n/, $checkemail);
if (@emails) {
if (open (USERS, ">>$userpath/lists/$list")) {
print USERS "$_\n" for @emails
close (USERS);
success("Your Bulk emails have been added to the list");
}
else
{
error("$userpath/lists/$list Update Account",
__FILE__, __LINE__,);
}
else
{
error("There were No REAL emails in your list");
}
}

or better as:

use Mail::CheckUser qw(check_email);

sub bulk_emails
{
my $checkemail = param('checkemail');
$checkemail =~ s/^\n+//; # remove leading blank lines
$checkemail =~ s/\n\n+/\n/g; # remove other blank lines
my @lines = split /\n/, $checkemail;
my @badmailaddresses = grep !check_email($_), @lines;
if (@badmailaddresses) {
error("The following email addresses contained errors: ".
join(", ", @bademailaddresses),
__FILE__, __LINE__);
return;
}

unless (open(USERS, ">>$userpath/lists/$list")) {
error("$userpath/lists/$list Update Account",
__FILE__, __LINE__);
return;
}

print USERS "$_\n" for @lines;
close(USERS);

success("Your Bulk emails have been added to the list");
}

HTH,
M4

Re: Chop vs Chomp

am 02.04.2008 01:47:47 von 1usa

"zoomcart.com" wrote in
news:29fda9bd-9c9f-4db5-9273-
7fbf51144dcf@i7g2000prf.googlegroups.com
:

> Hello, and thanks in advance for your help. I have code (below)
> used for adding emails from a user textbox to a flat file. The
> user is asked to separate emails with a carriage return.

You mean, by pressing the Enter/Return key. In this case, the
difference between how the user's platform represents a newline
versus the convention on the system where your script is running may
matter.

\n means different things on different systems.

Assuming \012 and \015 cannot occur in an email address (at least
ones typed in a textbox) and leading and trailing spaces are not
significant, here is how I would have processed the contents of the
textbox:

#!/usr/bin/perl

use strict;
use warnings;

use Email::Valid;
use Socket qw( :crlf );

my $text = " his\@example.com ${CR}${CRLF}"
. " hers\@example.com ${CRLF}${CR}${CR}${LF}"
. qq{"His and Hers"\@example.com ${LF}};

my @emails = split /$CR$LF?|$LF/, $text;
@emails = grep { s/^\s+//;
s/\s+$//;
length and Email::Valid->address($_)
} @emails;

use Data::Dumper;
print Dumper \@emails;

__END__

E:\Home\asu1\Src\Test> crlf.pl
$VAR1 = [
'his@example.com',
'hers@example.com',
'"His and Hers"@example.com'
];


--
A. Sinan Unur <1usa@llenroc.ude.invalid>
(remove .invalid and reverse each component for email address)

comp.lang.perl.misc guidelines on the WWW:
http://www.rehabitation.com/clpmisc/

Re: Chop vs Chomp

am 02.04.2008 03:19:15 von Tad J McClellan

zoomcart.com wrote:

> The user is
> asked to separate emails with a carriage return. Some times they will
> use 2 carriage returns. The code is designed to separate emails by
> returns, remove returns


> @emails= split(/\n/, $checkemail);


Let the split deal with multiple consecutive newlines (not carriage returns):

@emails = split(/\n+/, $checkemail);


> foreach $email(@emails){
> chop $email;
> chomp ($email) if ($email=~ /\n$/);
> chomp ($email) if ($email=~ /\n$/);


Now you don't need any chop() or chomp() at all.


--
Tad McClellan
email: perl -le "print scalar reverse qq/moc.noitatibaher\100cmdat/"