[22996] in Perl-Users-Digest

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

Perl-Users Digest, Issue: 5216 Volume: 10

daemon@ATHENA.MIT.EDU (Perl-Users Digest)
Fri Jul 11 18:10:38 2003

Date: Fri, 11 Jul 2003 15:10:11 -0700 (PDT)
From: Perl-Users Digest <Perl-Users-Request@ruby.OCE.ORST.EDU>
To: Perl-Users@ruby.OCE.ORST.EDU (Perl-Users Digest)

Perl-Users Digest           Fri, 11 Jul 2003     Volume: 10 Number: 5216

Today's topics:
        Perl subroutine question <r@randr.com>
    Re: Perl subroutine question (Greg Bacon)
    Re: Perl subroutine question <r@randr.com>
    Re: Perl subroutine question (Greg Bacon)
    Re: Q- Empirical usable upper limit on hash array numbe (Carlton Brown)
    Re: Simple: How to include file? <ericw@nospam.ku.edu>
    Re: transform 3*0.0 into 0.0, 0.0, 0.0 nobull@mail.com
        uninitialized value in pattern match (gilgames)
    Re: uninitialized value in pattern match <mbudash@sonic.net>
        Digest Administrivia (Last modified: 6 Apr 01) (Perl-Users-Digest Admin)

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

Date: Fri, 11 Jul 2003 16:54:43 GMT
From: "Thomas" <r@randr.com>
Subject: Perl subroutine question
Message-Id: <nZBPa.345$Y92.283@nwrdny01.gnilink.net>

I am having trouble passing a socket to a subroutine.
I get "readline() on unopened file" error.

Here is the code: (I hope you can tell me what I am doing wrong)

#!c:\perl\bin\perl
use warnings;
use strict;
use subs;
use IO::Socket;

my $port = shift || 7112;
if ( $port =~ /\D/ ) { $port = getservbyname($port, 'tcp') }
die "No port $port" unless $port;

my $server = IO::Socket::INET->new(LocalPort => $port,
                                  Listen => SOMAXCONN) ||
                                  die "Server couldn't start $!";

print "Server start at $port\n";
while ( my $clients = $server->accept()) {
      new_client(*clients);   # pass filehandle as glob
}

sub new_client  {
      *C = shift;      # get the glob filehandle?
     print "Accepted new client\n";
     while (my $chatter = <C> ) {
       chomp($chatter);
       print C "$chatter\n";
     }
  close C;
}





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

Date: Fri, 11 Jul 2003 18:21:52 -0000
From: gbacon@hiwaay.net (Greg Bacon)
Subject: Re: Perl subroutine question
Message-Id: <vgu020n2bei9a0@corp.supernews.com>

In article <nZBPa.345$Y92.283@nwrdny01.gnilink.net>,
    Thomas <r@randr.com> wrote:

: print "Server start at $port\n";
: while ( my $clients = $server->accept()) {
:       new_client(*clients);   # pass filehandle as glob
: }

Globs look at symbol table variables (i.e., globals), but $clients is
a lexical.  See code below.

Hope this helps,
Greg

#! /usr/local/bin/perl

use warnings;
use strict;

use Socket;
use IO::Socket;

sub peer {
    my $s = shift;

    my $sa = $s->peername;
    my($port,$iaddr) = sockaddr_in($sa);

    my $name = gethostbyaddr $iaddr, AF_INET;
    my $ip   = inet_ntoa $iaddr;

    ($name, $ip);
}

sub new_client  {
    my $c = shift;
    my($name,$ip) = peer $c;
    my $fd = fileno $c;

    print "Accepted new client: fd $fd, $name [$ip]\n";

    while (1) {
        my $status;
        my $ch;

        $status = sysread $c, $ch, 1;
        if ($status == 0) {
            last;
        }
        elsif (not defined $status) {
            warn "$0: sysread fd $fd ($name [$ip]): $!";
            last;
        }
        elsif ($status != 1) {
            warn "$0: sysread fd $fd ($name [$ip]) got $status bytes";
        }

        $status = syswrite $c, $ch, 1;
        if (not defined $status) {
            warn "$0: syswrite fd $fd ($name [$ip]): $!";
            last;
        }
        elsif ($status != 1) {
            warn "$0: syswrite fd $fd ($name [$ip]) sent $status bytes";
        }
    }

    close $c or warn "$0: close client fd ($name [$ip]): $!";
}

## main
my $port = shift || 7112;
if ($port =~ /\D/) {
    $port = getservbyname($port, 'tcp');
}
die "$0: No port $port" unless $port;

my $server = IO::Socket::INET->new(
    LocalPort => $port,
    Listen => SOMAXCONN,
);
die "$0: Server couldn't start: $!" unless $server;

print "Server start at $port\n";

while (1) {
    my $client = $server->accept;
    die "$0: accept: $!" unless defined $client;

    new_client $client;
}
-- 
Like one who takes a dog by the ears
  Is he who passes by and meddles with strife not belonging to him.
    -- Proverbs 26:17


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

Date: Fri, 11 Jul 2003 19:02:40 GMT
From: "Thomas" <r@randr.com>
Subject: Re: Perl subroutine question
Message-Id: <kRDPa.48$3G5.13@nwrdny03.gnilink.net>

Thank you Greg.
See below:
I had a scoping issue.

"Greg Bacon" <gbacon@hiwaay.net> wrote in message
news:vgu020n2bei9a0@corp.supernews.com...
> In article <nZBPa.345$Y92.283@nwrdny01.gnilink.net>,
>     Thomas <r@randr.com> wrote:
>
> : print "Server start at $port\n";
> : while ( my $clients = $server->accept()) {
> :       new_client(*clients);   # pass filehandle as glob
> : }
>
> Globs look at symbol table variables (i.e., globals), but $clients is
> a lexical.  See code below.
>
> Hope this helps,
> Greg
>
> #! /usr/local/bin/perl
>
> use warnings;
> use strict;
>
> use Socket;
> use IO::Socket;
>
> sub peer {
>     my $s = shift;
>
>     my $sa = $s->peername;
>     my($port,$iaddr) = sockaddr_in($sa);
>
>     my $name = gethostbyaddr $iaddr, AF_INET;
>     my $ip   = inet_ntoa $iaddr;
>
>     ($name, $ip);
> }
>
> sub new_client  {
>     my $c = shift;
>     my($name,$ip) = peer $c;
>     my $fd = fileno $c;
>
>     print "Accepted new client: fd $fd, $name [$ip]\n";
>
>     while (1) {
>         my $status;
>         my $ch;
>
>         $status = sysread $c, $ch, 1;
>         if ($status == 0) {
>             last;
>         }
>         elsif (not defined $status) {
>             warn "$0: sysread fd $fd ($name [$ip]): $!";
>             last;
>         }
>         elsif ($status != 1) {
>             warn "$0: sysread fd $fd ($name [$ip]) got $status bytes";
>         }
>
>         $status = syswrite $c, $ch, 1;
>         if (not defined $status) {
>             warn "$0: syswrite fd $fd ($name [$ip]): $!";
>             last;
>         }
>         elsif ($status != 1) {
>             warn "$0: syswrite fd $fd ($name [$ip]) sent $status bytes";
>         }
>     }
>
>     close $c or warn "$0: close client fd ($name [$ip]): $!";
> }
>
> ## main
> my $port = shift || 7112;
> if ($port =~ /\D/) {
>     $port = getservbyname($port, 'tcp');
> }
> die "$0: No port $port" unless $port;
>
> my $server = IO::Socket::INET->new(
>     LocalPort => $port,
>     Listen => SOMAXCONN,
> );
> die "$0: Server couldn't start: $!" unless $server;
>
> print "Server start at $port\n";
>
> while (1) {
>     my $client = $server->accept;
>     die "$0: accept: $!" unless defined $client;

In my code I had: ($client is scoped wrong)
while ( my $clients = $server->accept()) {
      new_client(*clients);   # pass filehandle as glob
}

I should have changed two things: the scope of $client in the while()
move to

my $clients;
while(....

to make the code like this:

my $clients;
while ( $clients = $server->accept()) {
      new_client($clients);   # pass filehandle as glob
}

Next I will post the threaded version.
I have to remember to dup the socket.

>
>     new_client $client;
> }
> --
> Like one who takes a dog by the ears
>   Is he who passes by and meddles with strife not belonging to him.
>     -- Proverbs 26:17
Glory to the Lord.
May he keep our feet
on the path of righteousness,
were everything is easy
and people are always smiling.




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

Date: Fri, 11 Jul 2003 20:19:38 -0000
From: gbacon@hiwaay.net (Greg Bacon)
Subject: Re: Perl subroutine question
Message-Id: <vgu6uqc22eqj37@corp.supernews.com>

In article <kRDPa.48$3G5.13@nwrdny03.gnilink.net>,
    Thomas <r@randr.com> wrote:

: [...]
: 
: In my code I had: ($client is scoped wrong)
: while ( my $clients = $server->accept()) {
:       new_client(*clients);   # pass filehandle as glob
: }

There's a scoping issue, but not the one you think.  Typeglobs only
grab symbol table variables:

    % cat try
    #! /usr/local/bin/perl

    use strict;
    use warnings;

    use Data::Dumper;

    sub show_glob_contents {
        my $s = shift;

        print $$s, "\n";
    }

    $main::foo = 'global';
    my $foo    = 'lexical';

    show_glob_contents *foo;
    % ./try
    global

: I should have changed two things: the scope of $client in the while()
: move to
: 
: my $clients;
: while(....

No, that doesn't matter.

: to make the code like this:
: 
: my $clients;
: while ( $clients = $server->accept()) {
:       new_client($clients);   # pass filehandle as glob
: }

Note that you changed the * to $.  That's a key difference because now
you're passing something other than the undefined value.

: Next I will post the threaded version.
: I have to remember to dup the socket.

fork, man!  fork! :-)

Greg
-- 
The competent programmer is fully aware of the strictly limited size of his
own skull; therefore he approaches the programming task in full humility,
and among other things he avoids clever tricks like the plague.
    -- Edsger Dijkstra


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

Date: 11 Jul 2003 09:07:21 -0700
From: carltonbrown@hotmail.com (Carlton Brown)
Subject: Re: Q- Empirical usable upper limit on hash array number of elements
Message-Id: <aa611a32.0307110807.6fdfe447@posting.google.com>

tiltonj@erols.com (Jay Tilton) wrote in message news:<3f0e050d.85101506@news.erols.com>...
> carltonbrown@hotmail.com (Carlton Brown) wrote:
> 
> : All the docs (that I've read) say that there is no limit on the size
> : of a hash in PERL.
>                ^^^^
> See perlfaq1, What's the difference between "perl" and "Perl"?

After remarking on some trivial differences, it says:

"...it doesn't matter much, especially if all you're doing is hearing
someone talk about the language; case is hard to distinguish aurally."

Glad we've cleared up that important point. 

> : But in my experience, when documentation says "no
> : limit" on a spec, it means the limit lies outside the boundaries of
> : what anyone has tested.
> 
> Or what anybody has been adequately capable of testing.  Whomping up
> some test code is trivial enough.  Give it a shot and see what
> happens.

So far, good results with 2 million records, although it takes some
time just to read the data in.  That's why I'm trying to see if
anybody has any experience about what may occur when I get into the
neighborhood of 100 million elements or greater.

> Allocating space for the hash will give a better idea how much memory
> will be consumed.
> 
>    keys(%hash) = 100e6;
> 
> Pre-allocating the space would also eliminate the speed hit from
> perl's need to dynamically resize the hash as it grows.

I'll try anything that may help it run faster.  Thanks for the tip.

> As for the speed of the hash lookup itself, under ideal circumstances
> it would be independent of the number of elements.  Whether ideal
> circumstances exist depends not only on the hashing function but on
> the data as well.  Others' experiences with big hashes may not be
> applicable, since their data will be different from yours.

Right, that's why I characterized the estimate as a type of "Fermi
Problem" and why I'm asking if anyone has had any experience in this
ballpark.  I appreciate the tip about pre-allocating the space, and
I'll take the rest of your post as a "no, I've never worked with
hashes of this magnitude" (unless I've somehow mis-read what you
posted).


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

Date: Fri, 11 Jul 2003 16:03:26 GMT
From: Eric Wilhelm <ericw@nospam.ku.edu>
Subject: Re: Simple: How to include file?
Message-Id: <pan.2003.07.11.10.58.51.84078.19056@nospam.ku.edu>

On Fri, 11 Jul 2003 08:56:40 -0500, Greg Bacon wrote:

> In article <20030711132522.1D889943.NOFFLE@orion.local>,
>     Tvrtko Ursulin  <tvrtko@croadria.com> wrote:
> 
> : I am new to perl (from C) and cannot figure how to include a simple :
> custom file in the main program?
> :
> : I need something like:
> :
> : our $default_value = 'xyz';
> :
> : in my include.ph, and a way to include this in main.pl so that :
> $default_value can normally be used. Can it be done?
> 
> You could do it quickly with
> 
>     % cat try
>     #! /usr/local/bin/perl
> 
>     require "foo.pl";
> 
>     print $default_value, "\n";
>     % cat foo.pl
>     $default_value = 'xyz';
>     % ./try
>     xyz
> 
> Depending on the nature of your project, you probably don't want to do
> it that way, though, but want instead to write a module.

I second that

There is also:
do "foo.pl"

which eases some of the restrictions (and can be called multiple times),
but makes debugging more difficult if there is something wrong with foo.pl
(you won't get any compiler warnings about the file.)

This is a very duct-tape and twine approach (doing it with a require is
not much better.)  If you are working on something that is going to grow,
definitely avoid it (feeling the pain right now myself.)


--Eric


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

Date: 11 Jul 2003 13:05:28 -0700
From: nobull@mail.com
Subject: Re: transform 3*0.0 into 0.0, 0.0, 0.0
Message-Id: <4dafc536.0307111205.2d0bd038@posting.google.com>

CM <starobs99@yahoo.com> wrote in message news:<beeump$4dgt0$1@ID-189674.news.dfncis.de>...
> Brian McCauley wrote:
> > CM <starobs99@yahoo.com> writes:
> > 
> > 
> >>Thanks to all, I finaly adopted the following program (just for people
> >>who could have a similar question) :
> >>
> >>--------------------------------------------------------------------
> >>#!/usr/bin/perl
> > 
> > 
> > Always:
> >   use strict;
> >   use warnings;
> > 
> > Do not wait for your failure to do so to cause you pain and
> > embarassement, do it now.
> 
> OK. So I put these two commands on the top of the file?

Yes.
 

 >># Transform e.g. 3*4.5 into 4.5 4.5 4.5
> >># Transform , into _space_
> >># Usage: removestars.pl input.dat > output.dat
> >>#
> >>open(INPUT, "<$ARGV[0]") || die "Cannot open $ARGV[0]";
> > 
> > 
> > Don't waste your time.  Just use the magic ARGV filehandle.
> > 
> 
> How?

while (<ARGV>) {
   # Do things
}

You can even abreviate it to 

while (<>) {
   # Do things
}

The ARGV file handle is magicially each of the files listed on the
command line in turn.

> >>while (<INPUT>)
> >>   {
> >>     $a =$_;
> > 
> > 
> > Either use a named variable or use the default variable $_.
> > 
> > If you do use a named variable make it lexically scoped.
> > 
> > Don't use $a
> 
> What do you mean?

The one can think of special $_ variable is 'the current record'.  

If you are doing several simple operations on a record letting it be
in $_ rather than a named variable is faster to write and faster to
run,

while (<>) {
  s/whatever/whatever else};
} 

> Avoiding the use of $a will turn the program to look 
> like what?


 
> > 
> >>     $a =~ s/(\d+)\*(\S+)(,)/print "$2 " for 1 .. $1/e;
> >>     $a =~ s/(\d+)\*(\S+)($)/print "$2 " for 1 .. $1/e;
> > 
> > 
> > Eeek!  
> > 
> > You really should not be printing in the RHS of the s///
> 
> If I don't print, it doens't work...

And if you do, it doesn't either.

> I certainly missed something.

You are using s/// as a loop control structure with an RHS that has a
side effect of causing output to STDOUT.  This output goes to the
program's output stream there and then, ir does not get put back into
the appropriate string you are processing.

> > You should not use a for loop in a non-void context.
> 
> Well, and without loops?

I have no idea what you mean by that.  The RHS of s///e is evaluated
and the return value is used for something.  AFAIK it is undefined
what happens if you use a for loop in such a context.

> > Do you really want to rely on their being whitespace after the comma?
> 
> No,

So why did you make you regex insist that there was?

> > Do you really want only to consider a maximum of 2 * in a line?
> 
> No, it can be more...

So why did you only have two s/// niether having a /g ?  Each can at
most handle one instance.
> 
> > 
> >>     $a =~ s/,/ /g;
> >>     print $a;
> >>   }
> >>close(INPUT);
> >>--------------------------------------------------------------------
> > 
> > 
> > So did you really want...
> > 
> >  '1, 4*2,3, 4*5, 3*6'
> > 
> > ...to be reansformed into...
> > 
> >  '2,3 2,3 2,3 2,3 6 6 6 1 '
> > 
> > ...?
> > 
> > I would have thought you'd have wanted:
> > 
> >  '1 2 2 2 2 3 5 5 5 5 6 6 6' 
> 
> Yep exactly! But I laso want to remove any coma, even if no * around...
> In conclusion, could you send me a more perly code?

#!/usr/bin/perl
use strict;
use warnings;
while (<>) {
    # chomp() technically redundant here - but a good habit...
    chomp;

    # replace comma with space
    tr/,/ /;

    # Process the "*"s
    s/(\S+)\s*\*\s*(\S+)/"$1 " x $2/eg;

    # Normalise the whitespace
    s/^\s+//; # Strip leading whitespace
    s/\s+$//; # Strip trailing whitespace
    s/\s+/ /g; # All whitespace becomes a single space

    print "$_\n";
}
__END__


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

Date: 11 Jul 2003 11:56:03 -0700
From: gilgames@aol.com (gilgames)
Subject: uninitialized value in pattern match
Message-Id: <ef58b788.0307111056.341b91ca@posting.google.com>

#!/usr/bin/perl

use warnings;
use strict "refs";
use strict "subs";
use strict "vars";

our $netscape;

$netscape = ($ENV{HTTP_USER_AGENT} =~ /netscape/i ) ? 1 : 0;

################################
The compileing reports an 

uninitialized value in pattern match (m//) at a.pl line 10

In the real program I got about 20 similar errors if I use warnings
option. All I want here to check if the string "netscape" matches the
environment variable or not. I use the

our $netscape;

line to avoid the only once error, but if I omit it does not makes any
difference. Also the

use warnings 

line is itself is enough to generate the warning. 
Could somebody help me, what is wrong and how can I avoid such
messages.

I use perl v5.6.1 for MSWin32-386-Multithread 

Activestate version


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

Date: Fri, 11 Jul 2003 19:23:47 GMT
From: Michael Budash <mbudash@sonic.net>
Subject: Re: uninitialized value in pattern match
Message-Id: <mbudash-35EF58.12234611072003@typhoon.sonic.net>

In article <ef58b788.0307111056.341b91ca@posting.google.com>,
 gilgames@aol.com (gilgames) wrote:

> #!/usr/bin/perl
> 
> use warnings;
> use strict "refs";
> use strict "subs";
> use strict "vars";
> 
> our $netscape;
> 
> $netscape = ($ENV{HTTP_USER_AGENT} =~ /netscape/i ) ? 1 : 0;
> 
> ################################
> The compileing reports an 
> 
> uninitialized value in pattern match (m//) at a.pl line 10
> 
> In the real program I got about 20 similar errors if I use warnings
> option. All I want here to check if the string "netscape" matches the
> environment variable or not. I use the
> 
> our $netscape;
> 
> line to avoid the only once error, but if I omit it does not makes any
> difference. Also the
> 
> use warnings 
> 
> line is itself is enough to generate the warning. 
> Could somebody help me, what is wrong and how can I avoid such
> messages.
> 
> I use perl v5.6.1 for MSWin32-386-Multithread 
> 
> Activestate version

$netscape = (defined $ENV{HTTP_USER_AGENT} && $ENV{HTTP_USER_AGENT} =~ 
/netscape/i ) ? 1 : 0;

hth-
-- 
Michael Budash


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

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:

The Perl-Users Digest is a retransmission of the USENET newsgroup
comp.lang.perl.misc.  For subscription or unsubscription requests, send
the single line:

	subscribe perl-users
or:
	unsubscribe perl-users

to almanac@ruby.oce.orst.edu.  

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

To request back copies (available for a week or so), send your request
to almanac@ruby.oce.orst.edu with the command "send perl-users x.y",
where x is the volume number and y is the issue number.

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 V10 Issue 5216
***************************************


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