Results tagged “PSGI”

leaves falling off the tree
For me, one of the promises of [PSGI and Plack]( 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, replaced using a global
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 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/ 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 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](, 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]( 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]( I've enjoyed the process, and respect 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]( for filling them. Whenever I think about how I'd like to change,what I have mind is often the same choice that [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 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 has to provide real world beta testing.