choroba has asked for the wisdom of the Perl Monks concerning the following question:

Dear Monks,

I got a strange tester failure report for Syntax::Construct. It seems there's a machine with Perl 5.20.2 whose $Config{randfunc} returns drand48 , but my test expects Perl_drand48 . See the relevant perl5200delta:

> Perl now uses its own internal drand48() implementation on all platforms.

Corion pointed me to a search for randfunc where the only possibly relevant line is the one from uconfig64.sh:

776:randfunc='drand48'

I don't understand what the file is used for, so this might be totally unrelated.

So, my questions are:

  1. Is it OK to have Perl 5.20+ with $Config{randfunc} returning drand48 without the Perl_ prefix? If so, I can check just /drand48/ or use index in the test.
  2. Is there some other method besides using %Config to check that Perl uses its own drand48 function?

($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord }map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,

Replies are listed 'Best First'.
Re: randfunc in Config
by Anonymous Monk on Jun 27, 2016 at 09:31 UTC

    Is it OK to have Perl 5.20+ with $Config{randfunc} returning drand48 without the Perl_ prefix?

    Yes, the user can always opt out of using perl_drand48, either on purpose or by mistake ... it is a weird thing to change

    Also, the user can always fake/fudge Config.pm

    simplest best option is trust Config

    Is there some other method besides using %Config to check that Perl uses its own drand48 function?

    see if any drand48 is imported with  objdump -x perl...dll |grep drand48

    Or heuristics ... hahah :D

Re: randfunc in Config
by BrowserUk (Patriarch) on Jun 27, 2016 at 10:53 UTC
    Is there some other method besides using %Config to check that Perl uses its own drand48 function?

    I would have thought the simplest test would be to seed (srand) with a known value (say 1) and test the first value that rand() returns. If it is the same PRNG you are expecting, then it will produce the same first (and sequence) of values.

    That said, it does kind of lead to the question: what is it that you are testing that requires a specific PRNG in the first place?

    It sounds like -- and given it is you, I'll not say it any more strongly than that -- you are testing the wrong thing. Ie. You appear to be testing for a specific implementation of a PRNG; rather than for the successful product of whatever your module that uses the PRNG is meant to produce.

    What I'm getting at is: is it necessary to limit the use of your module to implementations that have one specific PRNG available?


    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority". I knew I was on the right track :)
    In the absence of evidence, opinion is indistinguishable from prejudice. Not understood.

      Having a unified (drand48) rand() implementation is one of the features that came in with Perl 5.20.0, so testing in a sensible way for availability of drand48 (instead of testing for 5.20.0+) is the main goal for choroba I think.

        Having a unified (drand48) rand() implementation is one of the features that came in with Perl 5.20.0, so testing in a sensible way for availability of drand48 (instead of testing for 5.20.0+)

        Besides that 5.20+ seems like a far simpler criteria to test for; even if the goal is "any perl with drand48 even if that's a linux build before 5.20"; that still suggests that he is insisting on a 48-bit PRNG, which without knowing what the module is doing, seems short-sighted.

        Ie. Why does it need to be 48-bit? How would the modules functionality be affected if I wanted to use the 32-bit MT? Or the 64-bit MT? Or even the very fast simd implementation of the 64-bit MT? What if I chose to provide a 48-bit PRNG that isn't the drand48 implementation?

        If he needs that particular implementation, then seeding to a known seed and testing the first return value will detect it, both if it is under a different name; and perhaps more importantly, fail if it has the right name but the implementation has been screwed up.

        But still the nagging in the back my head says that any algorithm that uses random numbers but needs one very specific PRNG to operate, is badly designed.

        I can see that TDD proponents would like to be able to specify they PRNG because then all their little OK/NOK tests can compare against known pre-calculated outputs; but if that is the purpose; as soon as you've detected that you have the right PRNG, all those comparisons against pre-calculated outputs become redundant.


        With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
        Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
        "Science is about questioning the status quo. Questioning authority". I knew I was on the right track :)
        In the absence of evidence, opinion is indistinguishable from prejudice. Not understood.
Re: randfunc in Config
by choroba (Cardinal) on Jun 27, 2016 at 18:14 UTC
    Googling for "OpenBSD perl drand48", I discovered this commit. So, it seems they chose not to use Perl's own drand48. Anybody running OpenBSD can confirm this, please?

    ($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord }map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,
        Hi afresh1, thanks for the reply. I guess that testing the values for a known seed should be enough, but maybe Syntax::Construct should emit a warning if the $Config{randfunc} is different to Perl_drand48 . The reasoning is: why would anyone need Perl_drand48 ? Either to get a predictable sequence for a given seed, or to have a better algorithm than the previous one (on some platforms, e.g. MSWin), which both holds for OpenBSD's rand. But maybe I'm too optimistic...

        ($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord }map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,
Re: randfunc in Config
by Cow1337killr (Monk) on Jun 28, 2016 at 04:32 UTC

    I don't think there is a foolproof method to check that Perl uses its own drand48 function.

    It appears that $Config{randfunc} contains the name of the random function used to build the Perl version on your box.

    Is there a way to lie to the poor Perl? Of course, there is. Just wave a twenty dollar bill in front of a hacker in a dark room. He will list half a dozen different ways to do it.

    I scanned for drand48 in all the files in C:\Strawberry, the directory that holds my Strawberry Perl installation on my computer (with a Windows operating system). One of the files found was C:\Strawberry\perl\bin\perl524.dll. I am pretty sure that is the dll that gets run when I run perl from the command line. Maybe the "drand48" that it found in there is a decoy. I doubt it. (I just installed Strawberry Perl last week, by the way.)

    Just to be clear, there is NO file in my C:\Strawberry directory with drand48 as part of the name.

    With my limited knowledge of systems programming, that tells me that the executable code is embedded in C:\Strawberry\perl\bin\perl524.dll (that I mentioned above).

    I have poked around and I can think of no easy way to get Perl or the operating system to reveal that Perl_drand48 is being called. (Obviously, an operating system dependent recipe is not desirable.)

      This will give one an idea of the degree of confusion out in the field regarding this subject.

      I Googled "$Config{randfunc} drand48".

      I got three hits on this fellow's GitHub.

      The code below is from https://github.com/drzigman/perl-random/blob/master/drand48/driver_perl/generate.pl

      use Config; # Make sure we are using drand48 as the underlying implementation if($Config{randfunc} ne "drand48") { print "Perl is configured with randfunc '" . $Config{randfunc} . "' rather than drand48\n"; return 1; }

      This code won't work anymore.

      'Perl_drand48' is stored in $Config{randfunc}.

      If someone asked me to change their Strawberry Perl installation so that it uses myrandom instead of Perl_drand48, I don’t know what I would do. I don’t know where I would go on the Internet to get an answer. However, if I did find a cookbook recipe and figured out how to do it, then there would be a 30% chance that I would forget to update $Config{randfunc} (which is the commonly accepted method of determining what program is ultimately called when you or I call rand() in a Perl program).