in reply to Re: Function over all letters in a string
in thread Function over all letters in a string

Thanks for the pointer. Simple fix:
{ my $r = substr rand, 2; sub crand() { length $r or ($r = rand) =~ tr/0-9//cd; chop $r; } } s[(.)]{$1 x (1+crand/3)}ge;
On that note one could also
# ... length $r or ($r = rand) =~ tr/3-9//cd; # ... s[(.)]{$1 x crand/3}ge;
and even move the division up into crand although that's not a generic "cached rand" anymore.

Makeshifts last the longest.

Replies are listed 'Best First'.
Re: Function over all letters in a string
by Abigail-II (Bishop) on Dec 01, 2003 at 17:47 UTC
    Well, if you initialize $r as substr rand, 2, you haven't solved the problem - $r can still contain non digits.
    On that note one could also
    # ... length $r or ($r = rand) =~ tr/3-9//cd; # ...
    No, not really. What happens if rand returns a value whose stringification only contains 0, 1 and 2? $r will be empty.

    Besides, why are you caching the result of rand? Are you running out of random numbers? The overhead of a call to a user function (crand) is much higher than the overhead of a call to Perl primitive.

    Abigail

      D'oh and d'oh. And indeed, it makes little sense to do this in Perl; in C, it would make more sense if performance was an issue. It simply struck me as inelegant to call rand over and over but throw away all but one digit of its return value on every invocation.

      Another way not to throw away digits might be something like

      $_ = 'dogcatfood'; my $l = length; my $r = sprintf "%${l}.0f\n", rand (10 ** $l);
      but that will not work for strings beyond a few hundred characters where 10^length($str) leaves the floating point range ceiling.

      Makeshifts last the longest.