[31419] in Perl-Users-Digest

home help back first fref pref prev next nref lref last post

Perl-Users Digest, Issue: 2671 Volume: 11

daemon@ATHENA.MIT.EDU (Perl-Users Digest)
Wed Nov 11 18:09:40 2009

Date: Wed, 11 Nov 2009 15:09:06 -0800 (PST)
From: Perl-Users Digest <Perl-Users-Request@ruby.OCE.ORST.EDU>
To: Perl-Users@ruby.OCE.ORST.EDU (Perl-Users Digest)

Perl-Users Digest           Wed, 11 Nov 2009     Volume: 11 Number: 2671

Today's topics:
    Re: connect to localhost failed error with Mail::Sendma <hjp-usenet2@hjp.at>
    Re: Exiting threads via signal <ben@morrow.me.uk>
    Re: Exiting threads via signal sln@netherlands.com
        remove one element with splice <user@example.net>
    Re: remove one element with splice <bugbear@trim_papermule.co.uk_trim>
    Re: remove one element with splice <willem@stack.nl>
    Re: remove one element with splice <ben@morrow.me.uk>
    Re: remove one element with splice <jurgenex@hotmail.com>
    Re: remove one element with splice <user@example.net>
    Re: remove one element with splice <user@example.net>
    Re: remove one element with splice <glennj@ncf.ca>
    Re: remove one element with splice <willem@stack.nl>
    Re: remove one element with splice <yankeeinexile@gmail.com>
    Re: remove one element with splice <jurgenex@hotmail.com>
    Re: remove one element with splice <jurgenex@hotmail.com>
    Re: remove one element with splice <yankeeinexile@gmail.com>
        Digest Administrivia (Last modified: 6 Apr 01) (Perl-Users-Digest Admin)

----------------------------------------------------------------------

Date: Wed, 11 Nov 2009 21:52:16 +0100
From: "Peter J. Holzer" <hjp-usenet2@hjp.at>
Subject: Re: connect to localhost failed error with Mail::Sendmail on Windows
Message-Id: <slrnhfm901.3bv.hjp-usenet2@hrunkner.hjp.at>

On 2009-11-11 09:42, ++imanshu <himanshu.garg@gmail.com> wrote:
> On Nov 11, 4:14 am, Ben Morrow <b...@morrow.me.uk> wrote:
>> Quoth "Peter J. Holzer" <hjp-usen...@hjp.at>:
>> > On 2009-11-09 09:45, ++imanshu <himanshu.g...@gmail.com> wrote:
>> > > On Nov 8, 11:03 pm, smallpond <smallp...@juno.com> wrote:
>> > >> Installation instructions for Mail::Sendmail:
>>
>> > >> "At the top of Sendmail.pm, set your default SMTP server(s),
>> > >> unless you specify it with each message, or want to use the
>> > >> default (localhost)."
>>
>> > > yes I wrongly assumed smtp to be so simple that the module alone could
>> > > handle it without another server.
>>
>> > That doesn't make sense. A protocol specifies how two (or more) entities
>> > talk to each other. In the case of a client/server protocol like SMTP,
>> > how a client talks to a server. Since Mail::Sendmail implements an SMTP
>> > client (it is used to send mail, not to receive it), it needs an SMTP
>> > server to talk to.
>>
>> It's not a priori obvious that Mail::Sendmail can't (and shouldn't)
>> perform MX lookups and deliver the mail directly to the appropriate
>> mailhost.

I could answer that in that case it still needs a server, it just
determines the server from the recipient domain via DNS instead of from
local configuration. But that would be nitpicking.

Mail::Sendmail should be able to talk to an MX if you can configure that
locally (which might make sense if you just want to send mail to a fixed
address), but in general this isn't useful. It wants a local submission
server which can then handle all the hard parts of mail transport,
especially queueing and retries after temporary failures.

>> OTOH, I would say anyone who *doesn't* know this (and why)
>> should not be writing programs which send mail...
>
> Thanks for the replies. The beating is well deserved :D

It wasn't meant as a beating. I was just puzzled how somebody who
obviously knows enough about SMTP to recognize SMTP keywords could fail
to recognize that Mail::Sendmail implements an SMTP client (or, more
specifically, a SUBMISSION client) and therefore needs an SMTP server to
talk to.

	hp


------------------------------

Date: Wed, 11 Nov 2009 16:49:53 +0000
From: Ben Morrow <ben@morrow.me.uk>
Subject: Re: Exiting threads via signal
Message-Id: <hi6rs6-9vu.ln1@osiris.mauzo.dyndns.org>


Quoth Prince Al <timothy.hill@gmail.com>:
> 
> I am trying to write some code that creates threads to run data load
> jobs. There is also an extra thread created that watches for a
> specific file to be created. When this file is found, the watcher
> thread sends stop signals to all currently running threads. My code
> appears to exit correctly, but I cannot seem to get the subroutine of
> the SIG command to exit correctly.

Threads and signals don't play well together. Find an alternative IPC
mechanism, or use processes instead of threads (on a real Unix fork is
likely to be faster than threading, anyway).

Ben



------------------------------

Date: Wed, 11 Nov 2009 12:50:14 -0800
From: sln@netherlands.com
Subject: Re: Exiting threads via signal
Message-Id: <178mf5tfgt1ekb1ch1qu3tct9t3569gk5c@4ax.com>

On Wed, 11 Nov 2009 04:08:50 -0800 (PST), Prince Al <timothy.hill@gmail.com> wrote:

>Hi,
>
>I am trying to write some code that creates threads to run data load
>jobs. There is also an extra thread created that watches for a
>specific file to be created. When this file is found, the watcher
>thread sends stop signals to all currently running threads. My code
>appears to exit correctly, but I cannot seem to get the subroutine of
>the SIG command to exit correctly.
>
>We are running HP-UX and the version of Perl we have is 5.8.8 (with
>thread support obviously). A cut down version of my code is below.
>
>Thanks in advance for any help :)
>
>Cheers
>
>Tim
>

It looks like detach() is being called before $SIG{'STOP'} sub,
so try detaching in the handler itself.

Of course after 20 seconds, the thread exits on its own, therefore
the handler is invalid in that case.

Also, detach will need to be called on the thread if it is no longer
running. Put in a check for that in the watcher thread. This way, the
body of flock_test() can exit after an arbitrary amount of time.


Try this ...

>#!/opt/perl_5.8.8cu/bin/perl
>
>use strict;
>use warnings;
>use threads;
>
>my $system = "test";
>my $hard_stop_file = "/tmp/$system"."_hard.stop";
>

use strict;
use warnings;
use threads;

my $system = "test";
my $hard_stop_file = "$system"."_hard.stop";

if (-f $hard_stop_file) {
   unlink($hard_stop_file);
}

my $watcher_thread = threads->new(\&hard_stop_watcher);
$watcher_thread->detach();

foreach my $i (0..4) {
   threads->new(\&flock_test, $i);
}

while (scalar(threads->list()) > 0) {
   sleep 1;
}

sub flock_test {
   my $id = $_[0];
   print "starting $id\n";
   $SIG{'STOP'} = sub {
      print "SIG_STOP recieved: $id\n";
      threads->detach();
      threads->exit();
   };
   sleep 1 while(1);  # this will always have to finish, ie: sleep(1) in this case
                      # but you can comment it out, is_running() below will detach it.
}

sub hard_stop_watcher {
   while ( !-f $hard_stop_file) {
      sleep 1;
   }

   print "$hard_stop_file found...\n";

   foreach my $thr (threads->list) {
      print "killing $thr\n";
      print " running? = '", $thr->is_running(),"'\n";

      if ($thr->is_running()) { # this is not atomic
	      $thr->kill('STOP');
      } else {
              $thr->detach();
      }
   }

   threads->exit();
}

__END__

-sln


------------------------------

Date: Wed, 11 Nov 2009 11:58:58 -0500
From: monkeys paw <user@example.net>
Subject: remove one element with splice
Message-Id: <TNadndeZdeyjcGfXnZ2dnUVZ_uWdnZ2d@insightbb.com>

I am trying to remove array elements where age is > 42.
I think splice is the function to use but i'm having
a problem getting it to work right. Here is the code,
what i would like array to equal at the end is just
two elements, bobbi and steve.

my @array = (

{ name => 'steve', age => 42 },
{ name => 'bobbi', age => 33 },
{ name => 'kate', age => 55 },
{ name => 'bob', age => 58 },

);

for my $i (0 .. $#array) {
   if ($array[$i]->{age} > 42) {
       print "Removing $array[$i]->{name}\n";
       splice(@array, $i, 1);
   }
}
use Data::Dumper;die 'DDDEBUG' .  Dumper(\@array);

Here is the output i get though:

Removing kate
DDDEBUG$VAR1 = [
           {
             'name' => 'steve',
             'age' => 42
           },
           {
             'name' => 'bobbi',
             'age' => 33
           },
           {
             'name' => 'bob',
             'age' => 58
           },
           {}
         ];


------------------------------

Date: Wed, 11 Nov 2009 17:25:32 +0000
From: bugbear <bugbear@trim_papermule.co.uk_trim>
Subject: Re: remove one element with splice
Message-Id: <E6idnSCNm5kRbmfXnZ2dnUVZ8mdi4p2d@brightview.co.uk>

monkeys paw wrote:
> I am trying to remove array elements where age is > 42.
> I think splice is the function to use but i'm having
> a problem getting it to work right. Here is the code,
> what i would like array to equal at the end is just
> two elements, bobbi and steve.

Editing the array you're iterating over is always
exciting.

I would use "grep" to make a new array, and assign
that over the top of the original array if you want to.

   BugBear


------------------------------

Date: Wed, 11 Nov 2009 17:28:41 +0000 (UTC)
From: Willem <willem@stack.nl>
Subject: Re: remove one element with splice
Message-Id: <slrnhflt29.139a.willem@turtle.stack.nl>

monkeys paw wrote:
) I am trying to remove array elements where age is > 42.
) I think splice is the function to use ...

No, you want grep:

 @array = grep { $_->{age} <= 42 } @array;


SaSW, Willem
-- 
Disclaimer: I am in no way responsible for any of the statements
            made in the above text. For all I know I might be
            drugged or something..
            No I'm not paranoid. You all think I'm paranoid, don't you !
#EOT


------------------------------

Date: Wed, 11 Nov 2009 17:22:08 +0000
From: Ben Morrow <ben@morrow.me.uk>
Subject: Re: remove one element with splice
Message-Id: <0f8rs6-6731.ln1@osiris.mauzo.dyndns.org>


Quoth monkeys paw <user@example.net>:
> I am trying to remove array elements where age is > 42.
> I think splice is the function to use but i'm having
> a problem getting it to work right. Here is the code,
> what i would like array to equal at the end is just
> two elements, bobbi and steve.
> 
> my @array = (
> 
> { name => 'steve', age => 42 },
> { name => 'bobbi', age => 33 },
> { name => 'kate', age => 55 },
> { name => 'bob', age => 58 },
> 
> );
> 
> for my $i (0 .. $#array) {
>    if ($array[$i]->{age} > 42) {
>        print "Removing $array[$i]->{name}\n";
>        splice(@array, $i, 1);
>    }
> }

You are iterating over array indices while changing the indices of the
elements. When you start the loop with $i=2, the array looks like

    {name => 'steve', age => 42},
    {name => 'bobbi,  age => 33},
    {name => 'kate',  age => 55},
    {name => 'bob',   age => 58},

then you do the splice, and the array looks like

    {name => 'steve', age => 42},
    {name => 'bobbi,  age => 33},
    {name => 'bob',   age => 58},

then you move on to $i=3 and the element $array[3] is auto-viv'd to a
hashref by the expression

    $array[$i]->{age}

I would just use grep: that's what it's there for:

    @array = grep { $_->{age} <= 42 } @array;

though if you insist on modifying the array in-place you could use
something like

    my $i = 0;
    while ($i < @array) {
        if ($array[$i]{age} > 42) {
            splice @array, $i, 1;
        }
        else {
            $i++;
        }
    }

Ben



------------------------------

Date: Wed, 11 Nov 2009 10:24:29 -0800
From: Jürgen Exner <jurgenex@hotmail.com>
Subject: Re: remove one element with splice
Message-Id: <2evlf5dom9e3fkn79asvn97q150ijbd6p5@4ax.com>

monkeys paw <user@example.net> wrote:
>I am trying to remove array elements where age is > 42.
>I think splice is the function to use 

As mentioned just 2 days ago: most people would probably just use grep()
instead of rolling their own code.

>but i'm having
>a problem getting it to work right. Here is the code,
>what i would like array to equal at the end is just
>two elements, bobbi and steve.
>
>my @array = (
>
>{ name => 'steve', age => 42 },
>{ name => 'bobbi', age => 33 },
>{ name => 'kate', age => 55 },
>{ name => 'bob', age => 58 },
>
>);
>
>for my $i (0 .. $#array) {
>   if ($array[$i]->{age} > 42) {
>       print "Removing $array[$i]->{name}\n";
>       splice(@array, $i, 1);
>   }
>}

Bad, bad idea: you are modifying the array while iterating over the
indices of the original(!!) array.
It will get you a "Use of uninitialized value in numeric gt (>)". 

If you insist on rolling your own code then at the very least start from
deleting from the end.

Of course with grep() it is a one-liner:

	@array = grep $_ ->{age} <= 42, @array;

jue


------------------------------

Date: Wed, 11 Nov 2009 14:26:43 -0500
From: monkeys paw <user@example.net>
Subject: Re: remove one element with splice
Message-Id: <GvCdnTTqlJpDkmbXnZ2dnUVZ_j5i4p2d@insightbb.com>

OK, i think i tried to oversimplify the code.
What is actually determining whether an array element
stays or gets removed is the return of a function call.

So i would be

for my $i (0 .. $#array) {
     if (is_something_true()) {
        # Remove this array element
     }
}

I don't think grep can be used in this case. Would i necessarily
need a second array to do this?


> monkeys paw <user@example.net> wrote:
>> I am trying to remove array elements where age is > 42.
>> I think splice is the function to use 
> 
> As mentioned just 2 days ago: most people would probably just use grep()
> instead of rolling their own code.
> 
>> but i'm having
>> a problem getting it to work right. Here is the code,
>> what i would like array to equal at the end is just
>> two elements, bobbi and steve.
>>
>> my @array = (
>>
>> { name => 'steve', age => 42 },
>> { name => 'bobbi', age => 33 },
>> { name => 'kate', age => 55 },
>> { name => 'bob', age => 58 },
>>
>> );
>>
>> for my $i (0 .. $#array) {
>>   if ($array[$i]->{age} > 42) {
>>       print "Removing $array[$i]->{name}\n";
>>       splice(@array, $i, 1);
>>   }
>> }
> 
> Bad, bad idea: you are modifying the array while iterating over the
> indices of the original(!!) array.
> It will get you a "Use of uninitialized value in numeric gt (>)". 
> 
> If you insist on rolling your own code then at the very least start from
> deleting from the end.
> 
> Of course with grep() it is a one-liner:
> 
> 	@array = grep $_ ->{age} <= 42, @array;
> 
> jue


------------------------------

Date: Wed, 11 Nov 2009 14:35:47 -0500
From: monkeys paw <user@example.net>
Subject: Re: remove one element with splice
Message-Id: <Fomdnf9f3M9jjGbXnZ2dnUVZ_ixi4p2d@insightbb.com>

monkeys paw wrote:
> OK, i think i tried to oversimplify the code.
> What is actually determining whether an array element
> stays or gets removed is the return of a function call.
> 
> So i would be
> 
> for my $i (0 .. $#array) {
>     if (is_something_true()) {

CORRECTION:
      if (is_something_true($array[$i])) {

>        # Remove this array element
>     }
> }
> 
> I don't think grep can be used in this case. Would i necessarily
> need a second array to do this?
> 
> 
>> monkeys paw <user@example.net> wrote:
>>> I am trying to remove array elements where age is > 42.
>>> I think splice is the function to use 
>>
>> As mentioned just 2 days ago: most people would probably just use grep()
>> instead of rolling their own code.
>>
>>> but i'm having
>>> a problem getting it to work right. Here is the code,
>>> what i would like array to equal at the end is just
>>> two elements, bobbi and steve.
>>>
>>> my @array = (
>>>
>>> { name => 'steve', age => 42 },
>>> { name => 'bobbi', age => 33 },
>>> { name => 'kate', age => 55 },
>>> { name => 'bob', age => 58 },
>>>
>>> );
>>>
>>> for my $i (0 .. $#array) {
>>>   if ($array[$i]->{age} > 42) {
>>>       print "Removing $array[$i]->{name}\n";
>>>       splice(@array, $i, 1);
>>>   }
>>> }
>>
>> Bad, bad idea: you are modifying the array while iterating over the
>> indices of the original(!!) array.
>> It will get you a "Use of uninitialized value in numeric gt (>)".
>> If you insist on rolling your own code then at the very least start from
>> deleting from the end.
>>
>> Of course with grep() it is a one-liner:
>>
>>     @array = grep $_ ->{age} <= 42, @array;
>>
>> jue


------------------------------

Date: 11 Nov 2009 19:42:37 GMT
From: Glenn Jackman <glennj@ncf.ca>
Subject: Re: remove one element with splice
Message-Id: <slrnhfm4tf.k87.glennj@smeagol.ncf.ca>

At 2009-11-11 02:35PM, "monkeys paw" wrote:
>  monkeys paw wrote:
> > OK, i think i tried to oversimplify the code.
> > What is actually determining whether an array element
> > stays or gets removed is the return of a function call.
> > 
> > So i would be
> > 
> > for my $i (0 .. $#array) {
>        if (is_something_true($array[$i])) {
> >        # Remove this array element
> >     }
> > }

So, you'd want:

    @array = grep { ! is_something_true($_) } @array;

-- 
Glenn Jackman
    Write a wise saying and your name will live forever. -- Anonymous


------------------------------

Date: Wed, 11 Nov 2009 19:44:07 +0000 (UTC)
From: Willem <willem@stack.nl>
Subject: Re: remove one element with splice
Message-Id: <slrnhfm507.15tk.willem@turtle.stack.nl>

monkeys paw wrote:
) monkeys paw wrote:
)> OK, i think i tried to oversimplify the code.
)> What is actually determining whether an array element
)> stays or gets removed is the return of a function call.
)> 
)> So i would be
)> 
)> for my $i (0 .. $#array) {
)>     if (is_something_true()) {
)
) CORRECTION:
)       if (is_something_true($array[$i])) {
)
)>        # Remove this array element
)>     }
)> }
)> 
)> I don't think grep can be used in this case. Would i necessarily
)> need a second array to do this?

 @array = grep { not is_something_true($_) } @array;


SaSW, Willem
-- 
Disclaimer: I am in no way responsible for any of the statements
            made in the above text. For all I know I might be
            drugged or something..
            No I'm not paranoid. You all think I'm paranoid, don't you !
#EOT


------------------------------

Date: Wed, 11 Nov 2009 13:50:45 -0600
From: Lawrence Statton <yankeeinexile@gmail.com>
Subject: Re: remove one element with splice
Message-Id: <m1pr7ou9gq.fsf@mac.lan>

monkeys paw <user@example.net> writes:

> monkeys paw wrote:
>> OK, i think i tried to oversimplify the code.
>> What is actually determining whether an array element
>> stays or gets removed is the return of a function call.

No difference ... put the function call inside the grep conditional

>>
>> So i would be
>>
>> for my $i (0 .. $#array) {
>      if (is_something_true($array[$i])) {
>>        # Remove this array element
>>     }
>> }
>>

No.  Removing an array element while iterating across the array will
ALWAYS cause you grief.  

>> I don't think grep can be used in this case. Would i necessarily
>> need a second array to do this?

Yes, grep can be used in this case.

No, you don't need a second array.


#!/usr/bin/perl
use strict;
use warnings;
use Data::Dumper qw/Dumper/;

sub some_other_function {
  my $datum = shift;
  return $datum->{age} <= 42; # or whatever more complex test you need
}


my @array = (
	     { name => 'steve', age => 42 },
	     { name => 'bobbi', age => 33 },
	     { name => 'kate', age => 55 },
	     { name => 'bob', age => 58 },
);

@array = grep some_other_function($_), @array;

print Dumper \@array;



------------------------------

Date: Wed, 11 Nov 2009 11:55:38 -0800
From: Jürgen Exner <jurgenex@hotmail.com>
Subject: Re: remove one element with splice
Message-Id: <ob5mf5h3jlti32do0ameosaoevra5u97u2@4ax.com>

monkeys paw <user@example.net> wrote:
>monkeys paw wrote:
>> OK, i think i tried to oversimplify the code.
>> What is actually determining whether an array element
>> stays or gets removed is the return of a function call.

Yes, so what? Did you read the man page for grep()? grep() accepts any
expression or code block to determine if to keep or reject an element. 
Where do you see a problem?

>> So i would be
>> 
>> for my $i (0 .. $#array) {
>>     if (is_something_true()) {
>
>CORRECTION:
>      if (is_something_true($array[$i])) {
>
>>        # Remove this array element

@array = grep !is_something_true($_) @array;

>> I don't think grep can be used in this case. 

Why not?

>> Would i necessarily
>> need a second array to do this?

Only as a temporary result, invisible to the programmer.

>>> Of course with grep() it is a one-liner:
>>>
>>>     @array = grep $_ ->{age} <= 42, @array;

Where did you see a second (named) array in my code?

jue


------------------------------

Date: Wed, 11 Nov 2009 12:32:40 -0800
From: Jürgen Exner <jurgenex@hotmail.com>
Subject: Re: remove one element with splice
Message-Id: <qn7mf55tf7cspuov2h6dgg1sjg7g4i43hb@4ax.com>

Lawrence Statton <yankeeinexile@gmail.com> wrote:
>No.  Removing an array element while iterating across the array will
>ALWAYS cause you grief.  

Unless you iterate from the end forward or use a while() loop with an
if() clause as shown by Ben. But it sure is a pain in the extended rear
nevertheless.

jue


------------------------------

Date: Wed, 11 Nov 2009 14:35:57 -0600
From: Lawrence Statton <yankeeinexile@gmail.com>
Subject: Re: remove one element with splice
Message-Id: <m1eio4u7de.fsf@mac.lan>

Jürgen Exner <jurgenex@hotmail.com> writes:

> Unless you iterate from the end forward or use a while() loop with an
> if() clause as shown by Ben. But it sure is a pain in the extended rear
> nevertheless.

I reject your reality and replace it with my own :)

I assert that either of these acrobatic feats through hoops constitutes
"grief" :) :)


------------------------------

Date: 6 Apr 2001 21:33:47 GMT (Last modified)
From: Perl-Users-Request@ruby.oce.orst.edu (Perl-Users-Digest Admin) 
Subject: Digest Administrivia (Last modified: 6 Apr 01)
Message-Id: <null>


Administrivia:

To submit articles to comp.lang.perl.announce, send your article to
clpa@perl.com.

Back issues are available via anonymous ftp from
ftp://cil-www.oce.orst.edu/pub/perl/old-digests. 

#For other requests pertaining to the digest, send mail to
#perl-users-request@ruby.oce.orst.edu. Do not waste your time or mine
#sending perl questions to the -request address, I don't have time to
#answer them even if I did know the answer.


------------------------------
End of Perl-Users Digest V11 Issue 2671
***************************************


home help back first fref pref prev next nref lref last post