Reviews by יובל קוג'מן


Moose (0.93)

AnyEvent-Kanye (0.02)

Great review and I'm going to let you finish, but Rev Michael Greb had one of the best reviews of all time

MooseX-Meta-Attribute-Lvalue (0.02) **

This is a bad idea, because the only way to actually make lvalue accessors work correctly would be to use a tied scalar when used in lvalue context. Otherwise no guarantees about the type constraint or storage is made, breaking the assumptions that you can make with a normal Moose class.

Authen-Passphrase (0.005) *****

This is a very clean and consistent way of managing password strings and making them into password objects.

It's nice for testing (using cleartext passwords), upgrading (migrating from say crypt to a stronger hash), and other scenarios where the polymorphism of the api is very valuable (everything can be used the as/from stringification methods, and can be tested for password equivalence the same way, even though the representations are different).

The only problem I ran into is that it doesn't [yet] support $apr1$ style passwords (i dunno if this is the hash function or just the formatting that is missing), but aside from that it works great.

DateTime-Locale (0.41) *****

Even if not perfect this is a very comprehensive and useful library.

I do agree with BKB though, Dave is a total douchebag for not learning japanese, especially since he is compiling this data based on the CLDR charts.

Update: Yeah, I totally agree! Dave please upload 400 dists, it will be *MUCH* easier to deal with like that. Oh and also you're a total douche!

Class-Std (0.0.9)

Give your class STDs!

namespace-clean (0.08) *****

This is a simple, clean and effective way of letting you use exports without polluting your class's package.

SVK (v2.0.2) *****

SVK makes subversion bearable. This is both a wonderful and a horrible thing.

Most places are using Subversion nowadays. Fortunately this trend has now stopped in favour of more novel systems, but the bottom line is you're more likely to have to use subversion than anything else.

SVK supports everything subversion does, and also adds disconnected operation and very good merging support.

The benefit is that it makes subversion almost as usable as a distributed system. For people who travel often or who make heavy use of branching it is a huge time saver.

The problem is that because SVK adds features on top of subversion instead of removing certain classes of features like purely distributed VCSs do, it has an extra layer of complexity to manage. This of course comes with usability and stability issues (most of which are rooted in subversion itself, so they are hard to fix).

So the bottom line is that SVK is about as good as it can be, within the limits of its subversion heritage. For when subversion is not necessary I prefer simpler tools.

Exporter-Simple (1.10)


HTTP-Engine (0.0.10) *****

Clean and simple HTTP server abstractions.

It's basically a web framework without the Kool Aid of frameworks - you do your own thing, but you can easily deploy FastCGI, mod_perl, POE standalone webserver with the same code.

Test-TAP-HTMLMatrix (0.09)

I recommend TAP::Formatter::HTML instead of this module as a modern, maintained alternative.

FWIW the "why" was in mouseovers ;-)

Test-TAP-Model (0.10)

Indeed, as the author I recommend TAP::Harness instead of this module, which is a hack that predates it.

Update: I uploaded a deprecation release, please use TAP::Harness for processing results, and TAP::Formatter::HTML as a Test::TAP::HTMLMatrix replacement. I would be happy to accept patches for the latter to make it work with TAP::Harness, but Test::TAP::Model is now unnecessary.

Data-Rand (v0.0.2) *

Definitely *not* cryptographically secure. Uses one call to rand() (typically 15 bits of "randomness" but even that's questionable), the process id and the time of day to seed an array, and then shuffles that around to generate chars.

Not efficient, either.

If you want real random data read it from /dev/random, use an openssl binding, use the entropy gathering daemon, or something like that.

Cryptographically secure algorithms should be designed by cryptographers, and much more importantly rigorously reviewed by cryptographers before making such claims.

Updated: The actual amount of entropy does not rise more than what the seed can provide, and so this is not cryptographically secure. For pseudorandom numbers much more efficient and reviewed algorithms exist, for instance the Yarrow random number generator. The shuffling you do could only plausibly reduce the actual randomness of the data, so it is doing more harm than good.

You implement a PRNG that uses an array as it's internal structure, which is seeded with various inputs i stated earlier. srand has nothing to do with that, it's seeding a different PRNG with different values (perl's own one). This is the the upper bound on the actual random data being inputted. You could arguably package the small amount of entropy gathering into something standalone useful for seeding e.g. OpenSSL's entropy pool based RNG.

Implementing a pseudo random number generator for security purposes is isomorphic with designing a cipher. The PRNG you implemented is dubious at best. Furthermore not enough truly random data is being seeded, so regardless of the fact that it is potentially volunerable to various analysis it can't actually generate more than roughly 2^16 random sequences. Since rand is a prng with no cryptographical merit, calling it repeatedly in the shuffle function doesn't actually add any additional entropy. Testing that this is random with 10k unit tests is meaningless. If you tested that the collision rate is in effect lower than 2 / 2^(128-1) or so then that is pretty much the lower bound on what is considered acceptible today. Note that actually verifying this in practice is not practical even with a government budget, so that's why people who actually know cryptography design, analyze and review ciphers/prngs.

See the recent debian ssh key fiasco for why people who don't understand what they are doing shouldn't touch crypto stuff, let alone make claims about it. The implementation of the debian openssl code was correct, but there was a bug in just the estimation of the amount of actual random data. It led to there only being about 30,000 actual keys produced on debian systems in practice.

To elaborate on the efficiency point: Perl arrays involve many layers of pointer indirection. Shuffling them around is an expensive process. Suppose for a second your algorithm was indeed a secure one, it would be much more efficiently implemented using bit vectors, and not array access. On my machine `openssl rand` is about 100x faster and actually known to be at least as secure as Data::Rand claims to be.

In summary, my review's purpose was to warn others, not to get you to improve the code, because I believe it's fundamentally flawed.

lib-tiny (0.1) *

This is the mother of all stupid ideas. I mean seriously, what the fuck are you on man?

nothingmuch % time perl -e 'use lib qw(/tmp)'

real 0m0.011s
user 0m0.005s
sys 0m0.005s
nothingmuch % time perl -e ''

real 0m0.006s
user 0m0.002s
sys 0m0.004s

WOOOOO!!! SHAVE A WHOLE 0.005s! TEH OSOM!!!11one

Variable-Magic (0.06) *****

This module opens up one of the nastiest bits of Perl's guts. it does so with a simple interface that hides what is, IMHO, the right amount of details for 90% of the use cases. The result is a very usable alternative to hacking magic in XS on your own.

If you need to do some really crazy stuff then you do need to go to those means, but for typical usage of magic in Perl this is a convenient and perlish interface.

Catalyst-Controller-BindLex (0.03)

As the author I can't wholeheartedly reccomend this module...

I find that the dependencies involve too much "black magic" to be truely stable and occasionally one sees segfaults, and incompatibilities with modules that are really hard to anticipate (for example total breakage WWW::Myspace has been reported).

Being mostly syntactic sugar it's easy to remove this module using find and replace and a little bit of manual labor, but finding out that it is the culprit might not be so easy.

Use with caution.

Sub-Todo (v0.0.1)

This is rather ironic ;-)

Acme-Placeholder (0.04)

Robert - I'll delete it at some point (a year's time sounds fair), especially if the butt end of the joke actually condenses into software (or gets deleted itself). I do feel that the namespaces taken by this module are somewhat less plausible choices for other authors, so I'm not really worried about clashes. If it really bothers you I can delete it now after I got my fame ;-)

Interpolate (v0.0.1) *

Unfortunately this module claims to interpolate variables both safely and quickly but fails to do either any better than string eval.

I doubt this module will ever live up to it's claim with it's current design and thus do not reccomend you use it. Instead, there is a wealth of templating modules available on the CPAN, and if that is a bit too much then good old sprintf can usually do the job.

Set-Object (1.17) *****

This is a lovely module!

Whenever I need to index by object it's either this module or Tie::RefHash. When Tie::RefHash isn't necessary (there is no value at the end) usually i'm working with collections of objects where set operations helps clarify the code immensely.

Performance is also good, and then new ->weaken feature is simply delightful.


Acme-ProgressBar (1.12) *****

This is the most accurate progress bar on the CPAN.

The ticks on the bar will update accurately, with ETAs precise to the second!


asa (0.02)

For the record that is not duck typing.

Duck typing is:

if ( $object->can("quack") ) {

warn "$object looks sufficiently like a duck";


That is to say, the actual type, the isa, does, interface restrictions etc are all phased out, and it's purely an interface level thing.

asa helps you write drop in replacements that would work if the code they were to drop into only checked for duck typing. When you want to do that you can use 'asa' to pretend that you 'isa' something that you only quack like.

Want (0.10) *****

Want provides introspection capabilities for all the context sensitive behaviors present in Perl, in a convenient API. It's a shame that Perl itself doesn't provide the same flexibility in it's core.

One problem with Want, though not directly Want's fault, is that things like Template Toolkit call into Perl space in slightly different ways, and don't provide an op tree to return to, which is how Want does it's magic. In these cases there is a pretty nasty error, so watch out.

The author is also very friendly and helpful (and patient ;-) - without him <plug>Context::Handle</plug> wouldn't be possible...

Carp-Indeed (0.04) ****

This module works as advertized for what I needed it... Devel::SimpleTrace and Acme::JavaTrace don't list the arguments.

It could improve by:

making _die and _warn goto \&Carp::confess etc, so that this particular stack frame is not mentioned

remove @EXPORT_OK, and in fact all use of Exporter (it's not used and in fact could result in errors later 'die' and 'warn' don't exist).

but it does get the job done and is *not* the same as -MCarp=verbose.

A better name could be Carp::Always.

UNIVERSAL-isa (0.06)

this module's use case is very very very simple.

Everyone seems to be making something it's not out of it.

If/when you encounter mis-use of UNIVERSAL::isa as a function, and this hinders your ability to e.g. test with Test::MockObject, you can load UNIVERSAL::isa (the module) to temporarily fix this problem until the author of the code that is causing the problem fixes it.

Automatically using it with Test::MockObject was a mistake, in my opinion. Shipping it and using it in production is also a mistake.

Admittedly the documentation was abusive but this spawned out of numerous frustrations with authors of modules refusing to fix their problematic code, and was not meant to be taken seriously.

That's all. Could we please stop beating the dead horse?

Catalyst-Runtime (5.63) *****

Catalyst is a very nice framework because unlike many other framework there is lots of emphasis on reducing bloat, keeping things clean, reusable, and flexible.

This means that Catalyst is a good choice for the long run, because chances are you can extend it and fix it more easily than more tightly coupled frameworks.

It's ease of use and arsenal of plugins and components mean that most of the time what you want has already been written, letting you focus on the code that is unique to your application, and thus cutting down development time.

Highly reccomended!

Bias note: I participate in Catalyst development, but I didn't when I first realized these things =)

Test-use-ok (0.01) *****

What can I say - it's elegant, simple, easy to use and solves the problem at hand very directly and efficiently.

This is what the CPAN should have more of.

UNIVERSAL-can (1.00) *****

Yet again, a bullshit review.


Why can't you read the docs? Why can't you understand the problem at hand?

See also the reviews for UNIVERSAL::isa

Algorithm-Bucketizer (0.10) *****

This module is versatile, extensible, and useful.

I needed to bucketize with varying buket sizes, for example. It took me about 10 lines of subclass code to come up with an adequeate solution.

This saved me lots of time designing and implementing a solution that I probably wouldn't have gotten right anyway.


SQL-Translator (0.06) ****

This distribution is really superb in terms of the abstraction it lets you do. I use it to create my schema in OO, and generate sane SQL from that. This I pipe to whatever database I'm using. The application level is completely oblivious of all this detail.

It just works, and it does it well.

There are three quirks though.

Speed. Parsing schemas and stuff is slow. That's what you get for using Parse::RecDescent. It's well worth it though.

The documentation is occasionally sparse, and you have to dig hard and long to find silly little bits, when you're trying to pick it up. The documentation is scarecely necessary after that, though.

Lastly, the installation process is tedious, as there are lots of extensions that, IMHO, should be packaged seperately, to allow an easier installation. Not everyone wants GD diagrams, or can even install GD...

Event (1.00) *****

This is a really wonderful module... The PDF tutorial is clear, concise and rich. The module's interface is very simple, and intuitive.

Most importantly, this gets the job done, cleanly and easily.

I'm so sorry I only found it just now. I would have used it extensively for a bajillion things i've previously written by hand.

Test-MockObject (0.14) *****

I couldn't think of a better interface for mock objects.

The documentation is exceptionally superb, and the module itself is very usable too.

Attempt (1.01) *****

This module is /the/ most intuitive interface i've seen for this problem, and it comes with no loss too - errors are not hidden or anything. It does not conflict with anything else... It's basically a stubborn eval {} which redies after it's given up.

I have yet to use the subroutine attributes and modifiers, but the normal attempt block was very useful thus far.

Maypole (1.4) ****

Maypole is an excellent start.

It does need work, though.

Installing is a mess, and usually freaks people out, from what I understand. It might be nice if there was a guide for doing that.

Additionally, not enough mention of the rest of the documentation is made in the file, so it's confusing if you don't look at the ditribution tarball itself.

Some features are still lacking, such as manymany relationship handling (maybe a patch will come to M::V::CDBI soon. CDBI supports these now), and overall things are a bit unpolished.

Aside from that, Maypole is a wonderful framework, especially when you're looking to have something working very quickly. I really reccomend that you try it if you're not sure about it.

Simon Cozens has done an excellent job in designing things properly, giving sensible default behavior, and introducing Maypole to new users with his articles on IBM's site, and

Petal (2.06) ****

Petal is an excellent templating system - it's reasonably fast, mod_perl ready, very MVCable, and well defined.

It's got a few drawbacks, at the interface level, like the inflexibility of objects. It would be nice to be able to represent a template file in an object, a parser in a different one, and then give the file object to the parser, with a shortucts for giving the parser a filename instead. Another issue is the opaqueness of the caching system - having something like callbacks to control it would be nice, and give it more customization.

The issue which bugs me the most, however, is error reporting. I would like to be able to have it set or return an error string, as well as have the option to raise errors, and define level severity. Currently, all errors are either died or warned on, so warnings cannot be collected and displayed to the user without lots of effort.

One thing blocking Petal at the moment, and expect this to change, is it's underlying parsers. The parser libraries on CPAN, that Petal uses, currently make handling entities somewhat of a voodoo. See the known bugs list.

Other than that, Petal serves as an /excellent/ templating system, due to it's clean design, promotion of standards compliance, and overall simplicity.

If you're trying to choose a templating system, you should definately give Petal a try.

Devel-Cover (0.43) *****

This is an extremely useful module, especially for extreme programming hype.

Branch coverage, for example, is a very interesting aspect of testing which is barely measurable by working 'well'. This module facilitates tests such as these, which, although perhaps not complete on their own, help even more than the reporting they provide, since they can open your eyes to whole aspects you missed.

For anybody writing tests, this is also a rewarding process. The green parts, and all those 100% spread all over the place are gratifying.

Pod-Wrap (0.01) ***

Questionable test suite.

Mail-Box (2.065) ****

Mail::Box is a heavy distribution, but it does it all.

I think that I would go as far as saying it is over engineered in places, but email is a tough nut to crack.

My only grudge is that sometimes the complexity of it all requires you to do lots and lots of doc/code diving to figure out what to actually do.

Array-Heap (0.01) *****

The module is a very simple and easy to use implementation of binary heap partial ordering on an array.

The only part lacking is the number of additional utility functions. For example, I'm trying to clip a priority queue, so I push an element, reverse the array, perform make_heap with an inverse comparison, pop an element with an inverse comparison, and reverse the array again. This could be made simpler using reverse_make_heap, reverse_pop_heap, which will enable treating the array as a heap, with the same comparison function, from the other end, so that big elements bubble that way, and you can remove them from there. I guess I could think of a number of other useful functions which are better implemented at the module level.

Otherwise jolly good show, and keep up the good work!