> $ perl -wle 'print 2**99' > 6.33825300114115e+29 > > $ ruby -wle 'print 2**99' > 633825300114114700748351602688 > > $ perl -wle 'print 9**9**5' > inf > > $ ruby -wle 'print 9**9**5' > 1163964896171447645003711273838351370118119528741870708047727598123267112930 > 6111037903049760060898121238296130301019497278726966272049388713194128225979 > 0233081290924196740856977261251272318881097024932788534895797954088979392032 > 7738428577367953596166126106831822401524421292985114258127612235972114773252 > 5778322807185432006841500874332599997098613753825177560964766837277637864923 > 8576839226487925173752881910807257686606441838099952474016813167775933784942 > and so on [1] > > Though even Ruby gives up after a while. > > $ ruby -wle 'print 9**9**9' > -e:1: warning: in a**b, b may be too big > Infinity > > > [1] Worth noting that Ruby gets this done in about 2.5 seconds while perl with > bigint takes 30. They're probably using gmp. #### #!/usr/bin/perl use strict; use warnings; no warnings 'syntax'; use Inline 'BC'; print x(); __DATA__ __BC__ define x(){ return (9^9^5) } #### use strict; use warnings; use Memoize; $| = 1; memoize('f_fenLisesi'); my $LARGE_N = shift || 10_000; time_this( \&f_fenLisesi, 'fenLisesi' ); time_this( \&f_swampyankee, 'swampyankee'); exit( 0 ); #--------------------------------------------------+ sub time_this { my ($cref, $test_name) = @_; my $start = time(); print "testing $test_name: "; for (1 .. $LARGE_N) { $cref->( $_ ); } printf "%d second(s)\n", time() - $start; } #--------------------------------------------------+ sub f_swampyankee { my ($n) = @_; my $sum = 0; for my $i (1 .. $n) { $sum += $i; } $sum; } ##--------------------------------------------------+ sub f_fenLisesi { my ($n) = @_; return 1 if $n == 1; $n + f_fenLisesi( $n - 1 ); } #### On 7/1/07, Mark Jason Dominus wrote: > >Dave Mitchell: >> NB - It has traditionally been the case that 'local $_' >> was unsafe, and that it was better to do 'local *_' >> instead. Can anyone remind me why this is, and I'm >> wondering whether the assorted local() fixes have made >> this point moot. > > tie $x, "DO_NOT_MODIFY"; > sub DO_NOT_MODIFY::TIESCALAR { bless [] => $_[0] } > sub DO_NOT_MODIFY::FETCH { return rand; } > sub DO_NOT_MODIFY::STORE { > # system("do-bad-stuff"); > die("I told you not to modify this!") > } > > for ($x) { > use_dollar_underbar(); > } > > sub use_dollar_underbar { > local $_; > print "okay...\n"; > $_ = 1; > } > > > use_dollar_underbar() wants to operate on $_ without > tampering with its global value and without causing > any strange action-at-a-distance. So it uses "local $_" > to try to do this. But "local $_" *itself* tampers > with the global value and causes a strange > action-at-a-distance. And more specifically... Changing it to confess() instead of die shows that local $_; calls DO_NOT_MODIFY::STORE(). Yves -- perl -Mre=debug -e "/just|another|perl|hacker/" #### # perl -wle 'print 2 ** 128' 3.40282366920938e+38 # perl -Mbigint -wle 'print 2 ** 128' 340282366920938463463374607431768211456 # perl -wle 'print sqrt(2)' 1.4142135623731 # perl -Mbignum -wle 'print sqrt(2)' 1.41421356237309504880168872420969807857 # perl -wle 'print 3/7 ** 77' 2.53847080898319e-65 # perl -Mbigrat -wle 'print 3/7 ** 77' 3/118181386580595879976868414312001964434038548836769923458287039207 #### ... In my current project, I needed to extend the 'convert' functionality of SQL-Abstract-1.22 in order to support two kinds of behavior: 1) convert procedures that take multiple parameters, such as: locale_upper( name, 'en_US' ) 2) convert procedures that apply to some columns only, as in the following snippet: WHERE locale_upper(name,'en_US') LIKE locale_upper($1,'en_US') AND age = 32 The simplest interface extension that I could came up with that supports these requirements was as follows: $criteria->{convert} = ['locale_upper', q('en_US') ]; OR $criteria->{convert} = { proc => ['locale_upper', q('en_US') ], labels => [qw( name description )], }; I was able to hack SQL-Abstract-1.22 today by introducing changes to sub _convert($) {...} only, as you can see in the following patch. After applying this patch, SQL-Abstract-1.22 passes the four tests that come with the distribution, which I hope means that I have not balatantly broken major existing behavior. I am likely to have introduced some new bugs, however, as I have just sewn the patch today and the code has not been reviewed. ... --- SQL-Abstract-1.22-orig.pm 2006-11-30 19:12:14.000000000 +0200 +++ SQL-Abstract-1.22-fenL.pm 2007-03-15 17:53:57.000000000 +0200 @@ -209,10 +209,78 @@ sub _quote { # Conversion, if applicable sub _convert ($) { - my $self = shift; - return @_ unless $self->{convert}; - my $conv = $self->_sqlcase($self->{convert}); - my @ret = map { $conv.'('.$_.')' } @_; + my ($self, @args) = @_; + + return @args unless $self->{convert}; + + if (! $self->{convert_has_been_init}) { + $self->{convert_has_been_init} = 1; + + my $conv = $self->{convert}; + my ($params, $labels) = ([], []); + + if (ref( $conv ) eq 'ARRAY') { + if (! @$conv) { + die q(convert arrayref refers to an empty array); + return @args; + } + ($conv, @$params) = @$conv; + } + elsif (ref( $conv ) eq 'HASH') { + my $proc = $conv->{proc}; + if (defined $conv->{labels}) { + if (ref( $conv->{labels} ) ne 'ARRAY') { + die q(val for key 'labels' must be an arrayref); + ## return @args; + } + $labels = $conv->{labels}; + } + if (! $proc) { + die q(required elem 'proc' missing in convert hash); + ## return @args; + } + if (! ref( $proc )) { + $conv = $proc; + } + elsif (ref( $proc ) eq 'ARRAY') { + if (! @$proc) { + die q(convert proc aref refers to an empty arr); + ## return @args; + } + ($conv, @$params) = @$proc; + } + else { + die q(convert hash elem 'proc' must be scalar/aref); + ## return @args; + } + } + $self->{convert} = $conv; + $self->{convert_params} = $params; + $self->{convert_labels} = { map { uc( $_ ) => 1 } @$labels }; + } + my $conv = $self->{convert}; + $conv = $self->_sqlcase( $conv ); + my @ret = (); + + ARG: + for my $arg (@args) { + if ($arg eq '?') { + if (not defined $self->{convert_current_label}) { + die q(request to convert '?' when no label has been seen yet); + } + } + else { + $self->{convert_current_label} = $arg; + } + if (keys %{ $self->{convert_labels} }) { + if (not $self->{convert_labels}->{uc $self->{convert_current_label}}) { + warn 'Ignoring _convert() for label ' . $self->{convert_current_label}; + push @ret, $arg; + next ARG; + } + } + push @ret, sprintf '%s(%s%s)', $conv, $arg, map { ",$_" } @{ $self->{convert_params} }; + } return wantarray ? @ret : $ret[0]; } #### Do you know me, my lord? Excellent well; you are a Perl Monger. #### Imperious Bill Gates, dead and turn'd to clay, Might stop a hole to keep the wind away: O, that that earth, which kept the world in awe, Should patch a Wall to expel the Windows' flaw! #### $words, @words, %words. #### my $class_name = 'Foo' . '::' . 'Bar'; eval "require $class_name"; if ($@) { warn $@; } $class_name =~ s|::|/|g; eval { require "$class_name.pm"; }; if ($@) { warn $@; }