tag:blogger.com,1999:blog-876358347971598886.post8277314032181020597..comments2023-03-25T16:20:46.021+03:00Comments on nothingmuch's perl blog: Reducing Scopenothingmuchhttp://www.blogger.com/profile/03855760206940108541noreply@blogger.comBlogger5125tag:blogger.com,1999:blog-876358347971598886.post-51997507836939853802009-11-09T13:55:14.915+02:002009-11-09T13:55:14.915+02:00A singleton prototype object, i should say.A singleton prototype object, i should say.nothingmuchhttps://www.blogger.com/profile/03975438115490089158noreply@blogger.comtag:blogger.com,1999:blog-876358347971598886.post-47364756638053842622009-11-09T12:51:56.782+02:002009-11-09T12:51:56.782+02:00C::RP is giving the user something sort of like a ...C::RP is giving the user something sort of like a prototype object with one overridable method, 'rng'.<br /><br />If instead if just provided a fine grained OO api that could easily be subclassed, where the different tasks, such as generating random data, generating an alphabet, picking sequences from it, etc.<br /><br />Now, thinking about this, there is no reason whatsoever for the public API of the random data generation method to return an arbitrary floating point number with an arbitrary number of bits of percision. The data type doesn't fit, the interface becomes clumsy, etc.<br /><br />If instead the method generated N bits and returned rthem as a packed string, or it would generate an integer between 0 and $n or something like that, it would have been much easier to provide an alternate random number generator. Sticking with the rand() builtin's API is just the wrong level of abstraction here.<br /><br />And no, use Crypt::RandPasswd ( rng => ... ) changes nothing in the ill fitting semantics of the 'rng' callback. The only difference is that it implies the overriding is global, which is just evil (it may or may not be true, the import method could curry, instead).<br /><br />It's not a question of the overriding syntax, it's a question of thinking about what it is that the random data generation api should look like when you're generating passwords.<br /><br />A sensible answer is 'a sequence of randomly chosen characters', and a silly one is 'a floating point number between 0 and 1'nothingmuchhttps://www.blogger.com/profile/03975438115490089158noreply@blogger.comtag:blogger.com,1999:blog-876358347971598886.post-22151977671048935232009-11-09T07:21:33.718+02:002009-11-09T07:21:33.718+02:00Why do you say that the approach in Crypt:RandPass...Why do you say that the approach in Crypt:RandPasswd is 'hardly a solution'. I don't necessarily disagree, but I wonder which parts bother you. Is it the ugliness of the syntax, or that the override can't really be redistributed? <br /><br />One could probably 'improve' the syntax in a general fashion by writing a module 'Override' such that 'use Override "Crypt::RandPasswd" => {rng => \&my_rng}' works. But would this be an improvement or even worse of an abomination?<br /><br />For that matter, what would your ideal interface look like? Is 'use Crypt::RandPasswd rng => \&my_rng' what you are looking for? I ask because I'm running up against similar issues, and haven't yet come up with a solution I really like.Nathan Kurzhttps://www.blogger.com/profile/14146798466013693392noreply@blogger.comtag:blogger.com,1999:blog-876358347971598886.post-31407997098659390872009-07-31T02:19:22.209+03:002009-07-31T02:19:22.209+03:00Yes, functional programming definitely fits into t...Yes, functional programming definitely fits into this just as well (if not better), but we don't really use it in Perlnothingmuchhttps://www.blogger.com/profile/03975438115490089158noreply@blogger.comtag:blogger.com,1999:blog-876358347971598886.post-81056710433741235342009-07-30T18:23:06.513+03:002009-07-30T18:23:06.513+03:00Dependency infection / inversion of control is nic...Dependency infection / inversion of control is nice, certainly, but I'm not sure it really depends on OO design.<br /><br />In a functional language interface, you would probably be allowed to construct your own password generator by passing the constructor a PRNG function and an encoder*. Currying makes for convenience -- and possibly, depending on your style preferences, cleaner than subclassing.<br /><br /><br />PS: One reason your modules get criticized is because your docs suck. Even if your interface is generic, you want to give a specific, concrete example near or in the synopsis so that (T_ahh - T_wtf) is minimized.<br /><br /><br />* So the generator might be implemented as, simply, (.).Anonymousnoreply@blogger.com