Results tagged “PSGI”

leaves falling off the tree
For me, one of the promises of [PSGI and Plack](http://plackperl.org) is to get away from programming with global variables in Perl, particularly being able to modify the request object after it's been created. Long ago, CGI.pm replaced using a global
%FORM
hash with a "query object", but it essentially has been used as always-accessible read/write data structure. It would appear at first look that improving this might a fundamental part of the new system: A lexical environment hashref is explicitly passed around, as seen here: Plack::Request->new($psgi_env); vs the old implicit grab from the environment: CGI->new; You might hope to be escaping some of th action-at-a-distance badness of global variables, like having a change to environment alter your object *after the object is created.* You might like avoid having changes made to your object avoid changing the global environment as well. Not only does Plack::Request require an explicit environment hash to be passed in, both nearly all methods are read-only, including a param() method inspired by a read/write method from CGI.pm of the same name. That's all good. This would all seem to speak to safety and simplicity for using Plack::Request, but the reality turns out to be far muddier than you might hope. I encourage you to down and run this short, safe [interactive perl script](/blog/2011/02/plack_vs_cgi.pl) which illustrates some differences. It shows that: * Plack::Request objects can be altered after they are created by changing the external environment. * Modifying a Plack::Request object can potentially alter the external environment hash (Something which CGI.pm explicitly does not allow). In effect, the situation with global variables is in some regards worse. Plack::Request provides the impression that there is a move away from action-at-distance programming, but the fundamental properties of being affected by global changes and locally creating them are still present. On the topic of surprising read/write behavior in Plack::Request, you may also interested to note the behavior of query\_parameters(), body\_parameters() and parameters() is not consistent in this regard. I submitted [tests and suggestion to clarify this](https://github.com/markstos/Plack/commit/0aefed0900eeb2281eb0fe925bd18dfd60076b1e), although that contribution has not yet been accepted. Here's the deal: The hashref returned by query\_parameters() and body\_parameters() and parameters() are all read/write -- subsequent calls to the same method return the modified hashref. However, modifying the hashes returned by body\_parameters() or query\_paremeters() does not modify the hashref returned by parameters(), which claims to be a merger of the two. It seems that either all the return values should be read-only, ( always returning the same values ), or if modifying them is supported then the parameters() hash should be updated when either of the body\_parameters() or query\_parameters() hashes are updated. ## Reflections An incoming HTTP request to your server is by it's nature read-only. It's analogous to a paper letter being delivered to you be postal mail. It's a perfect application for an immutable object object design that Yuval Kogman [eloquently advocates for](http://blog.woobling.org/2009/05/immutable-data-structures.html). Plack::Request comes close to implementing the idea with mostly read-only accessors, but falls short. The gap it leave unfortunately carries forward some possibilities for action-at-distance cases that have been been sources of bugs in the past. I'd like to see Plack::Request, or some alternative to it, with the holes plugged: It should copy the input, not modify it by reference, and parameter related methods should also return copies rather than reference to internal data structures.
baby sleeps again I've spent a lot time recently [triaging bugs for CGI.pm](http://mark.stosberg.com/blog/2009/08/almost-100-cgipm-bugs-closed-help-with-the-50-still-open.html). I've enjoyed the process, and respect CGI.pm as a widely used Perl module. I'm not in love all aspects of module. I don't use or recommend the HTML generation features-- I recommend using HTML template files and [HTML::FillInForm](http://search.cpan.org/perldoc?HTML::FillInform) for filling them. Whenever I think about how I'd like to change CGI.pm,what I have mind is often the same choice that [CGI::Simple](http://search.cpan.org/perldoc?CGI::Simple) made. There was a time years ago that I focused my attention on CGI::Simple and tried it in production, only to be bit by a compatibility issue, so I reverted back to CGI.pm. I don't remember what the specific issue, and it's likely been fixed by now. But the pragmatic point remained with me: CGI::Simple may have clean code and a good test suite, but it's not necessarily free of defects and in particularly it lacks the vastly larger user base that CGI.pm has to provide real world beta testing.
1
Close