Re: test for real number
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
--- 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
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
--- 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
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
--- 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)
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)
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)
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)
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
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
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
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
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
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
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