Re: test for real number

2001-06-01 Thread Piers Cawley

Paul [EMAIL PROTECTED] writes:
 BTW, this is another use of the same sort of trick as 
 
   { local $/ = undef;
 $file = FH; # slurp the whole file into $file
   }
 
 which is more efficient than
 
while(FH) { $file .= $_ }
 
 or 
 
$file = join '', FH;
 
 Still, I have a coworker who swears by the latter as more work, yes,
 but MUCH more readable in his opinion.

You know, I think I agree with your cow orker. The intent of the last
version is obvious. It'd be interesting to see profiling data from a
typical app that slurped in a whole file to see if the method of
slurping made a significant difference in the running time.

-- 
Piers Cawley
www.iterative-software.com




Re: test for real number

2001-06-01 Thread Paul


--- Piers Cawley [EMAIL PROTECTED] wrote:
 Paul [EMAIL PROTECTED] writes:
  BTW, this is another use of the same sort of trick as 
  
{ local $/ = undef;
  $file = FH; # slurp the whole file into $file
}
  
  which is more efficient than
  
 while(FH) { $file .= $_ }
  
  or 
  
 $file = join '', FH;
  
  Still, I have a coworker who swears by the latter as more work,
 yes,
  but MUCH more readable in his opinion.
 
 You know, I think I agree with your cow orker. The intent of the last
 version is obvious. It'd be interesting to see profiling data from a
 typical app that slurped in a whole file to see if the method of
 slurping made a significant difference in the running time.

Technically, I do, too.
IMHO, the program would *really* need to scream before the difference
in work would make enough difference to matter.

Unfortunately, I'm too much a gearhead not to use the neat toys, lol

__
Do You Yahoo!?
Get personalized email addresses from Yahoo! Mail - only $35 
a year!  http://personal.mail.yahoo.com/



Re: test for real number

2001-05-31 Thread Timothy Kimball


Randal L. Schwartz wrote
: For integers, you can narrow it down:
: 
: sub is_integer {
:   my $bad = 0;
:   local $SIG{__WARN__} = sub { $bad++ };
:   local $^W = 1;
:   my $guess = shift;
:   return $guess == int($guess) and not $bad;
: }

oops, precedence:

return $guess == int($guess)  not $bad;

Otherwise everything's an integer.

-- tdk



Re: test for real number

2001-05-31 Thread Paul


--- Randal L. Schwartz [EMAIL PROTECTED] wrote:
 
 The most comprehensive test for a real number is to let Perl
 do it itself:
 
 sub is_number {
   my $bad = 0;
   local $SIG{__WARN__} = sub { $bad++ };
   local $^W = 1;
   my $guess = shift;
   $guess += 0;
   return not $bad;
 }

This is lovely, and a great opportunity to show some new toys to
beginners, as well as some well-placed caveats. With your indulgence,
I'll try to break this down for the newbies. :)

 sub is_number {

Declaring the function modularizes the code for reuse, and declares a
block scope (which we'll be using).

   my $bad = 0;

my() makes $bad private to the function. It doesn't exist outside this
scope.

   local $SIG{__WARN__} = sub { $bad++ };

%SIG is the magical global Perl table in which you can put signal
handlers, so that you can do things like cleanup tempfiles if you get
an interrupt signal (someone hits CTRL-C while your script is running).
The __WARN__ tag represents the handler called when something triggers
a warning in perl, such as when -w is enabled at the command-line.

local() stores whatever was in the global value, and replaces it with
the new value, but at the end of the current scope will put the old
value back.  (You can't use my() on magical globals like %SIG and
expect them to work normally.) Be careful with this, though -- if you
call some other function from this scope, the value of $SIG{__WARN__}
will still be the routine that increments $bad, but it won't be able to
see the $bad we made with my()!

The handler function for warnings is here set to a simple anonymous
routine which increments $bad. (Note that both $bad and the routine go
away at the end of the scope.)

   local $^W = 1;

$^W is set be turning on the -w switch. It means warnings are active.
It's a magical Perl global, too, so we localize it here so that we can
set it on, but it won't affect anything outside this block (unless we
pass control out ourselves!), and will be automagically restored at the
end of the block.

   my $guess = shift;

We create another private variable called $guess, and populate it with
the shift operator, which removes element 0 from @_ (the list of
arguments passed to the function) and returns it. $guess is now the
function's first argument.

   $guess += 0;

By adding zero, we use $guess in a numeric context without actually
changing it's value. For any valid number format that Perl accepts,
this works and is silent, but if an invalid value is passed in (such as
foo, or nothing at all), it triggers a warning. The warning handler
istalled above increments $bad to indicate the error.

   return not $bad;

$bad is now a boolean value indicating whether or not an invalid value
was passed in. Since we want to know if the number was good, we
return the boolean inversion of the value of $bad.

 }

Now, calling is_number($val) will give you a boolean indicator of
whether  the value in $val is a perl number. =o)

It doesn't let you say 1,000 however, or 1_000 (which the Perl compiler
recognozes if it's a bareword, but not in quotes). Neither of these are
significant problems. If you wanted to strip such characters with s///
it would be trivial.



=
print Just another Perl Hacker\n; # edited for readability =o)
=
Real friends are those whom, when you inconvenience them, are bothered less by it than 
you are. -- me. =o) 
=
There are trivial truths and there are great Truths.
 The opposite of a trival truth is obviously false.
 The opposite of a great Truth is also true.  -- Neils Bohr

__
Do You Yahoo!?
Get personalized email addresses from Yahoo! Mail - only $35 
a year!  http://personal.mail.yahoo.com/



Re: test for real number

2001-05-31 Thread Randal L. Schwartz

 Paul == Paul  [EMAIL PROTECTED] writes:

Paul This is lovely, and a great opportunity to show some new toys to
Paul beginners, as well as some well-placed caveats. With your indulgence,
Paul I'll try to break this down for the newbies. :)

Great!

Paul Be careful with this, though -- if you call some other function
Paul from this scope, the value of $SIG{__WARN__} will still be the
Paul routine that increments $bad, but it won't be able to see the
Paul $bad we made with my()!

Wrong.  It'll still work!  It's a closure!

(now explain that... :)

-- 
Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095
[EMAIL PROTECTED] URL:http://www.stonehenge.com/merlyn/
Perl/Unix/security consulting, Technical writing, Comedy, etc. etc.
See PerlTraining.Stonehenge.com for onsite and open-enrollment Perl training!



Re: test for real number

2001-05-31 Thread Paul


--- Randal L. Schwartz [EMAIL PROTECTED] wrote:
  Paul == Paul  [EMAIL PROTECTED] writes:
 
 Paul This is lovely, and a great opportunity to show some new toys
 Paul to beginners, as well as some well-placed caveats. With your
 Paul indulgence, I'll try to break this down for the newbies. :)
 
 Great!
 
 Paul Be careful with this, though -- if you call some other function
 Paul from this scope, the value of $SIG{__WARN__} will still be the
 Paul routine that increments $bad, but it won't be able to see the
 Paul $bad we made with my()!
 
 Wrong.  It'll still work!  It's a closure!
 
 (now explain that... :)

LOL Better and better! 
I'm embarrased not to have thought of that, but that's why I love this
list. It keeps us all on our toes.
Though it still might not do what you expect in the other
function...especially if that function were counting on a __WARN__ hook
that had been globally setr before the call. Yes?

For the audience:
Perl's idiom for making private static variables is to put both the
global function definition and a my() variable in the same scope, but
don't put the var inside the function, like this:

  { # start a scope
my $static; # exists only in this scope 
sub func {  # global function
   print ++$static; # increments
}   # and of func
  } # end of external scope

Now, $static doesn't exist beyond the boudaries of that external scope,
but the global function references it, *so the variable doesn't die*
while the function exists. Someone remembers it, and it just so happens
that the someone is this global function. (If you read docs that talk
about deep-binding, think of this.)

So, back to Randall's code.

My declared a variable $bad using my, then assigned a closure (an
anonymous function) to the __WARN__ hook of the %SIG signal handler
table. %SIG is global, even though the value was swapped with local().
If you call out of the current function while the local() is still in
effect, the *global* value of $SIG{__WARN__} is still the anonymous
function. That closure was compiled in tha same scope as the my()
variable and accesses that variable, so the closure containes a
reference to the private variable $bad. That means it knows where to
look, even when not in that scope. Thus, this handler will still work,
even though you probably wouldn't want it to!

Moral: if you must use local() to accomplish something, be aware of
what it does, and that it can affect things outside that scope if you
are careless. Use my() when you can, BUT know that you can't on certain
magical variables (c.f. perldoc perlvar for some good examples. =o)

BTW, this is another use of the same sort of trick as 

  { local $/ = undef;
$file = FH; # slurp the whole file into $file
  }

which is more efficient than

   while(FH) { $file .= $_ }

or 

   $file = join '', FH;

Still, I have a coworker who swears by the latter as more work, yes,
but MUCH more readable in his opinion.

And now that I've digressed so... =o)

Aside from the divergence to an only marginally related topic, how'd I
do? List? Randall?

Finally, one last caveat: if you didn't understand the explanation,
it's either because I did it poorly, or because these are things beyond
your experience. Read the label: CAUTION! HANDLE WITH CARE.

Paul ;o]

__
Do You Yahoo!?
Get personalized email addresses from Yahoo! Mail - only $35 
a year!  http://personal.mail.yahoo.com/



advanced: closures (was Re: test for real number)

2001-05-31 Thread Jeff Pinyan

On May 31, Randal L. Schwartz said:

Paul Be careful with this, though -- if you call some other function
Paul from this scope, the value of $SIG{__WARN__} will still be the
Paul routine that increments $bad, but it won't be able to see the
Paul $bad we made with my()!

Wrong.  It'll still work!  It's a closure!

(now explain that... :)

What's a closure?  To understand this, first you have to understand a bit
about Perl's scoping.

There are two types of variables in Perl, package (global), and private
(lexical).  Package variables belong to a specific package:

  #!/usr/bin/perl

  $foo = 10;  # this is $foo in package main
  print $main::foo;  # this is how you explicitly access $foo in main

Private variables are declared with 'my', and belong to the block they are
defined in.  Because of this, they are called lexical -- you can see, in
the code, the exact scope of the variable.  Lexical variables do not
belong to any package.

  $foo = 10;
  {
my $foo = 20;
print $foo;# 20
print $main::foo;  # 10
  }
  print $foo;  # 10
  print $main::foo;# 10

The 'my $foo' is ONLY visible inside the block of code we defined it in.
That means that if a function is looking for a variable named $foo, it
might not see the 'my $foo' we created:

  # the 'my $foo' DOES NOT EXIST OUT HERE!
  sub bar { print $foo }

  $foo = 10;
  {
# 'my $foo' exists in here!
my $foo = 20;
bar();
  }

This program prints 10, not 20.  (This is a reason why it's good to send
the variables that a function will need to the function explicitly.)

[This is a short introduction to scope.  Please read the documentation
about my()[1], and Mark-Jason Dominus's Coping with Scoping[2] article.]

So, japhy, what's a closure?

A closure is an ANONYMOUS function (constructed via $x = sub { ... }) that
contains LEXICAL variables that have been defined in a scope visible to
the closure itself.

Guh?  Yeah, that's what I thought you'd say.

Here's a simple example:

  sub make_a_counter {
my $start = shift;
return sub { return $start++ }
  }

  my $start_at_5 = make_a_counter(5);

  print $start_at_5-() for 1 .. 10;

Ok, let's step back and see what this is doing:

  sub make_a_counter {
my $start = shift;
return sub { return $start++ }
  }

We're creating a function called make_a_counter(), and it takes some
number as its argument (we store that in the LEXICAL variable
$start).  Then, the function returns a reference to an anonymous function.

  $code_ref = sub { ... };

That code creates a reference to an anonymous function, and stores it in
$code_ref.  You can then call that function via

  $code_ref-(@args);
  # or
  $code_ref(@args);

Now, the anonymous function we create is:

  {
return $start++;
  }

Where did this $start variable get defined?  It was defined in the same
scope as this anonymous function... so that means $start is visible to
this anonymous function.

Now, we return a reference to the anonymous function.

  my $start_at_5 = make_a_counter(5);

Now we store that code reference in $start_at_5.

  print $start_at_5-() for 1 .. 10;

Here, we print the return value of the code reference 10 times.  The
output of this program is 5 6 7 8 9 10 11 12 13 14 (spaces added for
clarity).

But how did the function see $start?  We called the function OUTSIDE of
the scope where the code reference was created!

That is the magical effect of closures.  The code reference we created
used the lexical $start variable.  You see, lexical variables only
disappear (or, more technically, go out of scope) when their reference
count drops to 0 -- that means, when no other data structure is depending
on them to exist.  We've created a code reference that depends on $start
to stick around, so lovingly, it complies. :)

But, if $start stays around, what happens when we make TWO counters?!

  $x = make_a_counter(10);
  $y = make_a_counter(20);
  print $x-();
  print $y-();
  print $x-();

This prints (thank goodness!) 10 20 11.  But why?  First, let's try that
exercise WITHOUT using a lexical $start, but rather, using a global
variable.

  sub make_a_bad_counter {
$start = shift;
return sub { return $start++ }
  }

  $x = make_a_bad_counter(10);
  $y = make_a_bad_counter(20);
  print $x-();
  print $y-();
  print $x-();

This code prints 20 21 22.  The reason is because the code reference
returned by make_a_bad_counter() is just accessing the global $start
variable.  By the time we call $x-(), $start has been set to 20 by the
call of make_a_bad_counter(20).  Oh well. :(

So now we know that we have to use my() variables.  But why does the
my() variable hold different values for different counters?  Because
my() uses a new chunk of memory if the chunk of memory it expected to use
has not been freed.  How does that memory get freed?  By the variable's
reference count being 0 -- which isn't the case here, since we have a code
reference depending on that variable hanging around.

Here's a quick 

Re: advanced: closures (was Re: test for real number)

2001-05-31 Thread Jeff Pinyan

On May 31, Randal L. Schwartz said:

 Jeff == Jeff Pinyan [EMAIL PROTECTED] writes:

Jeff A closure is an ANONYMOUS function (constructed via $x = sub {
Jeff ... }) that contains LEXICAL variables that have been defined in
Jeff a scope visible to the closure itself.

leave out the word ANONYMOUS there.

ANONYMOUS and CLOSURE are orthogonal.

in BEGIN { my $x; sub foo { ... $x ... } }, foo is a CLOSURE
and is not ANONYMOUS.

I was scolded highly about that by Uri, back when my article[1] about
closures.  I, too, felt that foo() should be called a closure, but Uri
seemed so convincing.  If you're going to let me say that functions that
refer to lexical variables in such a fashion are closures, thank you, I
can return my normal sane self.


[1] Using Closures, by Jeff Pinyan, May 2000:
http://www.pobox.com/~japhy/articles/pm/2000-05.html

-- 
Jeff japhy Pinyan  [EMAIL PROTECTED]  http://www.pobox.com/~japhy/
Are you a Monk?  http://www.perlmonks.com/ http://forums.perlguru.com/
Perl Programmer at RiskMetrics Group, Inc. http://www.riskmetrics.com/
Acacia Fraternity, Rensselaer Chapter. Brother #734
**I no longer need a publisher for my Perl Regex book :)**




Re: advanced: closures (was Re: test for real number)

2001-05-31 Thread Randal L. Schwartz

 Jeff == Jeff Pinyan [EMAIL PROTECTED] writes:

Jeff I was scolded highly about that by Uri, back when my article[1] about
Jeff closures.  I, too, felt that foo() should be called a closure, but Uri
Jeff seemed so convincing.  If you're going to let me say that functions that
Jeff refer to lexical variables in such a fashion are closures, thank you, I
Jeff can return my normal sane self.

Uri is occasionally confused. :-)

There's a school of (mis-)thought that a coderef is a closure.  I
don't know how that got started, but it's wrong.  A closure is created
only when lexical variables go out of scope.  So a coderef without
external references is *not* a closure, and a named subroutine *can*
be a closure.

-- 
Randal L. Schwartz - Stonehenge Consulting Services, Inc. - +1 503 777 0095
[EMAIL PROTECTED] URL:http://www.stonehenge.com/merlyn/
Perl/Unix/security consulting, Technical writing, Comedy, etc. etc.
See PerlTraining.Stonehenge.com for onsite and open-enrollment Perl training!



Re: advanced: closures (was Re: test for real number)

2001-05-31 Thread Peter Scott

At 10:51 AM 5/31/01 -0700, Randal L. Schwartz wrote:
There's a school of (mis-)thought that a coderef is a closure.  I
don't know how that got started, but it's wrong.  A closure is created
only when lexical variables go out of scope.  So a coderef without
external references is *not* a closure, and a named subroutine *can*
be a closure.

Exactly.  To quote Damian Conway's Object-Oriented Programming with Perl, 
p. 56:

To hear some people talking about closures, you'd think they were 
discussing quantum physics, brain surgery, or VCR programming.  In reality, 
the idea of closures is incredibly simple and obvious, once the technical 
jargon has been stripped from it.

In Perl, a closure is just a subroutine that refers to one or more lexical 
variables declared outside the subroutine itself.

Perhaps we've exposed the beginners to enough of the seamy underbelly of 
Perl experts disagreeing among themselves, assuming any are still following 
this thread...

--
Peter Scott
Pacific Systems Design Technologies
http://www.perldebugged.com




Re: test for real number

2001-05-31 Thread Paul


List, I got this paragraph in recent correspondence with someone
off-list:

 I'm not so much discouraged as realize that I need a bit more time
 with Perl before I can understand most of what gets passed around in
 the list. I'll be back in a couple of months. From my short exposure,
 it seems that the beginners's list is not so much for true beginners
 as a forum for enthusiasts to get help from professionals.

It doesn't sound like any sort of recrimination, but I thought we might
want to keep it in mind. I for one am certainly guilty of going a
little too far into the deep end more often than necessary.

For those of you reading the list looking for help, please help *us* by
giving us code examples of what you're doing. There's no better way to
see at what level you're working (though you should note if you copied
it from a book or something. =o)

Paul

__
Do You Yahoo!?
Get personalized email addresses from Yahoo! Mail - only $35 
a year!  http://personal.mail.yahoo.com/



test for real number

2001-05-30 Thread mikemckee

Hi,
I'm new to the group and new to Perl and am very glad to have such a 
resource available. Hopefully someday I'll be on the giving end of the 
help list but for now I'm stumped. How do I test an input to see if it 
is a real number?  I have a situation something like:

  $input = STDIN;
chomp $input;

if (input equals a real number) {
 xx
}
else {

}
best, michael



Re: test for real number

2001-05-30 Thread Walt Mankowski

On Wed, May 30, 2001 at 01:56:40PM -0700, [EMAIL PROTECTED] wrote:
 How do I test an input to see if it is a real number?

$ perldoc -q float 

Found in /usr/local/lib/perl5/5.6.1/pod/perlfaq4.pod
 How do I determine whether a scalar is a
 number/whole/integer/float?

 Assuming that you don't care about IEEE notations like NaN
 or Infinity, you probably just want to use a regular
 expression.

if (/\D/){ print has nondigits\n }
if (/^\d+$/) { print is a whole number\n }
if (/^-?\d+$/)   { print is an integer\n }
if (/^[+-]?\d+$/){ print is a +/- integer\n }
if (/^-?\d+\.?\d*$/) { print is a real number\n }
if (/^-?(?:\d+(?:\.\d*)?|\.\d+)$/) { print is a decimal number }
if (/^([+-]?)(?=\d|\.\d)\d*(\.\d*)?([Ee]([+-]?\d+))?$/)
 { print a C float }

 If you're on a POSIX system, Perl's supports the
 POSIX::strtod function.  Its semantics are somewhat
 cumbersome, so here's a getnum wrapper function for more
 convenient access.  This function takes a string and returns
 the number it found, or undef for input that isn't a C
 float.  The is_numeric function is a front end to getnum
 if you just want to say, ``Is this a float?''

 sub getnum {
 use POSIX qw(strtod);
 my $str = shift;
 $str =~ s/^\s+//;
 $str =~ s/\s+$//;
 $! = 0;
 my($num, $unparsed) = strtod($str);
 if (($str eq '') || ($unparsed != 0) || $!) {
 return undef;
 } else {
 return $num;
 }
 }

 sub is_numeric { defined getnum($_[0]) }

 Or you could check out the String::Scanf module on CPAN
 instead.  The POSIX module (part of the standard Perl
 distribution) provides the strtod and strtol for
 converting strings to double and longs, respectively.


-- 
Walter C. Mankowski
Senior Software EngineerMyxa Corporation
phone: (610) 234-2626   fax: (610) 234-2640
email: [EMAIL PROTECTED]http://www.myxa.com




Re: test for real number

2001-05-30 Thread Jeff Pinyan

On May 30, [EMAIL PROTECTED] said:

I'm new to the group and new to Perl and am very glad to have such a 
resource available. Hopefully someday I'll be on the giving end of the 
help list but for now I'm stumped. How do I test an input to see if it 
is a real number?  I have a situation something like:

I suggest you look at the FAQ entry for 'float' (perldoc -q float), and at
Tom Christiansen's Far More Than You Ever Wanted To Know (FMTYEWTK) doc
on this same question:

  http://www.cpan.org/doc/FMTEYEWTK/is_numeric.html

-- 
Jeff japhy Pinyan  [EMAIL PROTECTED]  http://www.pobox.com/~japhy/
Are you a Monk?  http://www.perlmonks.com/ http://forums.perlguru.com/
Perl Programmer at RiskMetrics Group, Inc. http://www.riskmetrics.com/
Acacia Fraternity, Rensselaer Chapter. Brother #734
**I no longer need a publisher for my Perl Regex book :)**




Re: test for real number

2001-05-30 Thread Carl Rogers

Good day;

try:::
if ($input =~ /\d+\.?\d+/){
xxx

}
The intent here is:
 \d+ ##one or more digits
 \.?  ##followed by zero or one . (there is a dot there)
 \d+ ##followed by one or more digits.

I think this will work. Depending on how your reals will be input, you can 
tweak the \d to suit your needs.
Hope this helps/works.
Carl

At 01:56 PM 5/30/2001 -0700, you wrote:
Hi,
I'm new to the group and new to Perl and am very glad to have such a 
resource available. Hopefully someday I'll be on the giving end of the 
help list but for now I'm stumped. How do I test an input to see if it is 
a real number?  I have a situation something like:

  $input = STDIN;
 chomp $input;

if (input equals a real number) {
 xx
}
else {

}
best, michael




Re: test for real number

2001-05-30 Thread Morten Sickel

Hi Mike,

You wrote:

How do I test an input to see if it is a real number?  I have a situation
something like:

(slightly snipped)

if (input equals a real number) {
xx
}
else {

}

Do you mean 'if it really is a number' or 'a real number' in the matematical
sense? If you have some advanced matematical things going on, please forget
this message, but if what you want to do is to check a value before
inserting it into a database or something similar to that, a quick and dirty
way of converting is just to say:

$value=STDIN;
$value*=1; # ie $value=$value*1;
if ($value){
   print $value is a number\n
}
else{
   print This is not a number\n
}

Divided by 1 or plus / minus 0 would do the same, force perl to think about
the value as a number. As a semi-beginner, I can see two problems with this
approach:
1: if $value=0 it will be counted as false
2: For a value that starts with a number, such as 123ABC, the numerical part
will be retained as a number, and everything including the first letter to
the end of the string will be thrown away:
i.e:
input  : ABCDE
output : This is not a number
input  : 0   - Zero
output : This is not a number
input  : 1.2345
output : 1.2345 is a number
input  : 123ABC
output : 123 is a number
input  : ABC123
output : This is not a number 

This may, or may not be, what you want. I am using that conversion/check
quite often, but in those cases, I know that my value cannot be zero.

Regards

Morten Sickel
Norwegian Radiation Protection Authority