<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:gd="http://schemas.google.com/g/2005" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" gd:etag="W/&quot;AkIAQ3wzeyp7ImA9WxBaEk4.&quot;"><id>tag:blogger.com,1999:blog-876358347971598886</id><updated>2010-03-22T08:15:42.283+02:00</updated><title>nothingmuch's perl blog</title><subtitle type="html" /><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://blog.woobling.org/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://blog.woobling.org/" /><link rel="next" type="application/atom+xml" href="http://www.blogger.com/feeds/876358347971598886/posts/default?start-index=26&amp;max-results=25&amp;redirect=false&amp;v=2" /><author><name>nothingmuch</name><uri>http://www.blogger.com/profile/03975438115490089158</uri><email>nothingmuch@woobling.org</email></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>72</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/yuvalkogman" /><feedburner:info uri="yuvalkogman" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><link rel="license" type="text/html" href="http://creativecommons.org/licenses/by-nc-sa/3.0/" /><entry gd:etag="W/&quot;CUYDRX45fip7ImA9WxBaEEw.&quot;"><id>tag:blogger.com,1999:blog-876358347971598886.post-8802370014286557164</id><published>2010-03-18T15:19:00.006+02:00</published><updated>2010-03-19T17:39:34.026+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-03-19T17:39:34.026+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="oltp" /><category scheme="http://www.blogger.com/atom/ns#" term="dbic" /><category scheme="http://www.blogger.com/atom/ns#" term="relational" /><category scheme="http://www.blogger.com/atom/ns#" term="object oriented" /><category scheme="http://www.blogger.com/atom/ns#" term="kiokudb" /><category scheme="http://www.blogger.com/atom/ns#" term="perl" /><category scheme="http://www.blogger.com/atom/ns#" term="database" /><title>What is a mixed schema?</title><content type="html">&lt;p&gt;&lt;a href="http://blog.woobling.org/2010/03/kiokudb-dbixclass.html"&gt;Yesterday's post&lt;/a&gt; is a technical one that says that KiokuDB and DBIx::Class can now be used together on the same schema. What it doesn't explain is what this is actually good for.&lt;/p&gt;

&lt;p&gt;Most of the application development we do involves &lt;a href="http://en.wikipedia.org/wiki/Online_transaction_processing"&gt;OLTP&lt;/a&gt; in one form or another. Some of the apps also do reporting on simple, highly regular data.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.iinteractive.com/kiokudb"&gt;KiokuDB&lt;/a&gt; grew out of the need to simplify the type of task we do most often. For the reporting side we are still trying to figure out what we like best. For example &lt;a href="http://stevan-little.blogspot.com"&gt;Stevan&lt;/a&gt; has been experimenting with &lt;a href="http://search.cpan.org/perldoc?Fey"&gt;&lt;tt&gt;Fey&lt;/tt&gt;&lt;/a&gt; (not &lt;a href="http://search.cpan.org/perldoc?Fey::ORM"&gt;&lt;tt&gt;Fey::ORM&lt;/tt&gt;&lt;/a&gt;) for the purely relational data.&lt;/p&gt;

&lt;p&gt;This approach has been far superior to what we had done before: forcing a loosely constructed, polymorphic set of objects with no reporting requirements into a normalized relational schema that's optimized for reporting applications. There is a also new, worse alternative, which is to run aggregate reports on several million data points as in memory objects with Perl ;-)&lt;/p&gt;

&lt;p&gt;However, the two pronged approach still has a major drawback: the two data sets are completely separate. There is no way to refer to data in the two sets without embedding knowlege about the database handles into the domain, which is tedious and annoying.&lt;/p&gt;

&lt;p&gt;What the new &lt;a href="http://search.cpan.org/perldoc?DBIx::Class"&gt;&lt;tt&gt;DBIx::Class&lt;/tt&gt;&lt;/a&gt; integration allows is to bridge that gap.&lt;/p&gt;

&lt;h2&gt;Concrete Example #1: Mixing KiokuDB into a DBIC centric app&lt;/h2&gt;

&lt;p&gt;Often times I would find myself making compromises about what sort of objects I put into a relational schema.&lt;/p&gt;

&lt;p&gt;There is a tension between &lt;a href="http://en.wikipedia.org/wiki/Polymorphism_in_object-oriented_programming"&gt;polymorphic&lt;/a&gt; &lt;a href=""&gt;graphs&lt;/a&gt; of objects and &lt;a href="http://en.wikipedia.org/wiki/Database_normalization"&gt;normalizd&lt;/a&gt; relational schema.&lt;/p&gt;

&lt;p&gt;Suppose you're writing an image gallery application, and you decide to add support for &lt;a href="http://www.youtube.com/"&gt;YouTube&lt;/a&gt; videos. Obviously YouTube videos should be treated as image objects in the UI, they should tile with the images, you should be able to rearrange them, add captions/tags, post comments, etc.&lt;/p&gt;

&lt;p&gt;This is precisely where polymorphism makes sense, you have two types of things that being used in a single context, but with a completely different representation. One is probably represented by a collection of files on disk, for the original image, previews, thumbnails, etc, and table entry of metadata. The other is represented by an opaque string ID, and most of its functionality is derived by generating calls to a web service.&lt;/p&gt;

&lt;p&gt;How do you put YouTube videos into your &lt;tt&gt;image&lt;/tt&gt; table? Do you add a &lt;tt&gt;type&lt;/tt&gt; column? What about a &lt;tt&gt;resource&lt;/tt&gt; table that has &lt;tt&gt;NULL&lt;/tt&gt;able foreign keys to the &lt;tt&gt;image&lt;/tt&gt; table and a &lt;tt&gt;NULL&lt;/tt&gt;able &lt;tt&gt;video_id&lt;/tt&gt; column? What about a &lt;tt&gt;blob&lt;/tt&gt; column containing serialized information about the data?&lt;/p&gt;

&lt;p&gt;With a mixed schema you could create a &lt;tt&gt;resource&lt;/tt&gt; table that has a foreign key to the KiokuDB entries table. You could use the resources table for things like random selection, searches, keeping track of views counts, etc.&lt;/p&gt;

&lt;p&gt;I'm going to assume that you're not really interested on running reports on which characters show up most often in the YouTube video IDs or what is the average length of image filenames, so that data can be opaque without compromising any features in your application.&lt;/p&gt;

&lt;p&gt;On a technical level this is is similar to using a serialized blob column approach, or some combination of &lt;a href="http://search.cpan.org/perldoc?DBIx::Class::DynamicSubclass"&gt;&lt;tt&gt;DBIx::Class::DynamicSubclass&lt;/tt&gt;&lt;/a&gt; and &lt;a href="http://search.cpan.org/perldoc?DBIx::Class::FrozenColumns"&gt;&lt;tt&gt;DBIx::Class::FrozenColumns&lt;/tt&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;However, by using KiokuDB these objects become first class citizens in your schema, instead of some "extra" data that is tacked on to a data row. You get a proper API for retrieving and updating real graphs of objects, much more powerful and automatable serialization, a large number of standard modules that are supported out of the box, etc.&lt;/p&gt;

&lt;p&gt;Perhaps most importantly, the encapsulation and notion of identity is maintained. You can share data between objects, and that data sharing is reflected consistently in memory. You can implement your &lt;tt&gt;MyApp::Resource::YouTubeVideo&lt;/tt&gt; and &lt;tt&gt;MyApp::Resource::Image&lt;/tt&gt; without worrying about mapping columns, or weird interactions with &lt;a href="http://search.cpan.org/perldoc?Storable"&gt;&lt;tt&gt;Storable&lt;/tt&gt;&lt;/a&gt;. That, to me, is the most liberating part of using KiokuDB.&lt;/p&gt;

&lt;h2&gt;Concrete Example #2: Mixing DBIC into a KiokuDB centric app&lt;/h2&gt;

&lt;p&gt;On the other side of the spectrum (of our apps, anyway) you'll find data models that are just too complicated to put into a relational schema easily; there are mixed data types all over the place, complex networks of data (we've put trees, graphs, DAGs, and other structures, sometimes all in a single app), and other things that are incredibly useful for rapid prototyping or complicated processing.&lt;/p&gt;

&lt;p&gt;This usually all works great until you need an aggregate data type at some point. That's when things fall apart. &lt;a href="http://search.cpan.org/perldoc?Search::GIN"&gt;&lt;tt&gt;Search::GIN&lt;/tt&gt;&lt;/a&gt; is not nearly as feature complete as I hoped it would be right now, in fact, it's barely a draft of a prototype. The &lt;a href="http://search.cpan.org/perldoc?KiokuDB::Backend::DBI"&gt;DBI Backend&lt;/a&gt;'s column extraction is a fantastically useful hack, but it's still just a hack at heart.&lt;/p&gt;

&lt;p&gt;But now we can freely refer to DBIC rows and resultsets just like we can in memory, from our OO schema, to help with these tasks.&lt;/p&gt;

&lt;p&gt;One of our apps used a linked list to represent a changelog of an object graph, somewhat similarly to Git's object store. After a few months of deployment, we got a performance issue from a client, a specific page was taking about 30 seconds to load. It turned out that normally only the last few revisions had to be queried, but on that specific cases a pathological data construction meant that over a thousand revisions were loaded from the database and had their data analyzed. Since this linked list structure is opaque, this was literally hitting the database thousands of times in a single request.&lt;/p&gt;

&lt;p&gt;I ended up using a crude cache to memoize some of the predicates, which let us just skip directly to the revision that had to be displayed.&lt;/p&gt;

&lt;p&gt;With the new features in the DBI backend I could simply create a table of revision containers (I would still need to store revisions in KiokuDB, because there were about 6 different revision types), on which I could do the entire operation with one select statement.&lt;/p&gt;

&lt;p&gt;Conceptually you can consider the DBIC result set as just an object oriented collection type. It's like any other object in KiokuDB, except that its data is backed by a much smarter representation than a serialized blob, the underlying data store understands it and can query its contents easily and efficiently. The drawback is that it requires some configuration, and it can only contain objects of the same data type, but these are very reasonable limitations, after all we've been living with them for years.&lt;/p&gt;

&lt;p&gt;It's all a bit like writing a custom typemap entry to better represent your data to the backend. In fact, this is pretty much exactly what I did to implement the feature ;-)&lt;/p&gt;

&lt;p&gt;This still requires making the effort to define a relational schema, but only where you need it, and only for data that make sense in a relational setting anyway. And it's probably less effort than writing a custom typemap to create a scalable/queriable collection type.&lt;/p&gt;

&lt;h2&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;Though still far from perfect, I feel that this really brings KiokuDB into a new level of usefulness; you no longer need to drink the kool aid and sacrifice a powerful tool and methodology you already know.&lt;/p&gt;

&lt;p&gt;Even though DBIC is not &lt;em&gt;everyone&lt;/em&gt;'s tool of choice and has its own drawbacks, I feel that is by far the most popular Perl ORM for a reason, which is why I chose to build on it. However, there's no reason why this approach can't be used for other backend types.&lt;/p&gt;

&lt;p&gt;Eventually I'd like to be able to see similar typemaps emerge for other backends. For example &lt;a href="http://search.cpan.org/perldoc?KiokuDB::Backend::Redis"&gt;the Redis backend&lt;/a&gt; could support &lt;a href="http://code.google.com/p/redis/"&gt;Redis'&lt;/a&gt; different &lt;a href="http://code.google.com/p/redis/wiki/IntroductionToRedisDataTypes"&gt;data types&lt;/a&gt;, &lt;a href="http://couchdb.apache.org/"&gt;CouchDB&lt;/a&gt; has design documents and views, and &lt;a href="http://riak.basho.com/"&gt;riak&lt;/a&gt;'s MapReduce jobs and queries (&lt;a href="http://lumberjaph.net/blog/"&gt;Franck&lt;/a&gt;'s backend is &lt;a href="http://github.com/franckcuny/kiokudb-backend-riak"&gt;on GitHub&lt;/a&gt;) could all be reflected as "just objects" that can coexist with other data in a KiokuDB object graph.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/876358347971598886-8802370014286557164?l=blog.woobling.org' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/yuvalkogman/~4/p6LmSYmf-ew" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.woobling.org/feeds/8802370014286557164/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=876358347971598886&amp;postID=8802370014286557164&amp;isPopup=true" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/876358347971598886/posts/default/8802370014286557164?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/876358347971598886/posts/default/8802370014286557164?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/yuvalkogman/~3/p6LmSYmf-ew/what-is-mixed-schema.html" title="What is a mixed schema?" /><author><name>nothingmuch</name><uri>http://www.blogger.com/profile/03975438115490089158</uri><email>nothingmuch@woobling.org</email><gd:extendedProperty name="OpenSocialUserId" value="04344917020781355723" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://blog.woobling.org/2010/03/what-is-mixed-schema.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0MDQX4zfyp7ImA9WxBbGUw.&quot;"><id>tag:blogger.com,1999:blog-876358347971598886.post-8222694014951455199</id><published>2010-03-17T16:42:00.006+02:00</published><updated>2010-03-18T15:37:50.087+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-03-18T15:37:50.087+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="dbic" /><category scheme="http://www.blogger.com/atom/ns#" term="relational" /><category scheme="http://www.blogger.com/atom/ns#" term="object oriented" /><category scheme="http://www.blogger.com/atom/ns#" term="kiokudb" /><category scheme="http://www.blogger.com/atom/ns#" term="perl" /><category scheme="http://www.blogger.com/atom/ns#" term="database" /><title>KiokuDB ♡ DBIx::Class</title><content type="html">&lt;p&gt;I just added a feature to &lt;a href="http://www.iinteractive.com/kiokudb"&gt;KiokuDB&lt;/a&gt;'s &lt;a href="http://github.com/nothingmuch/kiokudb-backend-dbi/"&gt;DBI&lt;/a&gt; backend that allows freely mixing &lt;a href="http://search.cpan.org/dist/DBIx-Class/"&gt;&lt;tt&gt;DBIx::Class&lt;/tt&gt;&lt;/a&gt; objects.&lt;/p&gt;

&lt;p&gt;This resolves KiokuDB's limitations with respect to sorting, aggregating and querying by letting you use &lt;tt&gt;DBIx::Class&lt;/tt&gt; for those objects, while still giving you KiokuDB's flexible schema for everything else.&lt;/p&gt;

&lt;p&gt;The first part of this is that you can refer to &lt;tt&gt;DBIx::Class&lt;/tt&gt; row objects from the objects stored in KiokuDB:&lt;/p&gt;

&lt;pre class="fake-gist" id="fake-gist-335340"&gt;my $dbic_object = $resultset-&amp;gt;find($primary_key);

$dir-&amp;gt;insert(
    some_id =&amp;gt; Some::Object-&amp;gt;new( some_attr =&amp;gt; $dbic_object ),
);&lt;/pre&gt;

&lt;p&gt;The second half is that relational objects managed by &lt;tt&gt;DBIx::Class&lt;/tt&gt; can specify &lt;tt&gt;belongs_to&lt;/tt&gt; type relationships (i.e. an inflated column) to any object in the KiokuDB &lt;tt&gt;entries&lt;/tt&gt; table:&lt;/p&gt;

&lt;pre class="fake-gist" id="fake-gist-335341"&gt;my $row = $rs-&amp;gt;create({ name =&amp;gt; "blah", object =&amp;gt; $anything );

$row-&amp;gt;insert;

say "Inserted ID for KiokuDB object: ",
    $dir-&amp;gt;object_to_id($row-&amp;gt;object);&lt;/pre&gt;

To set things up you need to tell &lt;tt&gt;DBIx::Class&lt;/tt&gt; about KiokuDB:

&lt;pre class="fake-gist" id="fake-gist-335342"&gt;package MyApp::Schema;
use base qw(DBIx::Class::Schema);

# load the KiokuDB schema component
# which adds the extra result sources
__PACKAGE__-&amp;gt;load_components(qw(Schema::KiokuDB));

__PACKAGE__-&amp;gt;load_namespaces;



package MyApp::Schema::Result::Foo;
use base qw(DBIx::Class);

# load the KiokuDB component:
__PACKAGE__-&amp;gt;load_components(qw(Core KiokuDB));

# do the normal stuff
__PACKAGE__-&amp;gt;table('foo');
__PACKAGE__-&amp;gt;add_columns(qw(id name object));
__PACKAGE__-&amp;gt;set_primary_key('id');

# setup a relationship column:
__PACKAGE__-&amp;gt;kiokudb_column('object');



# connect both together
my $dir = KiokuDB-&amp;gt;connect(
    dsn =&amp;gt; "dbi:SQLite:dbname=blah",
    schema_proto =&amp;gt; "MyApp::Schema",
);

my $schema = $dir-&amp;gt;backend-&amp;gt;schema;



# then you can do some work:
$dir-&amp;gt;txn_do( scope =&amp;gt; 1, body =&amp;gt; sub {
    my $rs = $schema-&amp;gt;resultset("Foo");
    my $obj = $rs-&amp;gt;find($primary_key)-&amp;gt;object;

    $obj-&amp;gt;change_something($something_else);

    $dir-&amp;gt;update($obj);
});&lt;/pre&gt;

&lt;p&gt;There are still a few missing features, and this is probably not production ready, but please try it out! &lt;strike&gt;A dev release will be out once I've documented it.&lt;/strike&gt; &lt;a href="http://search.cpan.org/dist/KiokuDB-Backend-DBI-1.11_01/"&gt;KiokuDB::Backend::DBI 0.11_01&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;In the future I hope to match all of &lt;a href="http://search.cpan.org/perldoc?Tangram"&gt;&lt;tt&gt;Tangram&lt;/tt&gt;&lt;/a&gt;'s features, enabling truly hybrid schemas. This would mean that KiokuDB could store objects in more than one table, with objects having any mixture of properly typed, normalized columns, opaque data BLOBs, or something in between (a bit like &lt;a href="http://search.cpan.org/perldoc?DBIx::Class::DynamicSubclass"&gt;&lt;tt&gt;DBIx::Class::DynamicSubclass&lt;/tt&gt;&lt;/a&gt; and &lt;a href="http://search.cpan.org/perldoc?DBIx::Class::FrozenColumns"&gt;&lt;tt&gt;DBIx::Class::FrozenColumns&lt;/tt&gt;&lt;/a&gt;, but with more flexibility and less setup).&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/876358347971598886-8222694014951455199?l=blog.woobling.org' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/yuvalkogman/~4/yaEjA81zN0w" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.woobling.org/feeds/8222694014951455199/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=876358347971598886&amp;postID=8222694014951455199&amp;isPopup=true" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/876358347971598886/posts/default/8222694014951455199?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/876358347971598886/posts/default/8222694014951455199?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/yuvalkogman/~3/yaEjA81zN0w/kiokudb-dbixclass.html" title="KiokuDB ♡ DBIx::Class" /><author><name>nothingmuch</name><uri>http://www.blogger.com/profile/03975438115490089158</uri><email>nothingmuch@woobling.org</email><gd:extendedProperty name="OpenSocialUserId" value="04344917020781355723" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://blog.woobling.org/2010/03/kiokudb-dbixclass.html</feedburner:origLink></entry><entry gd:etag="W/&quot;AkcBSXY-eCp7ImA9WxBbFU4.&quot;"><id>tag:blogger.com,1999:blog-876358347971598886.post-2644983427671433041</id><published>2010-03-14T05:31:00.009+02:00</published><updated>2010-03-14T05:40:58.850+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-03-14T05:40:58.850+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="spotlight" /><category scheme="http://www.blogger.com/atom/ns#" term="git" /><category scheme="http://www.blogger.com/atom/ns#" term="backups" /><title>git snapshot</title><content type="html">&lt;span style="font-style:italic;"&gt;&lt;/span&gt;&lt;p&gt;I've just uploaded a new tool, &lt;a href="http://github.com/nothingmuch/git-snapshot/"&gt;git snapshot&lt;/a&gt;, which lets you routinely capture snapshots of your working directory, and records them in parallel to your explicitly recorded history.&lt;/p&gt;

&lt;p&gt;The snapshot revisions stay out of the way for the most part, but if you need to view them you can look at them, for example using &lt;tt&gt;&lt;a href="http://gitx.frim.nl/"&gt;gitx&lt;/a&gt; refs/snapshots/HEAD&lt;/tt&gt;&lt;/p&gt;

&lt;p&gt;For me this is primarily useful when I'm sketching out a new project and forgetting to commit anything. When working on a large patch I usually use &lt;tt&gt;git commit -a --amend -C HEAD&lt;/tt&gt; fairly often, which in conjunction with &lt;tt&gt;git &lt;a href="http://www.gitready.com/intermediate/2009/02/09/reflog-your-safety-net.html"&gt;reflog&lt;/a&gt;&lt;/tt&gt; provides similar safety. However, &lt;tt&gt;git snapshot&lt;/tt&gt; is designed to work well in either scenario.&lt;/p&gt;

&lt;p&gt;I have a crontab set up to use &lt;a href="http://developer.apple.com/mac/library/DOCUMENTATION/Darwin/Reference/ManPages/man1/mdfind.1.htmlA"&gt;mdfind&lt;/a&gt; so that all directories with the red label are snapshotted once an hour.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/876358347971598886-2644983427671433041?l=blog.woobling.org' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/yuvalkogman/~4/D-KjOvkHWPI" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.woobling.org/feeds/2644983427671433041/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=876358347971598886&amp;postID=2644983427671433041&amp;isPopup=true" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/876358347971598886/posts/default/2644983427671433041?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/876358347971598886/posts/default/2644983427671433041?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/yuvalkogman/~3/D-KjOvkHWPI/git-snapshot.html" title="&lt;tt&gt;git snapshot&lt;/tt&gt;" /><author><name>nothingmuch</name><uri>http://www.blogger.com/profile/03975438115490089158</uri><email>nothingmuch@woobling.org</email><gd:extendedProperty name="OpenSocialUserId" value="04344917020781355723" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">2</thr:total><feedburner:origLink>http://blog.woobling.org/2010/03/git-snapshot.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CUQFSX8zeCp7ImA9WxBUGE0.&quot;"><id>tag:blogger.com,1999:blog-876358347971598886.post-2399456088063444272</id><published>2010-03-03T20:15:00.001+02:00</published><updated>2010-03-05T17:35:18.180+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-03-05T17:35:18.180+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="modules" /><category scheme="http://www.blogger.com/atom/ns#" term="kiokudb" /><category scheme="http://www.blogger.com/atom/ns#" term="perl" /><title>KiokuDB Introduces Schema Versioning</title><content type="html">&lt;p&gt;I've just released &lt;a href="http://search.cpan.org/dist/KiokuDB"&gt;KiokuDB&lt;/a&gt; version &lt;a href="http://cpansearch.perl.org/src/NUFFIN/KiokuDB-0.37/Changes"&gt;0.37&lt;/a&gt;, which introduces class versioning.&lt;/p&gt;

&lt;p&gt;This feature is &lt;em&gt;disabled&lt;/em&gt; by default to avoid introducing errors to existing schemas&lt;sup&gt;&lt;a href="#0582E125-4992-4913-A217-C1680E067A1B" name="71CDC4C9-3810-461B-A72C-F95B42BE9D78"&gt;[1]&lt;/a&gt;&lt;/sup&gt;. To try it out pass &lt;tt&gt;check_class_versions =&amp;gt; 1&lt;/tt&gt; to &lt;tt&gt;connect&lt;/tt&gt;:&lt;/p&gt;

&lt;pre class="fake-gist" id="fake-gist-320734"&gt;KiokuDB-&amp;gt;connect(
    dsn =&amp;gt; ...,
    check_class_versions =&amp;gt; 1,
);&lt;/pre&gt;

&lt;p&gt;To use this feature, whenever you make an incompatible change to a class, also change the &lt;tt&gt;$VERSION&lt;/tt&gt;. When KiokuDB tries to load an object that has been stored before the change was made, the version mismatch is detected (versions are only compared as strings, there is no meaning to the values).&lt;/p&gt;

&lt;p&gt;Without any configuration this mismatch will result in an error at load time, but the &lt;a href="http://search.cpan.org/perldoc?KiokuDB::Role::Upgrade::Handlers::Table"&gt;&lt;tt&gt;KiokuDB::Role::Upgrade::Handlers::Table&lt;/tt&gt;&lt;/a&gt; role allows you to declaratively add upgrade handlers to your classes:&lt;/p&gt;

&lt;pre class="fake-gist" id="fake-gist-320735"&gt;package Foo;
use Moose;

with qw(KiokuDB::Role::Upgrade::Handlers::Table);

use constant kiokudb_upgrade_handlers_table =&amp;gt; {

    # we can mark versions as being equivalent in terms of their
    # data. 0.01 to 0.02 may have introduced an incompatible API
    # change, but the stored data should be compatible
    "0.01" =&amp;gt; "0.02",

    # on the other hand, after 0.02 there may have been an
    # incompatible data change, so we need to convert
    "0.02" =&amp;gt; sub {
        my ( $self, %args ) = @_;

        return $args{entry}-&amp;gt;derive(
            class_version =&amp;gt; our $VERSION, # up to date version
            data =&amp;gt; ..., # converted entry data
        );
    },
};&lt;/pre&gt;

&lt;p&gt;For more details see the documentation, especially &lt;a href="http://search.cpan.org/perldoc?KiokuDB::TypeMap::Entry::MOP"&gt;&lt;tt&gt;KiokuDB::TypeMap::Entry::MOP&lt;/tt&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;sup&gt;&lt;a name="0582E125-4992-4913-A217-C1680E067A1B" href="#71CDC4C9-3810-461B-A72C-F95B42BE9D78"&gt;[1]&lt;/a&gt;&lt;/sup&gt; In the future this might be enabled by default, but when data without any version information is found in the database it is assumed to be up to date.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/876358347971598886-2399456088063444272?l=blog.woobling.org' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/yuvalkogman/~4/Ez7wAqwbDLo" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.woobling.org/feeds/2399456088063444272/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=876358347971598886&amp;postID=2399456088063444272&amp;isPopup=true" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/876358347971598886/posts/default/2399456088063444272?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/876358347971598886/posts/default/2399456088063444272?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/yuvalkogman/~3/Ez7wAqwbDLo/kiokudb-introduces-schema-versioning.html" title="KiokuDB Introduces Schema Versioning" /><author><name>nothingmuch</name><uri>http://www.blogger.com/profile/03975438115490089158</uri><email>nothingmuch@woobling.org</email><gd:extendedProperty name="OpenSocialUserId" value="04344917020781355723" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">1</thr:total><feedburner:origLink>http://blog.woobling.org/2010/03/kiokudb-introduces-schema-versioning.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkEASXc-eCp7ImA9WxBWEEk.&quot;"><id>tag:blogger.com,1999:blog-876358347971598886.post-6125596033217946257</id><published>2010-02-01T16:27:00.002+02:00</published><updated>2010-02-01T18:10:48.950+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-02-01T18:10:48.950+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="fail" /><category scheme="http://www.blogger.com/atom/ns#" term="object oriented" /><category scheme="http://www.blogger.com/atom/ns#" term="perl" /><title>$obj-&gt;blessed</title><content type="html">&lt;p&gt;I've been meaning to write about this gotcha for a long time, but somehow forgot. This was actually an undiscovered bug in Moose for several &lt;em&gt;years&lt;/em&gt;:&lt;/p&gt;

&lt;pre class="fake-gist" id="fake-gist-291746"&gt;use strict;
use warnings;

use Test::More;

use Try::Tiny qw(try);

{
    package Foo;

    use Scalar::Util qw(blessed);

    sub new { bless {}, $_[0] }
}

my $foo = Foo-&amp;gt;new;

is( try { blessed($foo) }, undef );

is( try { blessed $foo }, undef );

done_testing;&lt;/pre&gt;

&lt;p&gt;The first test passes. &lt;tt&gt;blessed&lt;/tt&gt; has't been imported into &lt;tt&gt;main&lt;/tt&gt;, so the code results in the error &lt;tt&gt;Undefined subroutine &amp;amp;main::blessed&lt;/tt&gt;.&lt;/p&gt;

&lt;p&gt;The second test, on the other hand, fails. This is because &lt;tt&gt;blessed&lt;/tt&gt; has been invoked as a method on &lt;tt&gt;$foo&lt;/tt&gt;.&lt;/p&gt;

&lt;p&gt;The Moose codebase had several instances of &lt;tt&gt;if ( blessed $object )&lt;/tt&gt;, in packages that did not import &lt;tt&gt;blessed&lt;/tt&gt; at all. This worked for ages, because &lt;tt&gt;Moose::Object&lt;/tt&gt;, the base class for most objects in the Moose ecosystem, didn't clean up that export, and therefore provided an inherited &lt;tt&gt;blessed&lt;/tt&gt; method for pretty much any class written in Moose.&lt;/p&gt;

&lt;p&gt;I think this example provides a very strong case for using &lt;a href="http://search.cpan.org/perldoc?namespace::clean"&gt;&lt;tt&gt;namespace::clean&lt;/tt&gt;&lt;/a&gt; or &lt;a href="http://search.cpan.org/perldoc?namespace::autoclean"&gt;&lt;tt&gt;namespace::autoclean&lt;/tt&gt;&lt;/a&gt; routinely in your classes.&lt;/p&gt;

&lt;p&gt;To cover the other half of the &lt;a href="http://www.shadowcat.co.uk/blog/matt-s-trout/indirect-but-still-fatal/"&gt;problem&lt;/a&gt;, the &lt;tt&gt;no &lt;a href="http://search.cpan.org/perldoc?indirect"&gt;indirect&lt;/a&gt;&lt;/tt&gt; pragma allows the removal of this unfortunate feature from specific lexical scopes.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/876358347971598886-6125596033217946257?l=blog.woobling.org' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/yuvalkogman/~4/crxMY9iKYHA" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.woobling.org/feeds/6125596033217946257/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=876358347971598886&amp;postID=6125596033217946257&amp;isPopup=true" title="1 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/876358347971598886/posts/default/6125596033217946257?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/876358347971598886/posts/default/6125596033217946257?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/yuvalkogman/~3/crxMY9iKYHA/obj.html" title="&lt;tt&gt;$obj-&amp;gt;blessed&lt;/tt&gt;" /><author><name>nothingmuch</name><uri>http://www.blogger.com/profile/03975438115490089158</uri><email>nothingmuch@woobling.org</email><gd:extendedProperty name="OpenSocialUserId" value="04344917020781355723" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">1</thr:total><feedburner:origLink>http://blog.woobling.org/2010/02/obj.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkUERHY4fip7ImA9WxBRF0U.&quot;"><id>tag:blogger.com,1999:blog-876358347971598886.post-2604505410827748772</id><published>2010-01-06T15:12:00.004+02:00</published><updated>2010-01-06T15:23:25.836+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-01-06T15:23:25.836+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="keywurl" /><category scheme="http://www.blogger.com/atom/ns#" term="quicksearch" /><category scheme="http://www.blogger.com/atom/ns#" term="safari" /><category scheme="http://www.blogger.com/atom/ns#" term="chrome" /><category scheme="http://www.blogger.com/atom/ns#" term="perl" /><title>Importing Keywurl searches to Chrome</title><content type="html">&lt;p&gt;I've recently switched to using &lt;a href="http://www.google.com/chrome"&gt;Chrome&lt;/a&gt;. I used &lt;a href="http://alexstaubo.github.com/keywurl/"&gt;Keywurl&lt;/a&gt; extensively with Safari. Here's a script that imports the Keywurl searches into Chrome:&lt;/p&gt;

&lt;pre id="fake-gist-270267" class="fake-gist"&gt;#!/usr/bin/perl

use strict;
use warnings;

use Mac::PropertyList qw(parse_plist_file);
use DBI;

my $app_support = &amp;quot;$ENV{HOME}/Library/Application Support&amp;quot;;

my $dbh = DBI-&amp;gt;connect(&amp;quot;dbi:SQLite:dbname=$app_support/Google/Chrome/Default/Web Data&amp;quot;);

my $plist = parse_plist_file(&amp;quot;$app_support/Keywurl/Keywords.plist&amp;quot;);

my $keywords = $plist-&amp;gt;{keywords};

$dbh-&amp;gt;begin_work;

my $t = time;

my $sth = $dbh-&amp;gt;prepare(qq{
    INSERT INTO keywords VALUES (
        NULL, -- id
        ?,    -- name
        ?,    -- keyword
        &amp;quot;&amp;quot;,   -- favicon url
        ?,    -- url
        0,    -- show in default list
        0,    -- safe for auto replace
        &amp;quot;&amp;quot;,   -- originating URL
        $t,   -- date created
        0,    -- usage count
        &amp;quot;&amp;quot;,   -- input encodings
        &amp;quot;&amp;quot;,   -- suggest url
        0,    -- prepopulate id
        0     -- autogenerate keyword
    )
});

foreach my $link ( keys %$keywords ) {
    my $data = $keywords-&amp;gt;{$link};

    my $url = $data-&amp;gt;{expansion}-&amp;gt;value;

    $url =~ s/\{query\}/{searchTerms}/g;

    $sth-&amp;gt;execute(
        $link, # name
        $link, # keyword
        $url,
    );
}

$dbh-&amp;gt;commit;
&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/876358347971598886-2604505410827748772?l=blog.woobling.org' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/yuvalkogman/~4/1vEXbOzHxKc" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.woobling.org/feeds/2604505410827748772/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=876358347971598886&amp;postID=2604505410827748772&amp;isPopup=true" title="4 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/876358347971598886/posts/default/2604505410827748772?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/876358347971598886/posts/default/2604505410827748772?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/yuvalkogman/~3/1vEXbOzHxKc/importing-keywurl-searches-to-chrome.html" title="Importing Keywurl searches to Chrome" /><author><name>nothingmuch</name><uri>http://www.blogger.com/profile/03975438115490089158</uri><email>nothingmuch@woobling.org</email><gd:extendedProperty name="OpenSocialUserId" value="04344917020781355723" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">4</thr:total><feedburner:origLink>http://blog.woobling.org/2010/01/importing-keywurl-searches-to-chrome.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0AFQH85eyp7ImA9WxBTGUo.&quot;"><id>tag:blogger.com,1999:blog-876358347971598886.post-3782083627793925934</id><published>2009-12-16T18:01:00.004+02:00</published><updated>2009-12-16T18:08:31.123+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-12-16T18:08:31.123+02:00</app:edited><title>Ironman FAIL</title><content type="html">&lt;p&gt;Oops... I moved back to Chamonix over the weekend and completely forgot about blogging.&lt;/p&gt;

&lt;p&gt;I guess I'll take a few days to get settled in and then start writing again. I'm aiming for chartreuse with alternating red and monkeyshit highlights and a fishnet, but unfortunately mst has been blogging much more consistently than me so far.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/876358347971598886-3782083627793925934?l=blog.woobling.org' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/yuvalkogman/~4/E5LRtPSOAOg" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.woobling.org/feeds/3782083627793925934/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=876358347971598886&amp;postID=3782083627793925934&amp;isPopup=true" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/876358347971598886/posts/default/3782083627793925934?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/876358347971598886/posts/default/3782083627793925934?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/yuvalkogman/~3/E5LRtPSOAOg/ironman-fail.html" title="Ironman FAIL" /><author><name>nothingmuch</name><uri>http://www.blogger.com/profile/03975438115490089158</uri><email>nothingmuch@woobling.org</email><gd:extendedProperty name="OpenSocialUserId" value="04344917020781355723" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://blog.woobling.org/2009/12/ironman-fail.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEUGQXY8fip7ImA9WxBTEkU.&quot;"><id>tag:blogger.com,1999:blog-876358347971598886.post-3098464960358922382</id><published>2009-12-04T01:54:00.003+02:00</published><updated>2009-12-08T16:23:40.876+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-12-08T16:23:40.876+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="moose" /><category scheme="http://www.blogger.com/atom/ns#" term="perl" /><category scheme="http://www.blogger.com/atom/ns#" term="hack" /><title>Simplifying BEGIN { } with Moose roles</title><content type="html">&lt;p&gt;This is a common Perl pattern:&lt;/p&gt;

&lt;pre class="fake-gist" id="fake-gist-248685"&gt;package MyClass;
use Moose

use Try::Tiny;

use namespace::autoclean;

BEGIN {
    if ( try { require Foo; 1 } ) {
        *bar = sub {
            my $self = shift;
            Foo::foo($self-&amp;gt;baz);
        };
    } else {
        *bar = sub {
            ... # fallback implementation
        };
    }
}&lt;/pre&gt;


&lt;p&gt;However, since this is a &lt;a href="http://moose.perl.org/"&gt;Moose&lt;/a&gt; class there is another way:&lt;/p&gt;

&lt;pre class="fake-gist" id="fake-gist-248687"&gt;package MyClass;
use Moose

use Try::Tiny;

use namespace::autoclean;

with try { require Foo; 1 }
    ? "MyClass::Bar::Foo"
    : "MyClass::Bar::Fallback";&lt;/pre&gt;


&lt;pre class="fake-gist" id="fake-gist-248688"&gt;package MyClass::Foo;
use Moose::Role;

use Foo qw(foo);

use namespace::autoclean;

sub bar {
    my $self = shift;

    foo($self-&amp;gt;baz);
}&lt;/pre&gt;

&lt;pre class="fake-gist" id="fake-gist-248689"&gt;package MyClass::Bar::Fallback;
use Moose::Role;

use namespace::autoclean;

sub bar {
    ...; # fallback implementation
}&lt;/pre&gt;

&lt;p&gt;Obviously for something that simple it doesn't make sense, but if there is more than one method involved, or the fallback implementation is a little long, it really helps readability in my opinion. Going one step further, you can create an abstract role like this:&lt;/p&gt;

&lt;pre class="fake-gist" id="fake-gist-248690"&gt;package MyClass::Bar::API;
use Moose::Role;

use namespace::autoclean;

requires "bar";&lt;/pre&gt;

&lt;p&gt;and add it to the class's &lt;tt&gt;with&lt;/tt&gt; statement to validate that all the required methods are really provided by one of the roles.&lt;/p&gt;

&lt;p&gt;Role inclusion is usually thought of as something very static, but dynamism can be very handy without doesn't hurting the structure of the code.&lt;/p&gt;

&lt;small&gt;If you want to be pedantic the role inclusion is not at compile time, but the loading of &lt;tt&gt;Foo&lt;/tt&gt; is done at compile time inside the role (&lt;tt&gt;Foo&lt;/tt&gt; is usually why it was in a &lt;tt&gt;BEGIN&lt;/tt&gt; block in the first place, in most of the code I've seen).&lt;/small&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/876358347971598886-3098464960358922382?l=blog.woobling.org' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/yuvalkogman/~4/_hWAoDac7VM" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.woobling.org/feeds/3098464960358922382/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=876358347971598886&amp;postID=3098464960358922382&amp;isPopup=true" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/876358347971598886/posts/default/3098464960358922382?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/876358347971598886/posts/default/3098464960358922382?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/yuvalkogman/~3/_hWAoDac7VM/simplifying-begin-with-moose-roles.html" title="Simplifying &lt;tt&gt;BEGIN { }&lt;/tt&gt; with Moose roles" /><author><name>nothingmuch</name><uri>http://www.blogger.com/profile/03975438115490089158</uri><email>nothingmuch@woobling.org</email><gd:extendedProperty name="OpenSocialUserId" value="04344917020781355723" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">3</thr:total><feedburner:origLink>http://blog.woobling.org/2009/12/simplifying-begin-with-moose-roles.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkYBSHY7cCp7ImA9WxNaEkU.&quot;"><id>tag:blogger.com,1999:blog-876358347971598886.post-1675309162246370786</id><published>2009-11-26T23:07:00.002+02:00</published><updated>2009-11-27T02:02:39.808+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-11-27T02:02:39.808+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="functional programming" /><category scheme="http://www.blogger.com/atom/ns#" term="simplicity" /><category scheme="http://www.blogger.com/atom/ns#" term="perl" /><title>The timing of values in imperative APIs</title><content type="html">&lt;p&gt;Option configuration is a classic example of when I prefer a purely functional approach. This post is not &lt;a href="http://blog.woobling.org/2009/11/functional-programming-and-unreasonable.html"&gt;about broken semantics&lt;/a&gt;, but rather about the tension between ease of implementation and ease of use.&lt;/p&gt;

&lt;p&gt;Given Perl's imperative heritage, many modules default to imperative option specification. This means that the choice of one behavior over another is represented by an action (setting the option), instead of a value.&lt;/p&gt;

&lt;p&gt;Actions are far more complicated than values. For starters, they are part of an ordered sequence. Secondly, it's hard to know what the complete set of choices is, and it's hard to correlate between choices. And of course the actual values must still be moved around.&lt;/p&gt;

&lt;p&gt;A simple example is Perl's built in &lt;tt&gt;import&lt;/tt&gt; mechanism.&lt;/p&gt;

&lt;p&gt;When you &lt;tt&gt;use&lt;/tt&gt; a module, you are providing a list of arguments that passed to two optional method calls on the module being loaded, &lt;tt&gt;import&lt;/tt&gt; and &lt;tt&gt;VERSION&lt;/tt&gt;.&lt;/p&gt;

&lt;p&gt;Most people know that this:&lt;/p&gt;

&lt;pre class="fake-gist" id="fake-gist-243454"&gt;use Foo;&lt;/pre&gt;

&lt;p&gt;Is pretty much the same as this:&lt;/p&gt;

&lt;pre class="fake-gist" id="fake-gist-243455"&gt;BEGIN {
    require Foo;
    Foo-&amp;gt;import();
}&lt;/pre&gt;

&lt;p&gt;There's also a secondary syntax, which allows you to specify a version:&lt;/p&gt;

&lt;pre class="fake-gist" id="fake-gist-243456"&gt;use Foo 0.13 qw(foo bar);&lt;/pre&gt;

&lt;p&gt;The effect is the same as:&lt;/p&gt;

&lt;pre class="fake-gist" id="fake-gist-243457"&gt;BEGIN {
    require Foo;
    Foo-&amp;gt;VERSION(0.13);
    Foo-&amp;gt;import(qw(foo bar));
}&lt;/pre&gt;

&lt;p&gt;&lt;tt&gt;UNIVERSAL::VERSION&lt;/tt&gt; is pretty simple, it looks at the version number and compares it with &lt;tt&gt;$Foo::VERSION&lt;/tt&gt; and then complains loudly if &lt;tt&gt;$Foo::VERSION&lt;/tt&gt; isn't recent enough.&lt;/p&gt;

&lt;p&gt;But what if we wanted to do something more interesting, for instance adapt the exported symbols to be compatible with a certain API version?&lt;/p&gt;

&lt;p&gt;This is precisely why &lt;tt&gt;VERSION&lt;/tt&gt; is an overridable class method, but this flexibility is still very far from ideal.&lt;/p&gt;

&lt;pre class="fake-gist" id="fake-gist-243458"&gt;my $import_version;

sub VERSION {
    my ( $class, $version ) = @_;

    # first verify that we are recent enough
    $class-&amp;gt;SUPER::VERSION($version);

    # stash the value that the user specified
    $import_version = $version;
}

sub import {
    my ( $class, @import ) = @_;

    # get the stashed value
    my $version = $import_version;

    # clear it so it doesn't affect subsequent imports
    undef $import_version;

    ... # use $version and @imports to set things up correctly
}&lt;/pre&gt;

&lt;p&gt;This is a shitty solution because really all we want is a simple value, but we have to juggle it around using a shared variable.&lt;/p&gt;

&lt;p&gt;Since the semantics of &lt;tt&gt;import&lt;/tt&gt; would have been made more complex by adding this rather esoteric feature, the API was made imperative instead, to allow things to be optional.&lt;/p&gt;

&lt;p&gt;But the above code is not only ugly, it's also broken. Consider this case:&lt;/p&gt;

&lt;pre class="fake-gist" id="fake-gist-243459"&gt;package Evil;
use Foo 0.13 (); # require Foo; Foo-&amp;gt;VERSION;

package Innocent;
use Foo qw(foo bar); # require Foo; Foo-&amp;gt;import;&lt;/pre&gt;

&lt;p&gt;In the above code, &lt;tt&gt;Evil&lt;/tt&gt; is causing &lt;tt&gt;$import_version&lt;/tt&gt; to be set, but &lt;tt&gt;import&lt;/tt&gt; is never called. The next invocation of &lt;tt&gt;import&lt;/tt&gt; comes from a completely unrelated consumer, but &lt;tt&gt;$import_version&lt;/tt&gt; never got cleared.&lt;/p&gt;

&lt;p&gt;We can't use &lt;tt&gt;local&lt;/tt&gt; to keep &lt;tt&gt;$import_version&lt;/tt&gt; properly scoped (it'd be cleared before &lt;tt&gt;import&lt;/tt&gt; is called). The best solution I can come up with is to key it in a hash by &lt;tt&gt;caller()&lt;/tt&gt;, which at least prevents pollution. This is something every implementation of &lt;tt&gt;VERSION&lt;/tt&gt; that wants to pass the version to &lt;tt&gt;import&lt;/tt&gt; must do to be robust.&lt;/p&gt;

&lt;p&gt;However, even if we isolate consumers from each other, the nonsensical usage &lt;tt&gt;use Foo 0.13 ()&lt;/tt&gt; which asks for a versioned API and then proceeds to import nothing, still can't be detected by &lt;tt&gt;Foo&lt;/tt&gt;.&lt;/p&gt;

&lt;p&gt;We have 3 * 2 = 6 different code paths&lt;a name="E7C2927D-1E8F-467D-A994-F0017688FF8B" href="#33128C52-07EF-4416-BFCA-44FCE2AFF977"&gt;&lt;sup&gt;[1]&lt;/sup&gt;&lt;/a&gt; for the different variants of &lt;tt&gt;use Foo&lt;/tt&gt;, one of which doesn't even make sense (&lt;tt&gt;VERSION&lt;/tt&gt; but no &lt;tt&gt;import&lt;/tt&gt;), two of which have an explicit stateful dependency between two parts of the code paths (&lt;tt&gt;VERSION&lt;/tt&gt; followed by &lt;tt&gt;import&lt;/tt&gt;, in two variants), and two of which have an implicit stateful dependency (&lt;tt&gt;import&lt;/tt&gt; without &lt;tt&gt;VERSION&lt;/tt&gt; should get &lt;tt&gt;undef&lt;/tt&gt; in &lt;tt&gt;$import_version&lt;/tt&gt;). This sort of combinatorial complexity places the burden of ensuring correctness on the implementors of the API, instead of the designer of the API.&lt;/p&gt;

&lt;p&gt;It seems that the original design goal was to minimize the complexity of the most common case (&lt;tt&gt;use Foo&lt;/tt&gt;, no &lt;tt&gt;VERSION&lt;/tt&gt;, and &lt;tt&gt;import&lt;/tt&gt; called with no arguments), but it really makes things difficult for the non default case, somewhat defeating the point of making it extensible in the first place (what good is an extensible API if nobody actually uses it to its full potential).&lt;/p&gt;

&lt;p&gt;In such cases my goal is often to avoid fragmenting the data as much as possible. If the version was an argument to &lt;tt&gt;import&lt;/tt&gt; which defaulted to &lt;tt&gt;undef&lt;/tt&gt; people would complain, but that's just because &lt;tt&gt;import&lt;/tt&gt; uses positional arguments. Unfortunately you don't really see this argument passing style in the Perl core:&lt;/p&gt;

&lt;pre class="fake-gist" id="fake-gist-243460"&gt;sub import {
    my ( $class, %args ) = @_;

    if ( exists $args{version} ) {
        ...
    }
    ... $args{import_list};
}&lt;/pre&gt;

&lt;p&gt;This keeps the values together in both space and time. The closest thing I can recall from core Perl is something like &lt;tt&gt;$AUTOLOAD&lt;/tt&gt;. &lt;tt&gt;$AUTOLOAD&lt;/tt&gt; does not address space fragmentation (an argument is being passed using a a variable instead of an argument), but it at leasts solves the fragmentation in time, the variable is &lt;em&gt;reliably&lt;/em&gt; set just before the &lt;tt&gt;AUTOLOAD&lt;/tt&gt; routine is invoked.&lt;/p&gt;

&lt;p&gt;Note that if &lt;tt&gt;import&lt;/tt&gt; worked like this it would still be far from pure, it mutates the symbol table of its caller, but the actual computation of the symbols to export can and should be side effect free, and if the version were specified in this way that would have been easier.&lt;/p&gt;

&lt;p&gt;This is related to the &lt;a href="http://c2.com/cgi/wiki?IntentionNotAlgorithm"&gt;distinction between intention and algorithm&lt;/a&gt;. Think of it this way: when you say &lt;tt&gt;use Foo 0.13 qw(foo bar)&lt;/tt&gt;, do you intend to import a specific version of the API, or do you intend to call a method to set the version of the API and then call a method to import the API? The declarative syntax has a close affinity to the intent. On the other hand, looking at it from the perspective of &lt;tt&gt;Foo&lt;/tt&gt;, where the intent is to export a specific version of the API, the code structure does not reflect that at all.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://blogs.perl.org/users/ovid/"&gt;Ovid&lt;/a&gt; wrote about a &lt;a href="http://use.perl.org/~Ovid/journal/39878"&gt;similar issue with Test::Builder&lt;/a&gt;, where a procedural approach was taken (diagnosis output is treated as "extra" stuff, not really a part of a test case's data).&lt;/p&gt;

&lt;p&gt;&lt;a href="http://moose.perl.org"&gt;Moose&lt;/a&gt; also suffers from this issue in its sugar layer. When a Moose class is declared the class definition is modified step by step, causing load time performance issues, order sensitivity (often you need to include a role after declaring an attribute for required method validation), etc.&lt;/p&gt;

&lt;p&gt;Lastly, &lt;a href="http://plackperl.org/"&gt;PSGI&lt;/a&gt;'s raison d'etre is that the &lt;tt&gt;CGI&lt;/tt&gt; interface is based on stateful values (&lt;tt&gt;%ENV&lt;/tt&gt;, globally filehandles). The gist of the PSGI spec is encapsulating those values into explicit arguments, without needing to &lt;a href="http://search.cpan.org/perldoc?HTTP::Request::AsCGI"&gt;imperatively monkeypatch global state&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I think the reason we tend to default to imperative configuration is out of a short sighted laziness&lt;a href="#5724A963-16E7-461D-9A68-3F639EAAC278" name="6A5E5B98-5537-438E-9250-1B5193BA3152"&gt;&lt;sup&gt;[2]&lt;/sup&gt;&lt;/a&gt;. It seems like it's easier to be imperative, when you are thinking about usage. For instance, creating a data type to encapsulate arguments is tedius. Dealing with optional vs. required arguments manually is even more so. Simply forcing the user to specify everything is not very Perlish. This is where the tension lies.&lt;/p&gt;

&lt;p&gt;The best compromise I've found is a multilayered approach. At the foundation I provide a low level, explicit API where all of the options are required all at once, and cannot be changed afterwords. This keeps the combinatorial complexity down and lets me do more complicated validation of dependent options. On top of that I can easily build a convenience layer which accumulates options from an imperative API and then provides them to the low level API &lt;em&gt;all at once&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;This was not done in Moose because at the time we did not know to detect the end of a &lt;tt&gt;.pm&lt;/tt&gt; file, so we couldn't know when the declaration was finished&lt;a name="D4C439D9-5E77-4024-98B9-DCE196EF1176" href="#12348E3B-2F94-4A48-9C3C-61EE2BFED643"&gt;&lt;sup&gt;[3]&lt;/sup&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Going back to &lt;tt&gt;VERSION&lt;/tt&gt; and &lt;tt&gt;import&lt;/tt&gt;, this approach would involve capturing the values as best we in a thin &lt;tt&gt;import&lt;/tt&gt; (the sugar layer), and passing them onwards together to some underlying implementation that doesn't need to worry about the details of collecting those values.&lt;/p&gt;

&lt;p&gt;In my opinion most of the time an API doesn't actually merit a convenience wrapper, but if it does then it's easy to develop one. Building on a more verbose but ultimately simpler foundation usually makes it much easier to write something that is correct, robust, and reusable. More importantly, the implementation is also easier to modify or even just replace (using polymorphism), since all the stateful dependencies are encapsulated by a dumb sugar layer.&lt;/p&gt;

&lt;p&gt;Secondly, when the sugar layer is getting in the way, it can just be ignored. Instead of needing to hack around something, you just need to be a little more verbose.&lt;/p&gt;

&lt;p&gt;Lastly, I'd also like to cite the &lt;a href="http://en.wikipedia.org/wiki/Unix_philosophy"&gt;Unix philosophy&lt;/a&gt;, another strong influence on Perl: do one thing, and do it well&lt;a href="#E575E230-D706-447B-90BE-BB2A641B4C51" name="4A5F8736-E00A-4EB4-83BC-3AB5C89E24C5"&gt;&lt;sup&gt;[4]&lt;/sup&gt;&lt;/a&gt;. The anti pattern is creating one thing that provides two features: a shitty convenience layer and a limited solution to the original problem. Dealing with each concern separately helps to focus on doing the important part, and of course doing it well ;-)&lt;/p&gt;

&lt;p&gt;This post's subject matter is obviously related to another procedural anti-pattern (&lt;tt&gt;$foo-&amp;gt;do_work; my $results = $foo-&amp;gt;results&lt;/tt&gt; vs &lt;tt&gt;my $results = $foo-&amp;gt;do_work&lt;/tt&gt;). I'll rant about that one in a later post.&lt;/p&gt;

&lt;p&gt;&lt;a href="#E7C2927D-1E8F-467D-A994-F0017688FF8B" name="33128C52-07EF-4416-BFCA-44FCE2AFF977"&gt;&lt;sup&gt;[1]&lt;/sup&gt;&lt;/a&gt;&lt;/p&gt;

&lt;pre class="fake-gist" id="fake-gist-243461"&gt;use Foo;
use Foo 0.13;
use Foo qw(foo bar);
use Foo 0.13 qw(Foo Bar);
use Foo ();
use Foo 0.13 ();&lt;/pre&gt;

&lt;p&gt;and this doesn't even account for manual invocation of those methods, e.g. from delegating &lt;tt&gt;import&lt;/tt&gt; routines.&lt;/p&gt;

&lt;p&gt;&lt;a name="5724A963-16E7-461D-9A68-3F639EAAC278" href="#6A5E5B98-5537-438E-9250-1B5193BA3152"&gt;&lt;sup&gt;[2]&lt;/sup&gt;&lt;/a&gt; This is the wrong kind of laziness, the virtuous laziness is long term&lt;/p&gt;

&lt;p&gt;&lt;a href="#D4C439D9-5E77-4024-98B9-DCE196EF1176" name="12348E3B-2F94-4A48-9C3C-61EE2BFED643"&gt;&lt;sup&gt;[3]&lt;/sup&gt;&lt;/a&gt; Now we have &lt;a href="http://search.cpan.org/perldoc?B::Hooks::EndOfScope"&gt;&lt;tt&gt;B::Hooks::EndOfScope&lt;/tt&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a name="E575E230-D706-447B-90BE-BB2A641B4C51" href="#4A5F8736-E00A-4EB4-83BC-3AB5C89E24C5"&gt;&lt;sup&gt;[4]&lt;/sup&gt;&lt;/a&gt; Perl itself does many things, but it is intended to let you write things that do one thing well (originally scripts, though nowadays I would say the CPAN is a much better example)&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/876358347971598886-1675309162246370786?l=blog.woobling.org' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/yuvalkogman/~4/9htZjLuG6F4" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.woobling.org/feeds/1675309162246370786/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=876358347971598886&amp;postID=1675309162246370786&amp;isPopup=true" title="5 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/876358347971598886/posts/default/1675309162246370786?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/876358347971598886/posts/default/1675309162246370786?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/yuvalkogman/~3/9htZjLuG6F4/timing-of-values-in-imperative-apis.html" title="The timing of values in imperative APIs" /><author><name>nothingmuch</name><uri>http://www.blogger.com/profile/03975438115490089158</uri><email>nothingmuch@woobling.org</email><gd:extendedProperty name="OpenSocialUserId" value="04344917020781355723" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">5</thr:total><feedburner:origLink>http://blog.woobling.org/2009/11/timing-of-values-in-imperative-apis.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CE8DR3kzfyp7ImA9WxNbGE4.&quot;"><id>tag:blogger.com,1999:blog-876358347971598886.post-7102107022195669199</id><published>2009-11-21T18:39:00.003+02:00</published><updated>2009-11-21T21:47:56.787+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-11-21T21:47:56.787+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="perl" /><title>Restricted Perl</title><content type="html">&lt;p&gt;&lt;a href="http://perlalchemy.blogspot.com/"&gt;zby&lt;/a&gt;'s comments on my &lt;a href="http://blog.woobling.org/2009/11/functional-programming-and-unreasonable.html"&gt;last post&lt;/a&gt; got me thinking. There are many features in Perl that we no longer use, or that are considered arcane or bad style, or even features we could simply live without. However, if they were removed, lots of code would break. So we keep those features, and we keep writing new code that uses them.&lt;/p&gt;

&lt;p&gt;Suppose there was a pragma, similar to &lt;tt&gt;no &lt;a href="http://search.cpan.org/perldoc?indirect"&gt;indirect&lt;/a&gt;&lt;/tt&gt; in that it restricts existing language features, and similar &lt;a href="http://perldoc.perl.org/perllexwarn.html"&gt;&lt;tt&gt;strict&lt;/tt&gt;&lt;/a&gt; in that it lets you opt out of unrelated discouraged behaviors.&lt;/p&gt;

&lt;p&gt;I think this would be an interesting baby step towards solving some of the problems that plague Perl code today:&lt;/p&gt;
 
&lt;ul&gt;
&lt;li&gt;Features that are often misused and need lots of &lt;a href="http://search.cpan.org/perldoc?Perl::Critic"&gt;critique&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Language features that are hard to change in the interpreter's implementation, limiting the revisions we can make to Perl 5.&lt;/li&gt;
&lt;li&gt;Code that will be hard to translate to Perl 6, for no good reason.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;On top of that one could implement several different defaults sets of feature-restricted Perl (sort of like &lt;a href="http://search.cpan.org/perldoc?Modern::Perl"&gt;&lt;tt&gt;Modern::Perl&lt;/tt&gt;&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;Instead of designing some sort of restricted subset of Perl 5 from the bottom up, several competing subsets could be developed organically, and if memory serves me right that is something we do quite well in our community =)&lt;/p&gt;

&lt;p&gt;So anyway, what are some things that you could easily live without in Perl? What things would you be willing to sacrifice if it meant you could trade them off for other advantages? Which features would you rather disallow as part of a coding standard?&lt;/p&gt;

&lt;h2&gt;My take&lt;/h2&gt;

&lt;p&gt;Here are some ideas. They are split up into categories which are loosely related, but don't necessarily go hand in hand (some of them even contradict slightly).&lt;/p&gt;

&lt;p&gt;They are all of a reasonable complexity to implement, either validating something or removing a language feature in a lexical scope.&lt;/p&gt;

&lt;p&gt;It's important to remember that these can be opted out of selectively, when you need them, just like you can say &lt;tt&gt;no warnings 'uninitialized'&lt;/tt&gt; when stringifying &lt;tt&gt;undef&lt;/tt&gt; is something you intentionally allowed.&lt;/p&gt;

&lt;h2&gt;Restrictions that would facilitate static modularity&lt;/h2&gt;

&lt;p&gt;The first four restrictions make it possible to treat &lt;tt&gt;.pm&lt;/tt&gt; files as standalone, cacheable compilation units. The fifth also allows for static linkage (no need to actually invoke &lt;tt&gt;import&lt;/tt&gt; when evaluating a &lt;tt&gt;use&lt;/tt&gt; statement), since the semantics of &lt;tt&gt;import&lt;/tt&gt; are statically known. This could help alleviate startup time problems with Perl code, per complicit compilation unit (without needing to solve the problem as a whole by crippling the adhoc nature of Perl's compile time &lt;em&gt;everywhere&lt;/em&gt;).&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Disallow recursive &lt;tt&gt;require&lt;/tt&gt;.&lt;/li&gt;
&lt;li&gt;Disallow modification to a package's symbol table after its &lt;tt&gt;package&lt;/tt&gt; declaration goes out of scope.&lt;/li&gt;
&lt;li&gt;Restrict a file to to only one package (which must match the &lt;tt&gt;.pm&lt;/tt&gt; file name).&lt;/li&gt;
&lt;li&gt;Disallow modification of other packages other than the currently declared one.&lt;/li&gt;
&lt;li&gt;Restrict the implementation of &lt;tt&gt;import&lt;/tt&gt; to a statically known one.&lt;/li&gt;
&lt;li&gt;Disallow access to external symbols that are not bound at compile time (e.g. variables from other packages, subroutines which weren't predeclared (fully qualified is OK).&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Restrictions that allow easier encapsulation of side effects&lt;/h2&gt;

&lt;p&gt;These restrictions address pollution of state between unrelated bits of code that have interacting dynamic scopes.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Disallow modification of any global variables that control IO behavior, such as &lt;tt&gt;$/&lt;/tt&gt;, &lt;tt&gt;$|&lt;/tt&gt;, etc, as well as code that depends on them. &lt;tt&gt;IO::Handle&lt;/tt&gt; would have to be augmented a bit to allow per handle equivalents, but it's most of the way there.&lt;/li&gt;
&lt;li&gt;Disallow such variables completely, instead requiring a trusted wrapper for &lt;tt&gt;open&lt;/tt&gt; that sets them at construction time and leaves them immutable thereafter.&lt;/li&gt;
&lt;li&gt;Disallow &lt;tt&gt;/g&lt;/tt&gt; matches on anything other than private lexicals (sets &lt;tt&gt;pos&lt;/tt&gt;)&lt;/li&gt;
&lt;li&gt;Disallow &lt;tt&gt;$SIG{__WARN__}&lt;/tt&gt;, &lt;tt&gt;$SIG{__DIE__}&lt;/tt&gt;, and &lt;tt&gt;$^S&lt;/tt&gt;&lt;/li&gt;
&lt;li&gt;Disallow &lt;tt&gt;eval&lt;/tt&gt; (instead, use &lt;a href="http://search.cpan.org/perldoc?Try::Tiny"&gt;trusted code that gets &lt;tt&gt;local $@&lt;/tt&gt; right&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Disallow use of global variables altogether. For instance, instead of &lt;tt&gt;$!&lt;/tt&gt; you'd rely on &lt;a href="http://search.cpan.org/perldoc?autodie"&gt;&lt;tt&gt;autodie&lt;/tt&gt;&lt;/a&gt;, for &lt;tt&gt;@ARGV&lt;/tt&gt; handling you'd use &lt;a href="http://search.cpan.org/perldoc?MooseX::Getopt"&gt;&lt;tt&gt;MooseX::Getopt&lt;/tt&gt;&lt;/a&gt; or &lt;a href="http://search.cpan.org/perldoc?App::Cmd"&gt;&lt;tt&gt;App::Cmd&lt;/tt&gt;&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Disallow mutation through references (only private lexical variables can be modified directly, and complex data structures are therefore immutable after being constructed). This has far reaching implications for object encapsulation, too.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Restrictions that would encourage immutable data.&lt;/h2&gt;

&lt;p&gt;These restrictions alleviate some of the mutation centric limitations of the &lt;tt&gt;SV&lt;/tt&gt; structure, that make lightweight concurrency impossible without protecting every variable access with a mutex. This would also allow aggressive &lt;a href="http://en.wikipedia.org/wiki/Copy-on-write"&gt;COW&lt;/a&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Only allow assignment to a variable at its declaration site. This only applies to lexicals.&lt;/li&gt;
&lt;li&gt;Allow only a single assignment to an &lt;tt&gt;SV&lt;/tt&gt; (by reference or directly. Once an &lt;tt&gt;SV&lt;/tt&gt; is given a value it becomes readonly)&lt;/li&gt;
&lt;li&gt;Disallow assignment modification of external variables (non lexicals, and closure captures). This is a weaker guarantee than the previous one (which is also much harder to enforce), but with similar implications (all assignment is guaranteed to have side effects that outlive its lexical scope)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Since many of the string operations in Perl are mutating, purely functional variants should be introduced (most likely as wrappers).&lt;/p&gt;

&lt;p&gt;Implicit mutations (such as the upgrading of an SV due to numification) typically results in a copy, so multithreaded access to immutable SVs could either pessimize the caching or just use a spinlock on upgrades.&lt;/p&gt;

&lt;h2&gt;Restrictions that would facilitate functional programming optimizations&lt;/h2&gt;

&lt;p&gt;These restrictions would allow representing simplified optrees in more advanced intermediate forms, allowing for interesting optimization transformations.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Disallow void context expressions&lt;/li&gt;
&lt;li&gt;...except for variable declarations (with the afore mentioned single use restrictions, this effectively makes every &lt;tt&gt;my $x = ...&lt;/tt&gt; into a let style binding)&lt;/li&gt;
&lt;li&gt;Allow only a single compound statement per subroutine, apart from let bindings (that evaluates to the return value). This special cases &lt;tt&gt;if&lt;/tt&gt; blocks to be treated as a compound statement due to the way implicit return values work in Perl.&lt;/li&gt;
&lt;li&gt;Disallow opcodes with non local side effects (including calls to non-verified subroutines) for purely functional code.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This is perhaps the most limiting set of restrictions. This essentially lets you embed lambda calculus type ASTs natively in Perl. Alternative representations for this subset of Perl could allow lisp style macros and other interesting compile time transformations, without the difficulty of making that alternative AST feature complete for all of Perl's semantics.&lt;/p&gt;

&lt;h2&gt;Restrictions that facilitate static binding of OO code&lt;/h2&gt;

&lt;p&gt;Perl's OO is always late bound, but most OO systems can actually be described statically. These restrictions would allow you to opt in for static binding of OO dispatch for a given hierarchy, in specific lexical scopes. This is a little more complicated than just lexical restrictions on features, since metadata about the classes must be recorded as well.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Only allow &lt;tt&gt;bless&lt;/tt&gt;ing into a class derived from the current package&lt;/li&gt;
&lt;li&gt;Enforce &lt;tt&gt;my Class $var&lt;/tt&gt;, including &lt;a href="Methods::CheckNames"&gt;static validation of method calls&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Disallow introduction of additional classes at runtime (per class hierarchy or alltogether)&lt;/li&gt;
&lt;li&gt;Based on the previous two restrictions, validate method call sites on typed variable invocants as static subroutine calls (with several target routines, instead of one)&lt;/li&gt;
&lt;li&gt;Similar the immutable references restriction above, disallow dereferencing of any blessed reference whose class is not derived from the current package.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;Restrictions that are easy to opt in to in most code (opting out only as necessary)&lt;/h2&gt;

&lt;p&gt;These features are subject to lots of criticism, and their usage tends to be discouraged. They're still useful, but in an ideal world they would probably be implemented as CPAN modules.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Disallow formats&lt;/li&gt;
&lt;li&gt;Disallow &lt;tt&gt;$[&lt;/tt&gt;&lt;/li&gt;
&lt;li&gt;Disallow tying and usage of tied variables&lt;/li&gt;
&lt;li&gt;Disallow overloading (declaration of overloads, as well as &lt;a href="http://perldoc.perl.org/overloading.html"&gt;their use&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;A note about implementation&lt;/h2&gt;

&lt;p&gt;Most of these features can be implemented in terms of &lt;a href="http://search.cpan.org/perldoc?B::Hooks::OP::Check"&gt;opcheck&lt;/a&gt; functions possibly coupled scrubbing triggered by and &lt;a href="http://search.cpan.org/perldoc?B::Hooks::EndOfScope"&gt;end of scope hook&lt;/a&gt;. Some of them are static checks at &lt;tt&gt;use&lt;/tt&gt; time. A few others require more drastic measures. For related modules see &lt;a href="http://search.cpan.org/perldoc?indirect"&gt;&lt;tt&gt;indirect&lt;/tt&gt;&lt;/a&gt;, &lt;a href="http://search.cpan.org/perldoc?Safe"&gt;&lt;tt&gt;Safe&lt;/tt&gt;&lt;/a&gt;, &lt;a href="http://search.cpan.org/perldoc? Sys::Protect"&gt;&lt;tt&gt;Sys::Protect&lt;/tt&gt;&lt;/a&gt;, and &lt;a href="http://search.cpan.org/perldoc?Devel::TypeCheck"&gt;&lt;tt&gt; Devel::TypeCheck&lt;/tt&gt;&lt;/a&gt; to name but a few&lt;/p&gt;

&lt;p&gt;I also see a niche for modules that implement &lt;em&gt;alternatives&lt;/em&gt; to built in features, disabling the core feature and providing a better alternative that replaces it instead of coexisting with it. This is the next step in exploratory language evolution as led by &lt;a href="http://search.cpan.org/perldoc?Devel::Declare"&gt;&lt;tt&gt;Devel::Declare&lt;/tt&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The difficulty of modernizing Perl 5's internals is the overwhelming amount of orthogonal concerns whenever you try to implement something. Instead of trying to take care of these problems we could make it possible for the user to promise they won't be an issue. It's not ideal, but it's better than nothing at all.&lt;/p&gt;

&lt;h2&gt;The distant future&lt;/h2&gt;

&lt;p&gt;If this sort of opt-out framework turns out to be successful, there's no reason why &lt;tt&gt;use 5.20.0&lt;/tt&gt; couldn't disable some of the more regrettable features by default, so that you have to explicitly ask for them instead. This effectively makes Perl's cost model per-per-use, instead of always pay.&lt;/p&gt;

&lt;p&gt;This would also increase the likelihood that people stop using such features in new code, and therefore the decision making aspects of the feature deprecation process would be easier to reason about.&lt;/p&gt;

&lt;p&gt;Secondly, and perhaps more importantly, it would be possible to try for alternative implementations of Perl 5 with shorter termed deliverables.&lt;/p&gt;

&lt;p&gt;Compiling a restricted subset of Perl to other languages (for instance client side JavaScript, different bytecodes, adding JIT support, etc) is a much easier task than implementing the language as a whole. If more feature restricted Perl code would be written and released on the CPAN, investments in such projects would be able to produce useful results sooner, and have clearer indications of progress.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/876358347971598886-7102107022195669199?l=blog.woobling.org' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/yuvalkogman/~4/3SX4YdoviR4" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.woobling.org/feeds/7102107022195669199/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=876358347971598886&amp;postID=7102107022195669199&amp;isPopup=true" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/876358347971598886/posts/default/7102107022195669199?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/876358347971598886/posts/default/7102107022195669199?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/yuvalkogman/~3/3SX4YdoviR4/restricted-perl.html" title="Restricted Perl" /><author><name>nothingmuch</name><uri>http://www.blogger.com/profile/03975438115490089158</uri><email>nothingmuch@woobling.org</email><gd:extendedProperty name="OpenSocialUserId" value="04344917020781355723" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">3</thr:total><feedburner:origLink>http://blog.woobling.org/2009/11/restricted-perl.html</feedburner:origLink></entry><entry gd:etag="W/&quot;Ak8MRHc7fSp7ImA9WxNbFUU.&quot;"><id>tag:blogger.com,1999:blog-876358347971598886.post-7304749074112351943</id><published>2009-11-18T23:57:00.007+02:00</published><updated>2009-11-19T02:01:25.905+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-11-19T02:01:25.905+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="functional programming" /><category scheme="http://www.blogger.com/atom/ns#" term="fail" /><category scheme="http://www.blogger.com/atom/ns#" term="immutability" /><category scheme="http://www.blogger.com/atom/ns#" term="perl" /><title>Functional programming and unreasonable expectations</title><content type="html">&lt;p&gt;&lt;tt&gt;&amp;lt;record type="broken"&amp;gt;&lt;/tt&gt;I'm a big fan of purely functional programming&lt;tt&gt;&amp;lt;/record&amp;gt;&lt;/tt&gt;.&lt;/p&gt;

&lt;p&gt;Another reason I like it so much is that purely functional software tends to be more reliable. Joe Armstrong of Erlang fame makes that point &lt;a href="http://www.infoq.com/presentations/Systems-that-Never-Stop-Joe-Armstrong"&gt;in an excellent talk&lt;/a&gt; much better than I could ever hope to.&lt;/p&gt;

&lt;p&gt;However, one aspect he doesn't really highlight is that reliability is not only good for keeping your system running, it also makes it easier to program.&lt;/p&gt;

&lt;p&gt;When a function is pure it is guaranteed to be isolated from other parts of the program. This separation is makes it much easier to change the code in one place without breaking anything unrelated.&lt;/p&gt;

&lt;p&gt;Embracing this style of programming has had one huge drawback though: it utterly ruined my expectations of non functional code.&lt;/p&gt;

&lt;p&gt;In imperative languages it's all too easy to add unstated assumptions about global state. When violated, these assumptions then manifest in very ugly and surprising ways (typically data corruption).&lt;/p&gt;

&lt;p&gt;A good example is reentrancy (or rather the lack thereof) in old style C code. Reentrant code can be freely used in multiple threads, from inside signal handlers, etc. Conversely, non-reentrant routines may only be executed once at a given point in time. Lack of foresight in early C code meant that lots of code had to be converted to be reentrant later on. Since unstated assumptions are by definition hidden this can be a difficult and error prone task.&lt;/p&gt;

&lt;p&gt;The specific disappointment that triggered this post is Perl's regular expression engine.&lt;/p&gt;

&lt;p&gt;Let's say we're parsing some digits from a string and we want to create a &lt;tt&gt;SomeObject&lt;/tt&gt; with those digits. Easy peasy:&lt;/p&gt;

&lt;pre class="fake-gist" id="fake-gist-238323"&gt;$string =~ m/(\d+)/;
push @results, SomeObject-&amp;gt;new( value =&amp;gt; $1 );&lt;/pre&gt;

&lt;p&gt;Encapsulating that match into a resuable regex is a little harder though. Where does the post processing code go? Which capture variable does it use? Isolation would have been nice. The following example might work, but it's totally wrong:&lt;/p&gt;

&lt;pre class="fake-gist" id="fake-gist-238318"&gt;my $match_digits = qr/(\d+)/;

my $other_match = qr{ ... $match_digits ... }x;

$string =~ $other_match;
push @results, SomeObject-&amp;gt;new( value =&amp;gt; $1 ); # FIXME makes no sense&lt;/pre&gt;

&lt;p&gt;Fortunately Perl's regex engine has a pretty awesome feature that let you run code during a match. This is very useful for constructing data from intermittent match results without having to think about nested captures, especially since the &lt;tt&gt;$^N&lt;/tt&gt; variable conveniently contains the result of the last capture.&lt;/p&gt;

&lt;p&gt;Not worrying about nested captures is important when you're combining arbitrary patterns into larger ones. There's no reliable way to know where the capture result ends up so it's easiest to process it as soon as it's available.&lt;/p&gt;

&lt;pre class="fake-gist" id="fake-gist-238319"&gt;qr{
    (\d+) # match some digits

    (?{
        # use the previous capture to produce a more useful result
        my $obj = SomeObject-&amp;gt;new( value =&amp;gt; $^N );

        # local allows backtracking to undo the effects of this block
        # this would have been much simpler if there was a purely
        # functional way to accumulate arbitrary values from regexes
        local @results = @results, $obj;
    })
}x;&lt;/pre&gt;

&lt;p&gt;Even though this is pretty finicky it still goes a long way. With this feature you can create regexes that also encapsulate the necessary post processing, while still remaining reusable.&lt;/p&gt;

&lt;p&gt;Here is a hypothetical the definition of &lt;tt&gt;SomeObject&lt;/tt&gt;:&lt;/p&gt;

&lt;pre class="fake-gist" id="fake-gist-238320"&gt;package SomeObject;
use Moose;

has value =&amp;gt; (
    isa =&amp;gt; "Int",
    is  =&amp;gt; "ro",
);&lt;/pre&gt;

&lt;p&gt;Constructing &lt;tt&gt;SomeObject&lt;/tt&gt; is a purely functional operation: it has no side effects, and only returns a new object.&lt;/p&gt;

&lt;p&gt;The only problem is that the above code is totally broken. It works, but only some of the time. The breakage is pretty random.&lt;/p&gt;

&lt;p&gt;Did you spot the bug yet? No? But it's oh so obvious! Look inside &lt;tt&gt;Moose::Util::TypeConstraints::OptimizedConstraints&lt;/tt&gt; and you will find the offending code:&lt;/p&gt;

&lt;pre class="fake-gist" id="fake-gist-238321"&gt;sub Int { defined($_[0]) &amp;amp;&amp;amp; !ref($_[0]) &amp;amp;&amp;amp; $_[0] =~ /^-?[0-9]+$/ }&lt;/pre&gt;

&lt;p&gt;The constructor Moose generated for &lt;tt&gt;SomeObject&lt;/tt&gt; is in fact not purely functional at all; though seemingly well behaved, in addition to returning an object it also the side effect of shitting all over the regexp engine's internal data structures, causing random values to be occasionally assigned to &lt;tt&gt;$^N&lt;/tt&gt; (but only if invoked from inside a &lt;tt&gt;(?{ })&lt;/tt&gt; block during a match). You can probably imagine what a great time I had finding that bug.&lt;/p&gt;

&lt;p&gt;What makes me sad is that the &lt;tt&gt;Int&lt;/tt&gt; validation routine appears purely functional. It takes a value and then without modifying anything merely checks that it's defined, that it's not a reference, and that its stringified form contains only digits, returning a truth value as a result. All of the inputs and all of the outputs are clear, and therefore it seems only logical that this should be freely reusable.&lt;/p&gt;

&lt;p&gt;When I came crying to &lt;tt&gt;#p5p&lt;/tt&gt; it turned out that this is actually a known issue. I guess I simply shouldn't have expected the regexp engine to do such things, after all it has a very long history and these sorts of problems are somewhat typical of C code.&lt;/p&gt;

&lt;p&gt;If the regexp engine was reentrant the what I tried to do would have just worked. Reentrancy guarantees one level of arbitrary combinations of code (the bit of reentrant code can be arbitrarily combined with itself). Unfortunately it seems very few people are actually in a position to fix it.&lt;/p&gt;

&lt;p&gt;Purely functional code goes one step further. You can &lt;strong&gt;reliably&lt;/strong&gt; mix and match any bit of code with any other bit of code, combining them in new ways, never having to expect failure. The price you have to pay is moving many more parameters around, but this is exactly what is necessary to make the boundaries well defined: all interaction between components is explicit.&lt;/p&gt;

&lt;p&gt;When old code gets reused it will inevitably get prodded in ways that the original author did not think of. Functional code has a much better chance of not needing to be reimplemented, because the implementation is kept isolated from the usage context.&lt;/p&gt;

&lt;p&gt;In short, every time you write dysfunctional code god kills a code reuse. Please, think of the code reuse!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/876358347971598886-7304749074112351943?l=blog.woobling.org' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/yuvalkogman/~4/kYvODVaaArk" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.woobling.org/feeds/7304749074112351943/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=876358347971598886&amp;postID=7304749074112351943&amp;isPopup=true" title="14 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/876358347971598886/posts/default/7304749074112351943?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/876358347971598886/posts/default/7304749074112351943?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/yuvalkogman/~3/kYvODVaaArk/functional-programming-and-unreasonable.html" title="Functional programming and unreasonable expectations" /><author><name>nothingmuch</name><uri>http://www.blogger.com/profile/03975438115490089158</uri><email>nothingmuch@woobling.org</email><gd:extendedProperty name="OpenSocialUserId" value="04344917020781355723" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">14</thr:total><feedburner:origLink>http://blog.woobling.org/2009/11/functional-programming-and-unreasonable.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEUAQXo_cCp7ImA9WxNbFEg.&quot;"><id>tag:blogger.com,1999:blog-876358347971598886.post-5925141149330559705</id><published>2009-11-10T17:25:00.007+02:00</published><updated>2009-11-17T12:04:00.448+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-11-17T12:04:00.448+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="scoping" /><category scheme="http://www.blogger.com/atom/ns#" term="fail" /><category scheme="http://www.blogger.com/atom/ns#" term="perl" /><title>Scoping of the current package</title><content type="html">&lt;p&gt;The one thing that I almost always notice when playing around in non Perl languages is how well Perl handles scoping.&lt;/p&gt;

&lt;p&gt;There is one place in which Perl got it totally wrong though.&lt;/p&gt;

&lt;p&gt;The value of the current package is lexically scoped:&lt;/p&gt;

&lt;pre class="fake-gist" id="fake-gist-230955"&gt;package Foo;

{
    package Bar;
    say __PACKAGE__; # prints Bar
}

say __PACKAGE__; # prints Foo&lt;/pre&gt;

&lt;p&gt;However, the notion of the current package &lt;em&gt;during compilation&lt;/em&gt; is dynamically scoped, even between files:&lt;/p&gt;

&lt;pre class="fake-gist" id="fake-gist-230956"&gt;# Foo.pm:

package Foo;
use Bar;&lt;/pre&gt;

&lt;pre class="fake-gist" id="fake-gist-230957"&gt;# Bar.pm:

say __PACKAGE__; # prints Foo&lt;/pre&gt;

&lt;p&gt;In other words, if you don't declare a package at the top of the &lt;tt&gt;.pm&lt;/tt&gt; file before doing anything, you are risking polluting the namespace of the module that called you. What's worse is that it can be unpredictable, only the first module to load &lt;tt&gt;Bar&lt;/tt&gt; will leak into &lt;tt&gt;Bar.pm&lt;/tt&gt;, so this could amount to serious debugging headaches.&lt;/p&gt;

&lt;p&gt;Consider the following:&lt;/p&gt;

&lt;pre class="fake-gist" id="fake-gist-230958"&gt;# Foo.pm:

package Foo;
use Moose;

use Bar;

sub foo { ... }&lt;/pre&gt;

&lt;p&gt;Now suppose a subsequent version of &lt;tt&gt;Bar&lt;/tt&gt; is rewritten using &lt;a href="http://search.cpan.org/perldoc?MooseX::Declare"&gt;&lt;tt&gt;MooseX::Declare&lt;/tt&gt;&lt;/a&gt;:&lt;/p&gt;

&lt;pre class="fake-gist" id="fake-gist-230959"&gt;use MooseX::Declare;

class Bar {
    ...
}&lt;/pre&gt;

&lt;p&gt;Guess which package the &lt;tt&gt;class&lt;/tt&gt; keyword was exported to?&lt;/p&gt;

&lt;p&gt;But maybe &lt;tt&gt;Bar&lt;/tt&gt; was tidy and used &lt;a href="http://search.cpan.org/perldoc?namespace::clean"&gt;&lt;tt&gt;namespace::clean&lt;/tt&gt;&lt;/a&gt;; instead of making &lt;tt&gt;$foo_object-&amp;gt;class&lt;/tt&gt; suddenly start working, &lt;tt&gt;$foo_object-&amp;gt;meta&lt;/tt&gt; would suddenly &lt;em&gt;stop&lt;/em&gt; working. And all this without a single change to &lt;tt&gt;Foo.pm&lt;/tt&gt;.&lt;/p&gt;

&lt;p&gt;Now imagine what would happen if &lt;tt&gt;Foo&lt;/tt&gt; did &lt;tt&gt;require Bar&lt;/tt&gt; instead of &lt;tt&gt;use&lt;/tt&gt;&amp;#x2026;&lt;/p&gt;

&lt;p&gt;Anyway, I think the point was made, always declare your package upfront or you risk pooping on your caller. Anything you do before an explicit &lt;tt&gt;package&lt;/tt&gt; declaration is in no man's land.&lt;/p&gt;

&lt;p&gt;I'm pretty sure a future version of &lt;tt&gt;MooseX::Declare&lt;/tt&gt; will contain a specific workaround for this, but I still think it's a good habit to always start every file with a package declaration, even if it's made redundant a few lines down.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/876358347971598886-5925141149330559705?l=blog.woobling.org' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/yuvalkogman/~4/Mwbn8Aj56zs" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.woobling.org/feeds/5925141149330559705/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=876358347971598886&amp;postID=5925141149330559705&amp;isPopup=true" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/876358347971598886/posts/default/5925141149330559705?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/876358347971598886/posts/default/5925141149330559705?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/yuvalkogman/~3/Mwbn8Aj56zs/scoping-of-current-package.html" title="Scoping of the current package" /><author><name>nothingmuch</name><uri>http://www.blogger.com/profile/03975438115490089158</uri><email>nothingmuch@woobling.org</email><gd:extendedProperty name="OpenSocialUserId" value="04344917020781355723" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">2</thr:total><feedburner:origLink>http://blog.woobling.org/2009/11/scoping-of-current-package.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEIGRn07cSp7ImA9WxNUEUg.&quot;"><id>tag:blogger.com,1999:blog-876358347971598886.post-3705847090725267635</id><published>2009-11-02T11:35:00.004+02:00</published><updated>2009-11-02T12:08:47.309+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-11-02T12:08:47.309+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="functional programming" /><category scheme="http://www.blogger.com/atom/ns#" term="internals" /><category scheme="http://www.blogger.com/atom/ns#" term="modules" /><category scheme="http://www.blogger.com/atom/ns#" term="perl" /><title>Sub::Call::Recur</title><content type="html">&lt;p&gt;After &lt;a href="http://blog.woobling.org/2009/10/subcalltail.html"&gt;my last post&lt;/a&gt; about &lt;a href="http://search.cpan.org/perldoc?Sub::Call::Tail"&gt;&lt;tt&gt;Sub::Call::Tail&lt;/tt&gt;&lt;/a&gt; &lt;a href="http://www.simplicidade.org/notes/"&gt;melo&lt;/a&gt; and &lt;a href="http://blog.jrock.us/"&gt;jrockway&lt;/a&gt; both asked me whether I was aware of Clojure's &lt;a href="http://clojure.org/special_forms#toc10"&gt;&lt;tt&gt;recur&lt;/tt&gt;&lt;/a&gt; form. I wasn't. Shortly afterwords I wrote &lt;a href="http://search.cpan.org/perldoc?Sub::Call::Recur"&gt;&lt;tt&gt;Sub::Call::Recur&lt;/tt&gt;&lt;/a&gt;, which implements that form in Perl.&lt;/p&gt;

&lt;p&gt;The &lt;tt&gt;recur&lt;/tt&gt; operation is a tail call to the &lt;em&gt;current&lt;/em&gt; subroutine. It's a bit like Perl's &lt;tt&gt;redo&lt;/tt&gt; builtin, but for functions instead of blocks.&lt;/p&gt;

&lt;p&gt;Here is a tail recursive factorial implementation:&lt;/p&gt;

&lt;pre class="fake-gist" id="fake-gist-224048"&gt;sub fact {
    my ( $n, $accum ) = @_;

    $accum ||= 1;

    if ( $n == 0 ) {
        return $accum;
    } else {
        recur( $n - 1, $n * $accum );
    }
}&lt;/pre&gt;

&lt;p&gt;The difference between this and using &lt;tt&gt;Sub::Call::Tail&lt;/tt&gt; to modify simple recursion is that &lt;tt&gt;recur&lt;/tt&gt; is almost as fast as an iterative loop. The overhead of destroying and recreating the stack frame for the subroutine invocation is avoided.&lt;/p&gt;

&lt;p&gt;I may end up combining the two modules so that a tail call resolving to the current subroutine is automatically optimized like &lt;tt&gt;recur&lt;/tt&gt;, but I'm not sure if that's a good idea yet (the semantics are a little different; &lt;tt&gt;Sub::Call::Tail&lt;/tt&gt; reuses the &lt;tt&gt;goto&lt;/tt&gt; opcode, whereas &lt;tt&gt;recur&lt;/tt&gt; is like a customized reimplementation of the &lt;tt&gt;redo&lt;/tt&gt; opcode).&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/876358347971598886-3705847090725267635?l=blog.woobling.org' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/yuvalkogman/~4/9gjKEehx9Fs" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.woobling.org/feeds/3705847090725267635/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=876358347971598886&amp;postID=3705847090725267635&amp;isPopup=true" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/876358347971598886/posts/default/3705847090725267635?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/876358347971598886/posts/default/3705847090725267635?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/yuvalkogman/~3/9gjKEehx9Fs/subcallrecur.html" title="&lt;tt&gt;Sub::Call::Recur&lt;/tt&gt;" /><author><name>nothingmuch</name><uri>http://www.blogger.com/profile/03975438115490089158</uri><email>nothingmuch@woobling.org</email><gd:extendedProperty name="OpenSocialUserId" value="04344917020781355723" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">3</thr:total><feedburner:origLink>http://blog.woobling.org/2009/11/subcallrecur.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CkMHR38yeCp7ImA9WxNUEUo.&quot;"><id>tag:blogger.com,1999:blog-876358347971598886.post-6423499055510843959</id><published>2009-10-31T18:20:00.004+02:00</published><updated>2009-11-02T16:00:36.190+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-11-02T16:00:36.190+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="functional programming" /><category scheme="http://www.blogger.com/atom/ns#" term="internals" /><category scheme="http://www.blogger.com/atom/ns#" term="modules" /><category scheme="http://www.blogger.com/atom/ns#" term="perl" /><title>Sub::Call::Tail</title><content type="html">&lt;p&gt;I've just released &lt;a href="http://search.cpan.org/perldoc?Sub::Call::Tail"&gt;&lt;tt&gt;Sub::Call::Tail&lt;/tt&gt;&lt;/a&gt; which allows for a much more natural tail call syntax than Perl's &lt;tt&gt;goto&lt;/tt&gt; built in.&lt;/p&gt;

&lt;p&gt;It provides a &lt;tt&gt;tail&lt;/tt&gt; keyword that modifies normal invocations to behave like &lt;tt&gt;goto &amp;amp;sub&lt;/tt&gt;, without needing the ugly &lt;tt&gt;@_&lt;/tt&gt; manipulation.&lt;/p&gt;

&lt;p&gt;Instead of this horrible kludge:&lt;/p&gt;

&lt;pre class="fake-gist" id="fake-gist-223122"&gt;@_ = ( $foo, $bar );
goto &amp;amp;foo;&lt;/pre&gt;

&lt;p&gt;You can now write:&lt;/p&gt;

&lt;pre class="fake-gist" id="fake-gist-223123"&gt;tail foo($foo, $bar);&lt;/pre&gt;

&lt;p&gt;And much more importantly this method call emulation atrocity:&lt;/p&gt;

&lt;pre class="fake-gist" id="fake-gist-223124"&gt;@_ = ( $object, $foo, $bar );
goto $object-&amp;gt;can("foo");&lt;/pre&gt;

&lt;p&gt;Can now be written as:&lt;/p&gt;

&lt;pre class="fake-gist" id="fake-gist-223125"&gt;tail $object-&amp;gt;foo($foo, $bar);&lt;/pre&gt;

&lt;p&gt;Finally we can write infinitely tail recursive and &lt;a href="http://en.wikipedia.org/wiki/Continuation_passing_style"&gt;CPS&lt;/a&gt; code with a constant stack space, without the syntactic letdown that is &lt;tt&gt;goto&lt;/tt&gt;. Lambdacamels rejoice!&lt;/p&gt;

&lt;p&gt;Thanks so much to &lt;a href="http://www.fysh.org/~zefram/"&gt;Zefram&lt;/a&gt; for his numerous tests and contributions.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/876358347971598886-6423499055510843959?l=blog.woobling.org' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/yuvalkogman/~4/MDFCVgyM6bg" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.woobling.org/feeds/6423499055510843959/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=876358347971598886&amp;postID=6423499055510843959&amp;isPopup=true" title="7 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/876358347971598886/posts/default/6423499055510843959?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/876358347971598886/posts/default/6423499055510843959?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/yuvalkogman/~3/MDFCVgyM6bg/subcalltail.html" title="&lt;tt&gt;Sub::Call::Tail&lt;/tt&gt;" /><author><name>nothingmuch</name><uri>http://www.blogger.com/profile/03975438115490089158</uri><email>nothingmuch@woobling.org</email><gd:extendedProperty name="OpenSocialUserId" value="04344917020781355723" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">7</thr:total><feedburner:origLink>http://blog.woobling.org/2009/10/subcalltail.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0UFSH07cSp7ImA9WxNVF0k.&quot;"><id>tag:blogger.com,1999:blog-876358347971598886.post-7347859625456988413</id><published>2009-10-28T17:39:00.004+02:00</published><updated>2009-10-28T19:00:19.309+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-28T19:00:19.309+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="git" /><category scheme="http://www.blogger.com/atom/ns#" term="cpan" /><category scheme="http://www.blogger.com/atom/ns#" term="sysadmin" /><category scheme="http://www.blogger.com/atom/ns#" term="perl" /><title>Versioned site_lib</title><content type="html">&lt;p&gt;Today I wanted to install a simple module on a production machine. I used the &lt;a href="http://search.cpan.org/perldoc?CPAN"&gt;&lt;tt&gt;CPAN&lt;/tt&gt;&lt;/a&gt; utility, as usual. Unfortunately that also pulled in an upgraded dependency which was not backwards compatible, breaking the application.&lt;/p&gt;

&lt;p&gt;I hate yak shaving.&lt;/p&gt;

&lt;p&gt;But not nearly as much as I hate &lt;em&gt;surprise&lt;/em&gt; yak shaving.&lt;/p&gt;

&lt;p&gt;I want to fix compatibility problems in my development environment on my own time, not hastily on a live server.&lt;/p&gt;

&lt;p&gt;I wrote &lt;a href="http://github.com/nothingmuch/git-site-perl"&gt;a small module&lt;/a&gt; to address this problem. To set it up run &lt;tt&gt;git site-perl-init&lt;/tt&gt;. This will initialize the &lt;tt&gt;.git&lt;/tt&gt; directory and configure &lt;tt&gt;CPAN&lt;/tt&gt; to wrap &lt;tt&gt;make install&lt;/tt&gt; and &lt;tt&gt;./Build install&lt;/tt&gt; with a helper script.&lt;/p&gt;

&lt;p&gt;The wrapper will invoke the installation command normally, and then commit any changes to &lt;tt&gt;installsitelib&lt;/tt&gt; with the distribution name as the commit message. This will happen automatically every time &lt;tt&gt;CPAN&lt;/tt&gt; tells a module to install itself.&lt;/p&gt;

&lt;p&gt;The approach is very simplistic; it does not version manpages or the &lt;tt&gt;bin&lt;/tt&gt; directory, nor does it work with &lt;a href="http://search.cpan.org/perldoc?local::lib"&gt;&lt;tt&gt;local::lib&lt;/tt&gt;&lt;/a&gt; or &lt;a href="http://search.cpan.org/perldoc?CPANPLUS"&gt;&lt;tt&gt;CPANPLUS&lt;/tt&gt;&lt;/a&gt; (at least not yet).&lt;/p&gt;

&lt;p&gt;It is just enough to let me run &lt;tt&gt;git reset --hard "master@{1 hour ago}"&lt;/tt&gt; to instantly go back to a working setup.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/876358347971598886-7347859625456988413?l=blog.woobling.org' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/yuvalkogman/~4/3DPEGOWFKMM" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.woobling.org/feeds/7347859625456988413/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=876358347971598886&amp;postID=7347859625456988413&amp;isPopup=true" title="5 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/876358347971598886/posts/default/7347859625456988413?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/876358347971598886/posts/default/7347859625456988413?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/yuvalkogman/~3/3DPEGOWFKMM/versioned-sitelib.html" title="Versioned &lt;tt&gt;site_lib&lt;/tt&gt;" /><author><name>nothingmuch</name><uri>http://www.blogger.com/profile/03975438115490089158</uri><email>nothingmuch@woobling.org</email><gd:extendedProperty name="OpenSocialUserId" value="04344917020781355723" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">5</thr:total><feedburner:origLink>http://blog.woobling.org/2009/10/versioned-sitelib.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DEMMQ3w4fCp7ImA9WxNVE04.&quot;"><id>tag:blogger.com,1999:blog-876358347971598886.post-3061177364415527452</id><published>2009-10-23T19:47:00.010+02:00</published><updated>2009-10-24T00:21:22.234+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-24T00:21:22.234+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="crypto" /><category scheme="http://www.blogger.com/atom/ns#" term="modules" /><category scheme="http://www.blogger.com/atom/ns#" term="authentication" /><title>Authenticated Encryption</title><content type="html">&lt;p&gt;One thing that makes me cringe is when people randomly invent their own cryptographic protocols. There's a &lt;a href="http://www.youtube.com/watch?v=ySQl0NhW1J0"&gt;Google Tech Talk by Nate Lawson&lt;/a&gt; where he explains some surprising approaches to attacking a cryptographic algorithm. It illustrates why rolling your own is probably a bad idea ;-)&lt;/p&gt;

&lt;p&gt;Perhaps the most &lt;a href="http://en.wikipedia.org/wiki/Not_Invented_Here"&gt;NIH&lt;/a&gt; cryptographic protocol I've seen is digitally signing as well as encrypting a message, in order to store tamper resistant data without revealing its contents. This is often done for storing sensitive data in cookies.&lt;/p&gt;

&lt;p&gt;Obviously such a protocol can be built using &lt;a href="http://search.cpan.org/perldoc?Digest::HMAC"&gt;HMACs&lt;/a&gt; and ciphers, but high level tools are already available, ones that have already been designed and analyzed by people who actually know what they're doing: &lt;a href="http://en.wikipedia.org/wiki/Authenticated_encryption"&gt;authenticated encryption modes of operation&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;WTF is a cipher mode?&lt;/h2&gt;

&lt;p&gt;Block ciphers are the sort of like hash functions, they take a block of data and scramble the block.&lt;/p&gt;

&lt;p&gt;Simply encrypting your data blocks one by one is not a good way of securing it though. Wikipedia has a &lt;a href="http://en.wikipedia.org/wiki/Block_cipher_modes_of_operation#Electronic_codebook_.28ECB.29"&gt;striking example&lt;/a&gt;:&lt;/p&gt;

&lt;a href="http://en.wikipedia.org/wiki/File:Tux_ecb.jpg"&gt;&lt;img src="http://s3.amazonaws.com/nothingmuch/Tux_ecb.jpg"/&gt;&lt;/a&gt;

&lt;p&gt;Even though every pixel is encrypted, the data as a whole still reveals a lot.&lt;/p&gt;

&lt;p&gt;Suffice it to say that blocks of operation are a wrapper that takes a low level scrambling function, the block cipher, and provide a less error prone tool, one that is more difficult to misuse.&lt;/p&gt;

&lt;h2&gt;On the CPAN&lt;/h2&gt;

&lt;p&gt;&lt;a href="http://search.cpan.org/perldoc?Crypt::CBC"&gt;&lt;tt&gt;Crypt::CBC&lt;/tt&gt;&lt;/a&gt; and &lt;a href="http://search.cpan.org/perldoc?Crypt::Ctr"&gt;&lt;tt&gt;Crypt::Ctr&lt;/tt&gt;&lt;/a&gt; are implementations of some of the more classic cipher modes. But this post is ranting about people not using &lt;em&gt;authenticated&lt;/em&gt; modes.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://search.cpan.org/perldoc?Crypt::GCM"&gt;&lt;tt&gt;Crypt::GCM&lt;/tt&gt;&lt;/a&gt; and &lt;a href="http://search.cpan.org/perldoc?Crypt::EAX"&gt;&lt;tt&gt;Crypt::EAX&lt;/tt&gt;&lt;/a&gt; implement two different AEAD modes of operation using any block cipher.&lt;/p&gt;

&lt;p&gt;These are carefully designed and analyzed algorithms, and the CPAN implementations make use of the tests from the articles describing the algorithms, so it sure beats rolling your own.&lt;/p&gt;

&lt;p&gt;Secondly, &lt;a href="http://search.cpan.org/perldoc?Crypt::Util"&gt;&lt;tt&gt;Crypt::Util&lt;/tt&gt;&lt;/a&gt; provides a convenience layer that builds on these tools (and many others), so perhaps &lt;tt&gt;Crypt::Util&lt;/tt&gt; already handles what you want.&lt;/p&gt;

&lt;p&gt;To tamper protect a simple data structure you can do something like this:&lt;/p&gt; 

&lt;pre class="fake-gist" id="fake-gist-217049"&gt;my $cu = Crypt::Util-&amp;gt;new( key =&amp;gt; ... );

my $ciphertext = $cu-&amp;gt;tamper_proof_data( data = { ... }, encrypt =&amp;gt; 1 );&lt;/pre&gt;

&lt;p&gt;&lt;tt&gt;Crypt::Util&lt;/tt&gt; will use &lt;a href="http://search.cpan.org/perldoc?Storable"&gt;&lt;tt&gt;Storable&lt;/tt&gt;&lt;/a&gt; to encode the data into a string, and then use an authenticated encryption mode to produce the ciphertext.&lt;/p&gt;

&lt;p&gt;To decrypt, simply do:&lt;/p&gt;

&lt;pre class="fake-gist" id="fake-gist-217050"&gt;my $data = $c-&amp;gt;thaw_tamper_proof( string =&amp;gt; $ciphertext );&lt;/pre&gt;

&lt;p&gt;&lt;tt&gt;Crypt::Util&lt;/tt&gt; will decrypt and validate the ciphertext, and only after it's sure that the data is trusted it'll start unpacking the data, and if appropriate using &lt;tt&gt;Storable&lt;/tt&gt; to deserialize the message. All allocations based on untrusted data are limited to 64KiB.&lt;/p&gt;

&lt;h2&gt;Don't sue me&lt;/h2&gt;

&lt;p&gt;I'm not saying that the CPAN code is guaranteed to be safe. I'm saying this is a better idea than rolling your own. If your application is sensitive you have no excuse not to open up the code and audit it.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/876358347971598886-3061177364415527452?l=blog.woobling.org' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/yuvalkogman/~4/qEhUOhIk6Y8" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.woobling.org/feeds/3061177364415527452/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=876358347971598886&amp;postID=3061177364415527452&amp;isPopup=true" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/876358347971598886/posts/default/3061177364415527452?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/876358347971598886/posts/default/3061177364415527452?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/yuvalkogman/~3/qEhUOhIk6Y8/authenticated-encryption.html" title="Authenticated Encryption" /><author><name>nothingmuch</name><uri>http://www.blogger.com/profile/03975438115490089158</uri><email>nothingmuch@woobling.org</email><gd:extendedProperty name="OpenSocialUserId" value="04344917020781355723" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://blog.woobling.org/2009/10/authenticated-encryption.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DUAFR3c4fip7ImA9WxNWFks.&quot;"><id>tag:blogger.com,1999:blog-876358347971598886.post-2165435005904754062</id><published>2009-10-16T02:40:00.005+02:00</published><updated>2009-10-16T06:35:16.936+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-16T06:35:16.936+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="anyevent" /><category scheme="http://www.blogger.com/atom/ns#" term="plack" /><category scheme="http://www.blogger.com/atom/ns#" term="psgi" /><title>Event driven PSGI</title><content type="html">&lt;p&gt;I spent most of today and yesterday bikeshedding event driven PSGI with &lt;a href="http://bulknews.typepad.com/"&gt;miyagawa&lt;/a&gt; on &lt;a href="irc://irc.perl.org/#http-engine"&gt;#http-engine&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;We seem to have converged on something that is both fairly portable to different event driven implementations, without being too yucky for blocking backends.&lt;/p&gt;

&lt;p&gt;For example, if you don't yet know the response code or headers and are waiting on some other event driven thing, it's sort of like continuation passing style:&lt;/p&gt;

&lt;pre class="fake-gist" id="fake-gist-211428"&gt;$app = sub {
    my $env = shift;

    ...

    return sub {
        my $write = shift;

        $some_event_thingy-&amp;gt;do_your_thing( when_finished =&amp;gt; sub {
            $write-&amp;gt;([ 200, $headers, $body ]);
        });
    };
};&lt;/pre&gt;

&lt;p&gt;A more complex example involves streaming:&lt;/p&gt;

&lt;pre class="fake-gist" id="fake-gist-211429"&gt;$app = sub {
    my $env = shift;

    ...

    return sub {
        my $write = shift;

        my $out = $write-&amp;gt;([ 200, $headers ]);

        $some_event_thingy-&amp;gt;new_data(sub {
            my $data = shift;

            if ( defined $data ) {
                $out-&amp;gt;write($data);
            } else {
                $out-&amp;gt;close;
            }
        });
    };
};
&lt;/pre&gt;

&lt;p&gt;Lastly, if you are worried about too much memory usage in the output buffer,
you can provide a callback to &lt;tt&gt;poll_cb&lt;/tt&gt;:&lt;/p&gt;

&lt;pre class="fake-gist" id="fake-gist-211439"&gt;$app = sub {
    my $env = shift;

    ...

    return sub {
        my $write = shift;

        $write-&amp;gt;([ 200, $headers ])-&amp;gt;poll_cb(sub {
            my $out = shift;

            $out-&amp;gt;write($some_more);

            $out-&amp;gt;close() if $finished;
 });
    };
};&lt;/pre&gt;

&lt;p&gt;But &lt;tt&gt;poll_cb&lt;/tt&gt; should only be used on event driven backends (check for it using &lt;tt&gt;$out-&amp;gt;can("poll_cb")&lt;/tt&gt;).&lt;/p&gt;

&lt;p&gt;This lets simple streaming applications will work nicely under blocking
backends as well as event driven ones.&lt;/p&gt;

&lt;p&gt;Even better, while I was busy implementing this this for the &lt;a href="http://github.com/nothingmuch/plack-server-anyevent"&gt;AnyEvent backend&lt;/a&gt; &lt;a href="http://twitter.com/frodwith"&gt;frodwith&lt;/a&gt; whipped up a &lt;a href="http://github.com/frodwith/plack-server-poe"&gt;POE implementation&lt;/a&gt; in no time at all.&lt;/p&gt;

&lt;p&gt;This pretty much obsoletes my &lt;tt&gt;IO::Writer&lt;/tt&gt; sketch. The only case it doesn't cover but which &lt;tt&gt;IO::Writer&lt;/tt&gt; theoretically does is &lt;tt&gt;poll_cb&lt;/tt&gt; based nonblocking output, combined with a non blocking data source, but without an event driven environment. This sucks because nonblocking IO without an event loop wastes a lot of CPU. I can't imagine why anyone would actually try that, so I hereby declare &lt;tt&gt;IO::Writer&lt;/tt&gt; deprecated, thankfully before I actually wrote a robust implementation ;-)&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/876358347971598886-2165435005904754062?l=blog.woobling.org' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/yuvalkogman/~4/0rBCBydtQ7U" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.woobling.org/feeds/2165435005904754062/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=876358347971598886&amp;postID=2165435005904754062&amp;isPopup=true" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/876358347971598886/posts/default/2165435005904754062?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/876358347971598886/posts/default/2165435005904754062?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/yuvalkogman/~3/0rBCBydtQ7U/event-driven-psgi.html" title="Event driven PSGI" /><author><name>nothingmuch</name><uri>http://www.blogger.com/profile/03975438115490089158</uri><email>nothingmuch@woobling.org</email><gd:extendedProperty name="OpenSocialUserId" value="04344917020781355723" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">3</thr:total><feedburner:origLink>http://blog.woobling.org/2009/10/event-driven-psgi.html</feedburner:origLink></entry><entry gd:etag="W/&quot;Dk8CQX09eyp7ImA9WxNWEEg.&quot;"><id>tag:blogger.com,1999:blog-876358347971598886.post-7895884456012497720</id><published>2009-10-08T16:46:00.004+02:00</published><updated>2009-10-09T04:21:00.363+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-09T04:21:00.363+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="moose" /><category scheme="http://www.blogger.com/atom/ns#" term="roles" /><category scheme="http://www.blogger.com/atom/ns#" term="object oriented" /><category scheme="http://www.blogger.com/atom/ns#" term="delegation" /><category scheme="http://www.blogger.com/atom/ns#" term="perl" /><title>Roles and Delegates and Refactoring</title><content type="html">&lt;img style="float:right; margin-left: 15px; margin-bottom: 15px;" width="200" height="150" src="http://s3.amazonaws.com/nothingmuch/ohmy.jpg"/&gt;

&lt;p&gt;&lt;a href="http://use.perl.org/~Ovid/journal/39728"&gt;Ovid writes&lt;/a&gt; about the distinction between responsibility and behavior, and what that means in the context of roles.&lt;/p&gt;

&lt;p&gt;He argues that the &lt;em&gt;responsibilities&lt;/em&gt; of a class may sometimes lie in tangent with additional behaviors it performs (and that these behaviors are often also in tangent with one another).&lt;/p&gt;

&lt;p&gt;Since roles lend themselves to more horizontal code reuse (what multiple inheritance tries to allow but fails to do safely), he makes the case that they are they are more appropriate for loosely related behaviors.&lt;/p&gt;

&lt;p&gt;I agree. However, roles only facilitate the &lt;em&gt;detection&lt;/em&gt; of a flawed taxonomy, which under multiple inheritance seems to work. They can often validate a sensible design, but they don't provide a solution for a flawed one.&lt;/p&gt;

&lt;p&gt;If you take a working multiple inheritance based design and change every base class into a role, it will still work. Roles will produce errors for ambiguities, but if the design makes sense there shouldn't be many of those to begin with. The fundamental structure of the code hasn't actually changed with the migration to roles.&lt;/p&gt;

&lt;p&gt;Roles do not in their own right prevent &lt;a href="http://en.wikipedia.org/wiki/God_object"&gt;god objects&lt;/a&gt; from forming. Unfortunately that has not yet been automated ;-)&lt;/p&gt;

&lt;h2&gt;Another Tool&lt;/h2&gt;

&lt;p&gt;Wikipedia defines &lt;a href="http://en.wikipedia.org/wiki/Delegation_pattern"&gt;Delegation&lt;/a&gt; as:&lt;/p&gt;

&lt;blockquote&gt;a technique where an object outwardly expresses certain behaviour but in reality delegates responsibility for implementing that behavior to an associated object&lt;/blockquote&gt;

&lt;img style="float:right; margin-left: 15px; margin-bottom: 15px;" width="200" height="110" src="http://s3.amazonaws.com/nothingmuch/god.jpg"/&gt;

&lt;p&gt;instead of merging the behavior into the consuming class (using roles or inheritence), the class uses a helper object to implement that behavior, and doesn't worry about the details.&lt;/p&gt;

&lt;p&gt;Roles help you find out you have a problem, but delegates help you to fix it.&lt;/p&gt;

&lt;h2&gt;Delegation by Example&lt;/h2&gt;

&lt;p&gt;A simple but practical example of how to refactor a class that mixes two behaviors is &lt;a href="http://search.cpan.org/perldoc?Test::Builder"&gt;&lt;tt&gt;Test::Builder&lt;/tt&gt;&lt;/a&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;It provides an API to easily generate &lt;a href="http://testanything.org/"&gt;TAP&lt;/a&gt; output&lt;/li&gt;
&lt;li&gt;It provides a way to share a TAP generator between the various &lt;tt&gt;Test::&lt;/tt&gt; modules on the CPAN, using the singleton pattern.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;tt&gt;Test::Builder&lt;/tt&gt;'s documentation says:&lt;/p&gt;

&lt;blockquote&gt;Since you only run one test per program &lt;tt&gt;new&lt;/tt&gt; always returns the same Test::Builder object.&lt;/blockquote&gt;

&lt;p&gt;The problem is that the assumption that you will only generate one stream of TAP per program hasn't got much to do with the problem of generating valid TAP data.&lt;/p&gt;

&lt;p&gt;That assumption makes it simpler to generate TAP output from a variety of &lt;a href="http://search.cpan.org/search?query=Test::&amp;amp;mode=module"&gt;loosely related modules&lt;/a&gt; designed to be run with &lt;a href="http://search.cpan.org/perldoc?Test::Harness"&gt;&lt;tt&gt;Test::Harness&lt;/tt&gt;&lt;/a&gt;, but it is limiting if you want to generate TAP in some other scenario.&lt;sup&gt;&lt;a href="#0377180D-002E-48BD-8601-ED2B80AA3388" name="95B600C7-B6C7-4ECA-9FA2-A49E5FD03D3C"&gt;[1]&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;

&lt;p&gt;With a delegate based design the task of obtaining the appropriate TAP generation helper and the task of generating TAP output would be managed by two separate objects, where the TAP generator is oblivious to the way it is being used.&lt;/p&gt;

&lt;p&gt;In this model &lt;tt&gt;Test::Builder&lt;/tt&gt; is just the singletony bits, and it &lt;em&gt;uses&lt;/em&gt; a TAP generation helper. It would still have the same API as it does now, but a hypothetical &lt;tt&gt;TAP::Generator&lt;/tt&gt; object would generate the actual TAP stream.&lt;/p&gt;

&lt;p&gt;The core idea is to separate the behaviors and responsibilities even more, not just into roles, but into different objects altogether.&lt;/p&gt;

&lt;p&gt;Though this does makes taxonomical inquiries like &lt;tt&gt;isa&lt;/tt&gt; and &lt;tt&gt;does&lt;/tt&gt; a little more roundabout, it allows a lot more flexibility when weaving together a complex system from simple parts, and encourages reuse and refactoring by making polymorphism and duck typing easy.&lt;/p&gt;

&lt;p&gt;If you want to use TAP for something other than testing Perl modules, you could do this without hacking around the singleton crap.&lt;/p&gt;

&lt;h2&gt;Delegating with Moose&lt;/h2&gt;

&lt;p&gt;Moose has strong support for delegation. I love this, because it means that convincing people to use delegation is much easier than it was before, since it's no longer tedius and doesn't need to involve &lt;tt&gt;AUTOLOAD&lt;/tt&gt;.&lt;/p&gt;

&lt;p&gt;To specify a delegation, you declare an attribute and use the &lt;tt&gt;handles&lt;/tt&gt; option:&lt;/p&gt;

&lt;pre class="fake-gist" id="fake-gist-204603"&gt;has tap_generator =&amp;gt; (
    isa =&amp;gt; "TAP::Generator",
    is  =&amp;gt; "ro",
    handles =&amp;gt; [qw(plan ok done_testing ...)],
);&lt;/pre&gt;

&lt;p&gt;Roles play a key part in making delegation even easier to use. This is because roles dramatically decrease the burden of maintenance and refactoring, for all the reasons that Ovid often cites.&lt;/p&gt;

&lt;p&gt;When refactoring role based code to use delegation, you can simply replace your use of the role with an attribute:&lt;/p&gt;

&lt;pre class="fake-gist" id="fake-gist-204604"&gt;has tap_generator =&amp;gt; (
    does =&amp;gt; "TAP::Generator",
    is   =&amp;gt; "ro",
    handles =&amp;gt; "TAP::Generator",
);&lt;/pre&gt;

&lt;p&gt;This will automatically proxy all of the methods of the &lt;tt&gt;TAP::Genrator&lt;/tt&gt; role to the &lt;tt&gt;tap_generator&lt;/tt&gt; attribute.&lt;sup&gt;&lt;a href="#C82E643C-AF80-4392-9CE7-E91E102A9214" name="09AEF75F-D061-4540-B05C-BAF3C70D0707"&gt;[2]&lt;/a&gt;&lt;/sup&gt;&lt;/p&gt;

&lt;p&gt;Moose's &lt;tt&gt;handles&lt;/tt&gt; parameter to attributes has many more features which are &lt;a href="http://search.cpan.org/perldoc?Moose::Manual::Delegation"&gt;covered in the Delegation section of the manual&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;A Metaclass Approach to ORMs&lt;/h2&gt;

&lt;p&gt;Ovid's example for roles implementing a separate behavior involves a simple ORM. It involves a &lt;tt&gt;Server&lt;/tt&gt; class, which in order to behave appropriately needs some of its attributes stored persistently (there isn't much value in a server management system that can't store information permanently).&lt;/p&gt;

&lt;p&gt;He proposes the following:&lt;/p&gt;

&lt;pre class="fake-gist" id="fake-gist-204605"&gt;class Server does SomeORM {
   has IPAddress $.ip_address is persisted;
   has Str       $.name       is persisted;

   method restart(Bool $nice=True) {
       say $nice ?? 'yes' !! 'no';
   }
}&lt;/pre&gt;

&lt;p&gt;But I think this confuses the notion of a class level behavior with a metaclass level behavior.&lt;/p&gt;

&lt;p&gt;The annotation &lt;tt&gt;is persisted&lt;/tt&gt; is on the same level as the annotation &lt;tt&gt;IPAddress&lt;/tt&gt; or &lt;tt&gt;Str&lt;/tt&gt;, it is something belonging to the meta attribute.&lt;/p&gt;

&lt;h2&gt;Metaclasses as Delegates&lt;/h2&gt;

&lt;p&gt;A metaclass is an object that represents a class. In a sense it could be considered a delegate of the compiler or language runtime. In the case of Moose this is a bit of a stretch (since the metaclass is not exactly authoritative as far as Perl is concerned, the symbol table is).&lt;/p&gt;

&lt;p&gt;Conceptually it still holds though. The metaclass is responsible for reflecting as well as specifying the definition of a single class. The clear separation of that single responsibility is the key here. The metaclass is delegated to by the sugar layer that uses it, and indirectly by the runtime that invokes methods on the class (since the metaclass is in control of the symbol table).&lt;/p&gt;

&lt;p&gt;Furthermore, the metaclass itself delegates many of its behaviors. Accessor generation is the responsibility of the attribute meta object.&lt;/p&gt;

&lt;p&gt;To frame the ORM example in these terms, we have several components:&lt;/p&gt;

&lt;img style="float:right; margin-left: 15px; margin-bottom: 15px;" width="150" height="174" src="http://s3.amazonaws.com/nothingmuch/pyramid_construction.jpg"/&gt;

&lt;ul&gt;
&lt;li&gt;persisted attributes, modeled by meta attribute delegate of the meta class object with an additional role for persistence&lt;sup&gt;&lt;a href="#A42AA808-94E6-4A3C-B0C0-91E41390C26E" name="D67F0E42-E4CA-4CB0-8CC5-9CF9F22947B2"&gt;[3]&lt;/a&gt;&lt;/sup&gt;
&lt;/li&gt;&lt;li&gt;the metaclass, which must also be modified for the additional persistence functionality (to make use of the attributes' extended interface)&lt;/li&gt;
&lt;li&gt;an object construction helper that knows about the class it is constructing, as well as the database handle from which to get the data, but doesn't care about the actual problem domain.&lt;sup&gt;&lt;a href="#76A8EA65-132C-41B3-A68C-4A11EC045BAE" name="417069C7-5699-469B-971A-13A9EBFB10FC"&gt;[4]&lt;/a&gt;&lt;/sup&gt;&lt;/li&gt;
&lt;li&gt;an object that models information about the problem domain being addressed (&lt;tt&gt;Server&lt;/tt&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;By &lt;a href="http://en.wikipedia.org/wiki/Separation_of_concerns"&gt;separating the responsibilities&lt;/a&gt; of the business logic from database connectivity from class definition we get decoupled components that can be reused more easily, and which are less sensitive to changes in one another.&lt;/p&gt;

&lt;h2&gt;KiokuDB&lt;/h2&gt;

&lt;p&gt;Lastly, I'd like to mention that &lt;a href="http://www.iinteractive.com/kiokudb/"&gt;KiokuDB&lt;/a&gt; can be used to solve that &lt;tt&gt;Server&lt;/tt&gt; problem far more simply. I promise I'm not saying that only on account of my vanity ;-)&lt;/p&gt;

&lt;p&gt;The reason it's a simpler solution is that the &lt;tt&gt;Server&lt;/tt&gt; class does not need to know that it is being persisted at all, and therefore does not need to accommodate a persistence layer. The KiokuDB handle would be asked to persist that object, and proceed to take it apart using reflection provided by the metaclass:&lt;/p&gt;

&lt;pre class="fake-gist" id="fake-gist-204606"&gt;$dir-&amp;gt;lookup($server_id);
$server-&amp;gt;name("Pluto");
$dir-&amp;gt;update($server);&lt;/pre&gt;

&lt;p&gt;This keeps the persistence behavior completely detached from the responsibilities of the server, which is to model a physical machine.&lt;/p&gt;

&lt;p&gt;The problem of figuring out how to store fields in a database can be delegated to a completely independent part of the program, which is operates on &lt;tt&gt;Server&lt;/tt&gt; via its metaclass, instead of being a tool that &lt;tt&gt;Server&lt;/tt&gt; uses. The behavior or responsibility (depending on how you look at it) of storing data about servers in a database can be completely removed from the &lt;tt&gt;Server&lt;/tt&gt; class, which is concerned solely with the shape of that data.&lt;/p&gt;

&lt;h2&gt;Summary&lt;/h2&gt;

&lt;p&gt;There is no silver bullet.&lt;/p&gt;

&lt;p&gt;Roles are almost always better than multiple inheritance, but don't replace some of the uses of single inheritance.&lt;/p&gt;

&lt;p&gt;Delegates provide even more structure than roles, and are usually best implemented using roles.&lt;/p&gt;

&lt;p&gt;By leveraging both techniques at the class as well as the metaclass level you can often achieve dramatically simplified results.&lt;/p&gt;

&lt;p&gt;Roles may help with code reuse, but the classes they create are still static (even runtime generated classes are still classes with a symbol table). Delegation allows components to be swapped and combined much more easily. When things get more complicated &lt;a href="http://search.cpan.org/perldoc?Bread::Board"&gt;inversion of control&lt;/a&gt; goes even further, and the end result is usually both more flexible and simpler than only static role composition.&lt;/p&gt;

&lt;p&gt;Secondly, and perhaps more importantly, delegates are not limited to single use&lt;sup&gt;&lt;a href="#F97295ED-026E-4DA2-B134-C6A048A7E768" name="BA8ABA17-3E87-4957-A32C-816DA27DA3FB"&gt;[5]&lt;/a&gt;&lt;/sup&gt;. You can have a list of delegates performing a responsibility together. &lt;a href="http://sartak.org"&gt;Sartak&lt;/a&gt;'s &lt;a href="http://www.slideshare.net/sartak/api-design"&gt;API Design&lt;/a&gt; talk at &lt;a href="http://conferences.yapcasia.org/ya2009"&gt;YAPC::Asia&lt;/a&gt; explained how &lt;a href="http://search.cpan.org/perldoc?Dist::Zilla"&gt;Dist::Zilla&lt;/a&gt; uses a powerful combination of roles and plugin delegates, taking this even further.&lt;/p&gt; 

&lt;p&gt;At the bottom line, though, nothing can replace a well thought out design. Reducing your problem space is often the best way of finding a clean solution. What I like so much about delegates is that they encourage you to think about the real purpose of each and every component in the system.&lt;/p&gt;

&lt;p&gt;Even the simple need for coming up with a name for each component can help you reach new understandings about the nature of the problem.&lt;/p&gt;

&lt;p&gt;Delegation heavy code tends to force you to come up with many names because there are many small classes, but this shouldn't lead to &lt;a href="http://img.skitch.com/20091008-qdkm32xy26ygg7qxd9d1dhu2ky.jpg"&gt;Java hell&lt;/a&gt;. Roles can really help alleviate this (they sure beat interfaces), but even so, this is just code smell that points to an overly complex solution. If it feels too big it probably is. A bloated solution that hasn't been factored out to smaller parts is still a bloated solution.&lt;/p&gt;

&lt;p&gt;Once you've taken the problem apart you can often figure out which parts are &lt;a href="http://en.wikipedia.org/wiki/YAGNI"&gt;actually necessary&lt;/a&gt;. Allowing (and relying on) polymorphism should make things future proof without needing to implement everything up front. Just swap your simple delegate with a more complicated one when you need to.&lt;/p&gt;

&lt;p&gt;&lt;sup&gt;&lt;a name="0377180D-002E-48BD-8601-ED2B80AA3388" href="#95B600C7-B6C7-4ECA-9FA2-A49E5FD03D3C"&gt;[1]&lt;/a&gt;&lt;/sup&gt; Fortunately &lt;tt&gt;Test::Builder&lt;/tt&gt; provides an alternate constructor, &lt;tt&gt;create&lt;/tt&gt;, that is precisely intended for this case.&lt;/p&gt;

&lt;p&gt;&lt;sup&gt;&lt;a name="C82E643C-AF80-4392-9CE7-E91E102A9214" href="#09AEF75F-D061-4540-B05C-BAF3C70D0707"&gt;[2]&lt;/a&gt;&lt;/sup&gt; Note that this is currently flawed in Moose for several reasons: accessors are not delegated automatically, the -&amp;gt;does method on the delegator will not return true for roles of the delegate (specifically "RoleName" in this case, etc), but that's generally not a problem in practice (there are failing tests and no one has bothered to fix them yet).&lt;/p&gt;

&lt;p&gt;&lt;sup&gt;&lt;a name="A42AA808-94E6-4A3C-B0C0-91E41390C26E" href="#D67F0E42-E4CA-4CB0-8CC5-9CF9F22947B2"&gt;[3]&lt;/a&gt;&lt;/sup&gt; For clarity's sake we tend to call roles applied to meta objects traits, so in this case the Server class would be using the &lt;tt&gt;SomeORM&lt;/tt&gt; and &lt;tt&gt;persistent&lt;/tt&gt; class and attribute traits.&lt;/p&gt;

&lt;p&gt;&lt;sup&gt;&lt;a name="76A8EA65-132C-41B3-A68C-4A11EC045BAE" href="#417069C7-5699-469B-971A-13A9EBFB10FC"&gt;[4]&lt;/a&gt;&lt;/sup&gt; in DBIC these responsibilities are actually carried out by the resultset, the result source, and the schema objects, a rich hierarchy of delegates in its own right.&lt;/p&gt;

&lt;p&gt;&lt;sup&gt;&lt;a name="F97295ED-026E-4DA2-B134-C6A048A7E768" href="#BA8ABA17-3E87-4957-A32C-816DA27DA3FB"&gt;[5]&lt;/a&gt;&lt;/sup&gt; &lt;a href="http://search.cpan.org/perldoc?MooseX::Role::Parameterized"&gt;parameterized roles&lt;/a&gt; are a very powerful static abstraction that allows multiple compositions of a single role into a single consumer with different paremeters.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/876358347971598886-7895884456012497720?l=blog.woobling.org' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/yuvalkogman/~4/WOCHK1p5NaU" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.woobling.org/feeds/7895884456012497720/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=876358347971598886&amp;postID=7895884456012497720&amp;isPopup=true" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/876358347971598886/posts/default/7895884456012497720?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/876358347971598886/posts/default/7895884456012497720?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/yuvalkogman/~3/WOCHK1p5NaU/roles-and-delegates-and-refactoring.html" title="Roles and Delegates and Refactoring" /><author><name>nothingmuch</name><uri>http://www.blogger.com/profile/03975438115490089158</uri><email>nothingmuch@woobling.org</email><gd:extendedProperty name="OpenSocialUserId" value="04344917020781355723" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://blog.woobling.org/2009/10/roles-and-delegates-and-refactoring.html</feedburner:origLink></entry><entry gd:etag="W/&quot;C0YBRXk7eCp7ImA9WxNXF0s.&quot;"><id>tag:blogger.com,1999:blog-876358347971598886.post-2713755643671327212</id><published>2009-10-05T17:00:00.005+02:00</published><updated>2009-10-05T18:45:54.700+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-05T18:45:54.700+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="internals" /><category scheme="http://www.blogger.com/atom/ns#" term="object oriented" /><category scheme="http://www.blogger.com/atom/ns#" term="perl" /><title>Are Filehandles Objects?</title><content type="html">&lt;p&gt;Perl has a very confusing set of behaviors for treating filehandles as objects.&lt;/p&gt;

&lt;h2&gt;ADHD Summary&lt;/h2&gt;

&lt;p&gt;Globs which contain open handles can be treated as objects, even if though they aren't blessed.&lt;/p&gt;

&lt;p&gt;Always load &lt;tt&gt;IO::Handle&lt;/tt&gt; and &lt;tt&gt;FileHandle&lt;/tt&gt;, to allow the method syntax.&lt;/p&gt;

&lt;p&gt;Whenever you are using filehandles, use the method syntax, regardless of whether it's a real handle or a fake one. A fake handle that works with the builtins needs to jump through some nasty hoops.&lt;/p&gt;

&lt;p&gt;Whenever you are creating fake handles, the aforementioned hopps are that you should tie &lt;tt&gt;*{$self}&lt;/tt&gt; (or return a tied glob from the &lt;tt&gt;*{}&lt;/tt&gt; overload), so that the builtins will know to call your object's methods through your TIEHANDLE implementation.&lt;/p&gt;

&lt;h2&gt;The Long Story&lt;/h2&gt;

&lt;p&gt;There are several potentially overlapping data types that can be used to perform IO.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Unblessed globs containing IO objects&lt;/li&gt;
&lt;li&gt;Blessed globs containing IO objects&lt;/li&gt;
&lt;li&gt;Blessed IO objects&lt;/li&gt;
&lt;li&gt;Objects resembling IO objects (i.e. &lt;tt&gt;$obj-&amp;gt;can("print")&lt;/tt&gt;), which aren't necessarily globs&lt;/li&gt;
&lt;li&gt;Tied globs&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;and there are two ways to use these data types, but some types only support one method:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;method calls (&lt;tt&gt;$fh-&amp;gt;print("foo")&lt;/tt&gt;)&lt;/li&gt;
&lt;li&gt;builtins (&lt;tt&gt;print $fh, "foo"&lt;/tt&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Lastly, there are a number of built in classes (which are not loaded by default, but are in core):&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="http://search.cpan.org/perldoc?IO::Handle"&gt;&lt;tt&gt;IO::Handle&lt;/tt&gt;&lt;/a&gt;, a base class for all handle types&lt;/li&gt;
&lt;li&gt;&lt;a href="http://search.cpan.org/perldoc?FileHandle"&gt;&lt;tt&gt;FileHandle&lt;/tt&gt;&lt;/a&gt;, a class for file handles (seekable)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When you open a standard filehandle:&lt;/p&gt;

&lt;pre class="fake-gist" id="fake-gist-200742"&gt;use autodie;

open my $fh, "&amp;lt;", $filename;&lt;/pre&gt;

&lt;p&gt;the variable &lt;tt&gt;$fh&lt;/tt&gt; contains an unblessed reference to a type glob. This type glob contains an &lt;tt&gt;IO&lt;/tt&gt; reference in the &lt;tt&gt;IO&lt;/tt&gt; slot, that is blessed into the class &lt;tt&gt;FileHandle&lt;/tt&gt; by default.&lt;/p&gt;

&lt;p&gt;The &lt;tt&gt;IO&lt;/tt&gt; object is blessed even if &lt;tt&gt;FileHandle&lt;/tt&gt; is not loaded.&lt;/p&gt;

&lt;p&gt;If it is loaded, then both ways of using the handle are allowed:&lt;/p&gt;

&lt;pre class="fake-gist" id="fake-gist-202223"&gt;# builtin
read $fh, my $var, 4096;

# as method
$fh-&amp;gt;read(my $var, 4096);&lt;/pre&gt;

&lt;p&gt;These two forms behave similarly. One could even be led to believe that the first form is actually treated as indirect method syntax. This is unfortunately very far from the truth.&lt;/p&gt;

&lt;p&gt;In the first form the &lt;tt&gt;read&lt;/tt&gt; is executed directly. In the second form the &lt;tt&gt;read&lt;/tt&gt; method would be invoked on the unblessed glob. However, instead of throwing the usual &lt;tt&gt;Can't call method "read" on unblessed reference&lt;/tt&gt; error, Perl's &lt;tt&gt;method_common&lt;/tt&gt; routine (which implements method dispatch) special cases globs with an &lt;tt&gt;IO&lt;/tt&gt; slot to actually dispatch the method using the class of &lt;tt&gt;*{$fh}{IO}&lt;/tt&gt;. In a way this is very similar to how &lt;a href="http://search.cpan.org/perldoc?autobox"&gt;&lt;tt&gt;autobox&lt;/tt&gt;&lt;/a&gt; works.&lt;/p&gt;

&lt;p&gt;If you remembered to &lt;tt&gt;use FileHandle&lt;/tt&gt; then this should result in a successful dispatch to &lt;tt&gt;IO::Handle::read&lt;/tt&gt;, which actually delegates to the &lt;tt&gt;read&lt;/tt&gt; builtin:&lt;/p&gt;

&lt;pre class="fake-gist" id="fake-gist-200743"&gt;sub read {
    @_ == 3 || @_ == 4 or croak 'usage: $io-&amp;gt;read(BUF, LEN [, OFFSET])';
    read($_[0], $_[1], $_[2], $_[3] || 0);
}&lt;/pre&gt;

&lt;p&gt;When you create nonstandard IO objects, this breaks down:&lt;/p&gt;

&lt;pre class="fake-gist" id="fake-gist-200744"&gt;{
    package MyHandle;

    sub read {
        my ( $self, undef, $length, $offset ) = @_;

        substr($_[1], $offset, $length) = ...;
    }
}&lt;/pre&gt;

&lt;p&gt;because now &lt;tt&gt;$myhandle-&amp;gt;read(...)&lt;/tt&gt; will work as expected, but &lt;tt&gt;read($myhandle, ...)&lt;/tt&gt; will not. If it is a blessed glob the error will be &lt;tt&gt;read() on unopened filehandle&lt;/tt&gt;, and for other data types the error will be &lt;tt&gt;Not a GLOB reference&lt;/tt&gt;.&lt;/p&gt;

&lt;h2&gt;Tied Handles&lt;/h2&gt;

&lt;p&gt;Tied handles are very similar to built in handles, they contain an &lt;tt&gt;IO&lt;/tt&gt; slot with a blessed object (this time the default is the &lt;tt&gt;FileHandle&lt;/tt&gt; class, a subclass of &lt;tt&gt;IO::Handle&lt;/tt&gt; that has a few additional methods like support for seeking.&lt;/p&gt;

&lt;p&gt;The &lt;tt&gt;IO&lt;/tt&gt; object is marked as a tied data structure so that the builtin opcodes will delegate to some object implementing the &lt;a href="http://search.cpan.org/perldoc?perltie"&gt;&lt;tt&gt;TIEHANDLE&lt;/tt&gt; interface&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;A method call on a tied object will therefore invoke the method on the &lt;tt&gt;FileHandle&lt;/tt&gt; class, which will delegate to to the builtin, which will delegate to a method on the object.&lt;/p&gt;

&lt;p&gt;Because of this, classes like &lt;a href="http://search.cpan.org/perldoc?IO::String"&gt;&lt;tt&gt;IO::String&lt;/tt&gt;&lt;/a&gt; employ a clever trick to allow the builtins to be used:&lt;/p&gt;

&lt;pre class="fake-gist" id="fake-gist-200745"&gt;my $fh = IO::String-&amp;gt;new($string);

# readline builtin calls getline method
while ( defined( my $line = &amp;lt;$fh&amp;gt; ) ) {
    ...
}

# print builtin calls print method
print $fh "foo";&lt;/pre&gt;

&lt;p&gt;&lt;tt&gt;IO::String::new&lt;/tt&gt; ties the new handle to itself&lt;sup&gt;&lt;a href="#617B0936-32B5-4A79-846F-0D7747318D2D" name="F230DE77-07D4-4E55-9875-7F3613170498"&gt;[1]&lt;/a&gt;&lt;/sup&gt;, and sets up the extra glue:&lt;/p&gt;

&lt;pre class="fake-gist" id="fake-gist-200746"&gt;sub new
{
    my $class = shift;
    my $self = bless Symbol::gensym(), ref($class) || $class;
    tie *$self, $self;
    $self-&amp;gt;open(@_);
    return $self;
}&lt;/pre&gt;

&lt;p&gt;The &lt;tt&gt;TIEHANDLE&lt;/tt&gt; API is set up by aliasing symbols:&lt;/p&gt;

&lt;pre class="fake-gist" id="fake-gist-200747"&gt;*READ   = \&amp;amp;read;&lt;/pre&gt;

&lt;p&gt;Effectively this reverses the the way it normally works. Instead of &lt;tt&gt;IO::Handle&lt;/tt&gt; methods delegating to the builtin ops, the builtin ops delegate to the &lt;tt&gt;IO::String&lt;/tt&gt; methods.&lt;/p&gt;

&lt;p&gt;&lt;a href="http://search.cpan.org/perldoc?IO::Handle::Util"&gt;&lt;tt&gt;IO::Handle::Util&lt;/tt&gt;&lt;/a&gt; provides a &lt;tt&gt;io_to_glob&lt;/tt&gt; helper function which produces a tied unblessed glob that delegates to the methods of an IO object. This function is then used to implement &lt;tt&gt;*{}&lt;/tt&gt; overloading. This allows non glob handles to automatically create a working glob as necessary, without needing to implement the tie kludge manually.&lt;/p&gt;

&lt;h2&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;When working with standard or nonstandard handle types, method syntax always works (provided &lt;tt&gt;IO::Handle&lt;/tt&gt; and &lt;tt&gt;FileHandle&lt;/tt&gt; are loaded), but the builtin syntax only works for tied handles, so when using a filehandle I prefer the method syntax.&lt;/p&gt;

&lt;p&gt;It also makes the silly &lt;tt&gt;print {$fh}&lt;/tt&gt; idiom unnecessary, since direct method syntax isn't ambiguous.&lt;/p&gt;

&lt;p&gt;Performance is a non issue, the extra overhead is nothing compared to PerlIO indirection, ties, and making the actual system calls.&lt;/p&gt;

&lt;p&gt;However, when creating nonstandard IO objects, you should probably provide a tie fallback so that code that doesn't use method syntax will not die with strange errors (or worse, violate the encapsulation of your handle object and just work on the internal glob structure directly).&lt;/p&gt;

&lt;p&gt;This is one of my least favourite parts in Perl. It's such a horrible cascade of kludges. In the spirit of &lt;a href="http://en.wikipedia.org/wiki/Robustness_Principle"&gt;Postel's Law&lt;/a&gt;, consistently using methods is the conservative thing to do (it works in all cases), and providing a tie based fallback is a way to be liberal about what you accept.&lt;/p&gt;

&lt;p&gt;&lt;sup&gt;&lt;a name="617B0936-32B5-4A79-846F-0D7747318D2D" href="#F230DE77-07D4-4E55-9875-7F3613170498"&gt;[1]&lt;/a&gt;&lt;/sup&gt; Surprisingly this doesn't leak, even though &lt;tt&gt;weaken(tie(*$self, $self))&lt;/tt&gt; is not used. I suspect there is a special case that prevents the refcount increment if the object is tied to itself. See also &lt;a href="http://search.cpan.org/perldoc?Tie::Util"&gt;&lt;tt&gt;Tie::Util&lt;/tt&gt;&lt;/a&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/876358347971598886-2713755643671327212?l=blog.woobling.org' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/yuvalkogman/~4/pzrOM1cDPZc" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.woobling.org/feeds/2713755643671327212/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=876358347971598886&amp;postID=2713755643671327212&amp;isPopup=true" title="4 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/876358347971598886/posts/default/2713755643671327212?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/876358347971598886/posts/default/2713755643671327212?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/yuvalkogman/~3/pzrOM1cDPZc/are-filehandles-objects.html" title="Are Filehandles Objects?" /><author><name>nothingmuch</name><uri>http://www.blogger.com/profile/03975438115490089158</uri><email>nothingmuch@woobling.org</email><gd:extendedProperty name="OpenSocialUserId" value="04344917020781355723" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">4</thr:total><feedburner:origLink>http://blog.woobling.org/2009/10/are-filehandles-objects.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEUNR3w8eSp7ImA9WxNXFE0.&quot;"><id>tag:blogger.com,1999:blog-876358347971598886.post-5344774945188808163</id><published>2009-10-01T15:03:00.001+02:00</published><updated>2009-10-01T15:04:56.271+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-01T15:04:56.271+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="modules" /><category scheme="http://www.blogger.com/atom/ns#" term="psgi" /><category scheme="http://www.blogger.com/atom/ns#" term="perl" /><title>IO::Handle::Util</title><content type="html">&lt;p&gt;My friend &lt;a href="http://bulknews.typepad.com/"&gt;miyagawa&lt;/a&gt; has been championing &lt;a href="http://plackperl.org/"&gt;PSGI and its reference implementation, Plack&lt;/a&gt;. This is something we've needed for a &lt;em&gt;long&lt;/em&gt; time: a clean and simple way to respond to HTTP requests without the cruft of CGI and &lt;tt&gt;%ENV&lt;/tt&gt;.&lt;/p&gt;

&lt;p&gt;The PSGI specification requires the body of the response to be represented using an object similar to &lt;a href="http://search.cpan.org/perldoc?IO::Handle"&gt;&lt;tt&gt;IO::Handle&lt;/tt&gt;&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I've released &lt;a href="http://search.cpan.org/perldoc?IO::Handle::Util"&gt;&lt;tt&gt;IO::Handle::Util&lt;/tt&gt;&lt;/a&gt;, a convenience package designed to make working with &lt;tt&gt;IO::Handle&lt;/tt&gt; like objects easier.&lt;/p&gt;

&lt;p&gt;The main package provides a number of utility functions for creating IO handles from various data structures, and for getting the data out of IO handles.&lt;/p&gt;

&lt;p&gt;For example, if you have a string or array of strings that you would like to just pass back, you can use the &lt;tt&gt;io_from_any&lt;/tt&gt; function:&lt;/p&gt;

&lt;pre class="fake-gist" id="fake-gist-198947"&gt;my $io = io_from_any $body;

# then you can do standard operations to get the data out:
$io-&amp;gt;getline;
$io-&amp;gt;read(my $str, $length);&lt;/pre&gt;

&lt;p&gt;This function will sensibly coerce other things, like &lt;a href="http://search.cpan.org/perldoc?Path::Class::File"&gt;paths&lt;/a&gt;, and let already working handles pass through as is.&lt;/p&gt;

&lt;p&gt;If you have an iterator callback that gets more data you can also use that:&lt;/p&gt;

&lt;pre class="fake-gist" id="fake-gist-198948"&gt;my $io = io_from_getline sub {
    ...
    return $more_data; # or undef when you're done
};&lt;/pre&gt;

&lt;p&gt;This is not automated by &lt;tt&gt;io_from_any&lt;/tt&gt; because you can also use a writer callback, or a callback that returns the whole handle (remember, this is not PSGI specific).&lt;/p&gt;

&lt;p&gt;You can also go the other, taking IO handles and getting useful things out of them. &lt;tt&gt;io_to_array&lt;/tt&gt; is pretty obvious, but you can also do something like:&lt;/p&gt;

&lt;pre class="fake-gist" id="fake-gist-198949"&gt;use autodie;

open my $fh, "&amp;gt;", $file;

my $cb = io_to_write_cb $fh;

$cb-&amp;gt;("blah\n");
$cb-&amp;gt;("orz\n");&lt;/pre&gt;

&lt;p&gt;Many of the utility functions are based on &lt;a href="http://search.cpan.org/perldoc?IO::Handle::Iterator"&gt;&lt;tt&gt;IO::Handle::Iterator&lt;/tt&gt;&lt;/a&gt; and &lt;a href="http://search.cpan.org/perldoc?IO::Handle::Prototype::Fallback"&gt;&lt;tt&gt;IO::Handle::Prototype::Fallback&lt;/tt&gt;&lt;/a&gt;, two classes which facilitate the creation of adhoc filehandles.&lt;/p&gt;

&lt;p&gt;Hopefully this will make creating and working with IO handles a little quicker and easier.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/876358347971598886-5344774945188808163?l=blog.woobling.org' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/yuvalkogman/~4/urP-R1XJ5_0" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.woobling.org/feeds/5344774945188808163/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=876358347971598886&amp;postID=5344774945188808163&amp;isPopup=true" title="5 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/876358347971598886/posts/default/5344774945188808163?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/876358347971598886/posts/default/5344774945188808163?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/yuvalkogman/~3/urP-R1XJ5_0/iohandleutil.html" title="IO::Handle::Util" /><author><name>nothingmuch</name><uri>http://www.blogger.com/profile/03975438115490089158</uri><email>nothingmuch@woobling.org</email><gd:extendedProperty name="OpenSocialUserId" value="04344917020781355723" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">5</thr:total><feedburner:origLink>http://blog.woobling.org/2009/10/iohandleutil.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CEQHSHw_fyp7ImA9WxNQFks.&quot;"><id>tag:blogger.com,1999:blog-876358347971598886.post-2051102466639795249</id><published>2009-09-23T02:27:00.001+03:00</published><updated>2009-09-23T02:32:19.247+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-09-23T02:32:19.247+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="testing" /><category scheme="http://www.blogger.com/atom/ns#" term="perl" /><category scheme="http://www.blogger.com/atom/ns#" term="concurrency" /><title>Testing for Race Conditions</title><content type="html">&lt;p&gt;Concurrent programming is hard for many reason. One of them is that scheduling isn't predictable; the same code may behave differently depending on the OS's scheduling decisions. This is more complicated on single CPU machines when there is no real concurrency, just the illusion of concurrency through time sharing.&lt;/p&gt;

&lt;p&gt;Because many operations can happen in a single &lt;a href="http://en.wikipedia.org/wiki/Preemption_(computing)#Time_slice"&gt;time slice&lt;/a&gt; (which is usually 10ms on most operating systems) unless the race condition falls on the time slice boundary it may go undetected in testing.&lt;/p&gt;

&lt;p&gt;My laptop can do several thousand IO operations and many more thread mutex operations per second. Chances are only if one of these has a race condition it'll take very long to find it accidentally.&lt;/p&gt;

&lt;p&gt;Since most concurrent code tries to minimize the duration of critical sections, the probability of critical sections interleaving with context switches can be very low. On a single CPU machine all the non blocking operations performed in a single time slice are atomic from the point of view of other processes. For a computer 10ms is a pretty long length of time.&lt;/p&gt;

&lt;p&gt;Therefore, when testing for concurrency bugs it's important to introduce artificial contention to increase the chance of exposing a race condition. A fairly reliable method of doing that which I use in &lt;a href="http://search.cpan.org/perldoc?Directory::Transactional"&gt;&lt;tt&gt;Directory::Transactional&lt;/tt&gt;&lt;/a&gt;'s test suite is introducing random delays into the process:&lt;/p&gt;

&lt;pre class="fake-gist" id="fake-gist-191533"&gt;use Time::HiRes qw(sleep);
use autodie;

sub cede {
    sleep 0.01 if rand &amp;lt; 0.2;
}

for ( 1 .. $j ) {
    fork and next;

    srand $$;

    for ( 1 .. $n ) {
        # critical section
        cede();
        acquire_resource();
        cede();
        read_resource();
        cede();
        write_resource();
    }

    exit;
}

wait_all();&lt;/pre&gt;

&lt;p&gt;This is very easy to add only during testing by wrapping the resource access APIs in your codebase.&lt;/p&gt;

&lt;p&gt;If you concurrently loop through the critical section &lt;a href="http://en.wikipedia.org/wiki/Sample_size"&gt;long enough&lt;/a&gt; the probability of finding a race condition is much higher than without the delays that encourage the OS to perform context switching even on a single CPU machine.&lt;/p&gt;

&lt;p&gt;This is by no means an exhaustive method of checking all possible context switch permutations. However, by increasing the probability of interleaved context switches from infinitesimally small to pretty good for a reasonable number of iterations we are much more likely to trigger any race condition (as opposed to all of them).&lt;/p&gt;

&lt;p&gt;Furthermore, by designing volatile test transactions the chance of &lt;em&gt;detecting&lt;/em&gt; this race condition is also quite good (since an exposed race condition would be more likely to cause inconsistency). Specifically in &lt;tt&gt;Directory::Transactional&lt;/tt&gt; the test simulates money transfers between three accounts, where each iteration deducts a random number from a random account and adds it to another.&lt;/p&gt;

&lt;p&gt;The values are read before a delay, and written afterwords, so any other process touching the same account would trigger a race condition if proper locking was not in place. The fact that the values are random too increases the chance of corruption being detectable (it's much more likely the accounts will not be balanced if the value is random as opposed to some constant).&lt;/p&gt;

&lt;p&gt;Coupled with concurrent consistency checks on the data done at intervals this was a pretty effective method for detecting race conditions, quickly exposing initial implementation flaws in &lt;tt&gt;Directory::Transactional&lt;/tt&gt; that took very many iterations to reproduce at first. Throwing in random &lt;tt&gt;kill -9&lt;/tt&gt; signals provided a fun test for journal replay recovery.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/876358347971598886-2051102466639795249?l=blog.woobling.org' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/yuvalkogman/~4/Pun5lnLJ48w" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.woobling.org/feeds/2051102466639795249/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=876358347971598886&amp;postID=2051102466639795249&amp;isPopup=true" title="3 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/876358347971598886/posts/default/2051102466639795249?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/876358347971598886/posts/default/2051102466639795249?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/yuvalkogman/~3/Pun5lnLJ48w/testing-for-race-conditions.html" title="Testing for Race Conditions" /><author><name>nothingmuch</name><uri>http://www.blogger.com/profile/03975438115490089158</uri><email>nothingmuch@woobling.org</email><gd:extendedProperty name="OpenSocialUserId" value="04344917020781355723" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">3</thr:total><feedburner:origLink>http://blog.woobling.org/2009/09/testing-for-race-conditions.html</feedburner:origLink></entry><entry gd:etag="W/&quot;DkEBQns6cCp7ImA9WxNQEkU.&quot;"><id>tag:blogger.com,1999:blog-876358347971598886.post-6702744752656545652</id><published>2009-09-18T05:37:00.000+03:00</published><updated>2009-09-18T17:37:33.518+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-09-18T17:37:33.518+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="perl" /><category scheme="http://www.blogger.com/atom/ns#" term="hack" /><title>Method Style Callbacks</title><content type="html">&lt;p&gt;This is a small trick I like to use when defining callbacks. Instead of invoking callbacks as code references:&lt;/p&gt;

&lt;pre class="fake-gist" id="fake-gist-189082"&gt;$callback-&amp;gt;($data);&lt;/pre&gt;

&lt;p&gt;I always write the invocation as a method call:&lt;/p&gt;

&lt;pre class="fake-gist" id="fake-gist-189083"&gt;$data-&amp;gt;$callback();&lt;/pre&gt;

&lt;p&gt;or if &lt;tt&gt;$data&lt;/tt&gt; is not a natural invocant for the routine, then I invoke it as a method on the object that is sending the notification:&lt;/p&gt;

&lt;pre class="fake-gist" id="fake-gist-189084"&gt;$self-&amp;gt;$callback($data);&lt;/pre&gt;

&lt;p&gt;This works in more cases than just plain code reference invocation:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If &lt;tt&gt;$data&lt;/tt&gt; is an object then &lt;tt&gt;$callback&lt;/tt&gt; can be a string  (a method name).&lt;/li&gt;
&lt;li&gt;If &lt;tt&gt;$callback&lt;/tt&gt; &lt;em&gt;is&lt;/em&gt; a code reference there is no difference between this syntax and code dereferncing&lt;/li&gt;
&lt;li&gt;Even if &lt;tt&gt;$data&lt;/tt&gt; is not an object but &lt;tt&gt;$callback&lt;/tt&gt; is a code reference, the method syntax will still work.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It's pretty nice to be able to pass method names as callbacks invoked on a subclass but still have the flexibility of a code reference when appropriate, and works especially well when the callback attribute has a sensible default value that resolves to a method call on &lt;tt&gt;$self&lt;/tt&gt; to allow easy overriding of behavior without needing a full subclass.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/876358347971598886-6702744752656545652?l=blog.woobling.org' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/yuvalkogman/~4/75x2MV-C-E0" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.woobling.org/feeds/6702744752656545652/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=876358347971598886&amp;postID=6702744752656545652&amp;isPopup=true" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/876358347971598886/posts/default/6702744752656545652?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/876358347971598886/posts/default/6702744752656545652?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/yuvalkogman/~3/75x2MV-C-E0/method-style-callbacks.html" title="Method Style Callbacks" /><author><name>nothingmuch</name><uri>http://www.blogger.com/profile/03975438115490089158</uri><email>nothingmuch@woobling.org</email><gd:extendedProperty name="OpenSocialUserId" value="04344917020781355723" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">2</thr:total><feedburner:origLink>http://blog.woobling.org/2009/09/method-style-callbacks.html</feedburner:origLink></entry><entry gd:etag="W/&quot;Ak4DQnk6cSp7ImA9WxNQEEw.&quot;"><id>tag:blogger.com,1999:blog-876358347971598886.post-8978027727098187460</id><published>2009-09-15T15:28:00.007+03:00</published><updated>2009-09-15T15:49:33.719+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-09-15T15:49:33.719+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="internals" /><category scheme="http://www.blogger.com/atom/ns#" term="modules" /><category scheme="http://www.blogger.com/atom/ns#" term="yapc" /><category scheme="http://www.blogger.com/atom/ns#" term="c" /><category scheme="http://www.blogger.com/atom/ns#" term="perl" /><category scheme="http://www.blogger.com/atom/ns#" term="hackathon" /><title>Hackathon Summary</title><content type="html">&lt;p&gt;During the &lt;a href="http://conferences.yapcasia.org/ya2009/"&gt;YAPC::Asia::2009&lt;/a&gt; hackathon I refactored a bunch of XS modules out of some other code, both &lt;a href="http://perldition.org"&gt;rafl&lt;/a&gt;'s and mine.&lt;/p&gt;

&lt;h2&gt;&lt;a href="http://search.cpan.org/perldoc?XS::Object::Magic"&gt;&lt;tt&gt;XS::Object::Magic&lt;/tt&gt;&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;This module provides an alternative to the standard &lt;tt&gt;T_PTROBJ&lt;/tt&gt; approach to creating C struct based objects in Perl.&lt;/p&gt;

&lt;p&gt;The traditional way creates a blessed scalar reference, which contains an integer value that is cast to a pointer of the right type.&lt;/p&gt;

&lt;p&gt;This is problematic for two reasons:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;If the pointer value is modified (accidentally or maliciously) then this could easily corrupt memory or cause segfaults.&lt;/li&gt;
&lt;li&gt;Scalar references can't be extended with more data without using &lt;a href="http://search.cpan.org/perldoc?MooseX::NonMoose::InsideOut"&gt;inside out objects&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This module provides a C api which uses &lt;tt&gt;sv_magicext&lt;/tt&gt; to create safer and more extensible objects associated with some pointer, that interoperates nicely with &lt;a href="http://moose.perl.org/"&gt;Moose&lt;/a&gt; amongst other things.&lt;/p&gt;

&lt;h2&gt;&lt;a href="http://search.cpan.org/perldoc?Magical::Hooker::Decorate"&gt;&lt;tt&gt;Magical::Hooker::Decorate&lt;/tt&gt;&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;This module lets you decorate an arbitrary SV with any other arbitrary SV using the magic hook API.&lt;/p&gt;

&lt;p&gt;This is similar to using a &lt;a href="http://search.cpan.org/perldoc?Hash::Util::FieldHash::Compat"&gt;&lt;tt&gt;fieldhash&lt;/tt&gt;&lt;/a&gt; to create inside out decorations, but is designed to be used primarily from XS code, and as such it provides a C api. The memory footprint is also slightly smaller since there is no auxillary storage.&lt;/p&gt;

&lt;h2&gt;&lt;a href="http://search.cpan.org/perldoc?B::Hooks::XSUB::CallAsOp"&gt;&lt;tt&gt;B::Hooks::XSUB::CallAsOp&lt;/tt&gt;&lt;/a&gt;&lt;/h2&gt;

&lt;p&gt;This module was refactored out of &lt;a href="http://github.com/nothingmuch/continuation-delimited/"&gt;&lt;tt&gt;Continuation::Delimited&lt;/tt&gt;&lt;/a&gt; and lets an XS routine trigger code that will be invoked in the context of its caller.&lt;/p&gt;

&lt;p&gt;This allows a little more freedom in the stack manipulations you can do (which is of course very important for continuations).&lt;/p&gt;

&lt;p&gt;These modules are all possible due to the awesome &lt;a href="http://search.cpan.org/perldoc?ExtUtils::Depends"&gt;&lt;tt&gt;ExtUtils::Depends&lt;/tt&gt;&lt;/a&gt; module. If you find yourself cargo culting XS consider refactoring it into a reusable module using &lt;tt&gt;ExtUtils::Depends&lt;/tt&gt; instead.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/876358347971598886-8978027727098187460?l=blog.woobling.org' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/yuvalkogman/~4/ytb_7pX5Xi8" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.woobling.org/feeds/8978027727098187460/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=876358347971598886&amp;postID=8978027727098187460&amp;isPopup=true" title="2 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/876358347971598886/posts/default/8978027727098187460?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/876358347971598886/posts/default/8978027727098187460?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/yuvalkogman/~3/ytb_7pX5Xi8/hackathon-summary.html" title="Hackathon Summary" /><author><name>nothingmuch</name><uri>http://www.blogger.com/profile/03975438115490089158</uri><email>nothingmuch@woobling.org</email><gd:extendedProperty name="OpenSocialUserId" value="04344917020781355723" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">2</thr:total><feedburner:origLink>http://blog.woobling.org/2009/09/hackathon-summary.html</feedburner:origLink></entry><entry gd:etag="W/&quot;CE4NRX07fyp7ImA9WxNRF0g.&quot;"><id>tag:blogger.com,1999:blog-876358347971598886.post-4495857593292740905</id><published>2009-09-12T13:05:00.004+03:00</published><updated>2009-09-12T13:56:34.307+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-09-12T13:56:34.307+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="git" /><category scheme="http://www.blogger.com/atom/ns#" term="hate" /><title>Git Hate</title><content type="html">&lt;p&gt;I like &lt;a href="http://git-scm.com"&gt;Git&lt;/a&gt;, but sometimes I also really hate it.&lt;/p&gt;

&lt;p&gt;My friend &lt;a href="http://sartak.org/"&gt;Sartak&lt;/a&gt; asked if there is a better way of finding a merge base in a command than hard coding &lt;tt&gt;master&lt;/tt&gt; as the merge point, and I stupidly said "of course, you just check what that branch tracks". That is the same logic that &lt;tt&gt;git pull&lt;/tt&gt; would use, so in theory you can apply the same concise logic to merge or rebase your branch without running &lt;tt&gt;git fetch&lt;/tt&gt;.&lt;/p&gt;

&lt;p&gt;In principle that's correct, but in practice it's utterly worthless.&lt;/p&gt;

&lt;p&gt;The first step is to figure out what branch you are on.&lt;/p&gt;

&lt;p&gt;You could easily do this with the &lt;tt&gt;git-current-branch&lt;/tt&gt; command. Except that it doesn't actually exist. Instead you need to resolve the symbolic ref in head and truncate that string:&lt;/p&gt;

&lt;pre class="fake-gist" id="fake-gist-185798"&gt;$(git symbolic-ref -q HEAD | sed -e 's/^refs\/heads\///'&lt;/pre&gt;

&lt;p&gt;Except that that's actually broken if the symbolic ref points at something not under heads.&lt;/p&gt;

&lt;p&gt;Ignoring that, we now have a string with which we can get our merge metadata:&lt;/p&gt;

&lt;pre class="fake-gist" id="fake-gist-185799"&gt;branch="$( git current-branch )"

git config --get "branch.$branch.remote"
git config --get "branch.$branch.merge"&lt;/pre&gt;

&lt;p&gt;The problem lies in the fact that the tracking refers to the remote, and the ref on the remote:&lt;/p&gt;

&lt;pre class="fake-gist" id="fake-gist-185800"&gt;[branch "master"]
 remote = origin
 merge = refs/heads/master&lt;/pre&gt;

&lt;p&gt;But we want to use the local ref. Based on git config, we can see that this value should be &lt;tt&gt;refs/remotes/origin/master&lt;/tt&gt;:&lt;/p&gt;

&lt;pre class="fake-gist" id="fake-gist-185801"&gt;[remote "origin"]
 url = git://example.com/example.git
 fetch = +refs/heads/*:refs/remotes/origin/*&lt;/pre&gt;

&lt;p&gt;If you read the documentation for &lt;a href="http://www.kernel.org/pub/software/scm/git/docs/git-fetch.html"&gt;&lt;tt&gt;git-fetch&lt;/tt&gt;&lt;/a&gt; you can see the description of the refspec for humans, but it's pretty feature rich.&lt;/p&gt;

&lt;p&gt;Fortunately Git already implements this, so it shouldn't be too hard. Too bad that it is.&lt;/p&gt;

&lt;p&gt;In &lt;tt&gt;builtin-fetch.c&lt;/tt&gt; are a number of &lt;em&gt;static&lt;/em&gt; functions that you could easily copy and paste to do this refspec evaluation in your own code.&lt;/p&gt;

&lt;p&gt;So in short, what should have been a simple helper command has degenerated into an epic yak shave involving cargo culting C and reimplementing commands that should have built in to begin with.&lt;/p&gt;

&lt;p&gt;And for what?&lt;/p&gt;

&lt;pre class="fake-gist" id="fake-gist-185802"&gt;git merge-base $( git-merge-branch $( git current-branch ) ) HEAD&lt;/pre&gt;

&lt;pre&gt;instead of&lt;/pre&gt;

&lt;pre class="fake-gist" id="fake-gist-185803"&gt;git merge-base master HEAD&lt;/pre&gt;

&lt;p&gt;In short, it's completely non-viable to do the right thing, nobody has that much spare time. Instead people just kludge it. These kludges later come back with a vengeance when you assume something does the right thing, and it actually doesn't handle an edge case you didn't think about before you invoked that command.&lt;/p&gt;

&lt;p&gt;I'm not trying to propose a solution, it's been obvious what the solution is for years (a proper &lt;tt&gt;libgit&lt;/tt&gt;). What makes me sad is that this is still a problem today. I just can't fathom any reason that would justify &lt;strong&gt;not&lt;/strong&gt; having a proper way to do this that outweighs the benefit of having one.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/876358347971598886-4495857593292740905?l=blog.woobling.org' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/yuvalkogman/~4/zX1635fCluE" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.woobling.org/feeds/4495857593292740905/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=876358347971598886&amp;postID=4495857593292740905&amp;isPopup=true" title="6 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/876358347971598886/posts/default/4495857593292740905?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/876358347971598886/posts/default/4495857593292740905?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/yuvalkogman/~3/zX1635fCluE/git-hate.html" title="Git Hate" /><author><name>nothingmuch</name><uri>http://www.blogger.com/profile/03975438115490089158</uri><email>nothingmuch@woobling.org</email><gd:extendedProperty name="OpenSocialUserId" value="04344917020781355723" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">6</thr:total><feedburner:origLink>http://blog.woobling.org/2009/09/git-hate.html</feedburner:origLink></entry><entry gd:etag="W/&quot;A0YER349fCp7ImA9WxNRFkU.&quot;"><id>tag:blogger.com,1999:blog-876358347971598886.post-393637844853939244</id><published>2009-09-11T19:45:00.006+03:00</published><updated>2009-09-11T20:11:46.064+03:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-09-11T20:11:46.064+03:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="yapc" /><category scheme="http://www.blogger.com/atom/ns#" term="perl" /><title>YAPC::Tiny, YAPC::Asia</title><content type="html">&lt;p&gt;I'd like to thank to everyone that made my trip to Asia so great thus far.&lt;/p&gt;

&lt;p&gt;To list but a few: thanks to the &lt;a href="http://japan.perlassociation.org/"&gt;JPA&lt;/a&gt; for organizing &lt;a href="http://conferences.yapcasia.org/ya2009/"&gt;YAPC::Asia&lt;/a&gt;, especially Daisuke for being so accommodating when it wasn't clear if I would make it till the end, &lt;a href="http://gugod.org"&gt;gugod&lt;/a&gt; for organizing YAPC::Tiny, &lt;a href="http://twitter.com/charsbar"&gt;Kenichi Ishigaki&lt;/a&gt; and &lt;a href="http://twitter.com/ktat"&gt;Kato Atsushi&lt;/a&gt; for translating my talks (though only one was presented in the end), &lt;a href="http://clkao.org"&gt;clkao&lt;/a&gt; and &lt;a href="http://audreyt.org"&gt;audreyt&lt;/a&gt; for being such great hosts in Taiwan, &lt;a href="http://www.dan.co.jp/~dankogai/"&gt;Dan Kogai&lt;/a&gt; for hosting us at Hotel Dan, and the Japanese and Taiwanese Perl communities in general for being so much fun to be around.&lt;/p&gt;

&lt;p&gt;I'm so indebted to everyone involved in this conference and all of the others, it makes every one of these trips fun and memorable, totally justifying the fact that Perl takes up such an unhealthily large part of my life and income.&lt;/p&gt;

&lt;p&gt;Tomorrow is the hackathon, always my favourite part of conferences. On my agenda:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Hacking with &lt;a href="http://d.hatena.ne.jp/gfx/"&gt;gfx&lt;/a&gt; and &lt;a href="http://perldition.org"&gt;rafl&lt;/a&gt; on Moose's XS stuff&lt;/li&gt;
&lt;li&gt;Fixing a weird corruption that happens with &lt;a href="http://github.com/nothingmuch/continuation-delimited"&gt;&lt;tt&gt;Continuation::Delimited&lt;/tt&gt;&lt;/a&gt;, so that finally it passes all of its tests. Once that happens I can focus on adding new failing tests, which is much more fun ;-)&lt;/li&gt;
&lt;li&gt;Playing with &lt;a href="http://bulknews.typepad.com/blog/2009/09/psgi-perl-wsgi.html"&gt;PSGI/Plack&lt;/a&gt;, &lt;a href="http://github.com/beppu/stardust/"&gt;Stardust&lt;/a&gt;, and other cool things I learned about during the conference and will probably discover tomorrow&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;On Sunday, the last day of my trip, CL and I are going to try to not get killed on &lt;a href="http://i-cjw.com/blog/2009/06/28/where-eagles-darent/"&gt;Mount Myogi&lt;/a&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/876358347971598886-393637844853939244?l=blog.woobling.org' alt='' /&gt;&lt;/div&gt;&lt;img src="http://feeds.feedburner.com/~r/yuvalkogman/~4/dVsJUA8Dquw" height="1" width="1"/&gt;</content><link rel="replies" type="application/atom+xml" href="http://blog.woobling.org/feeds/393637844853939244/comments/default" title="Post Comments" /><link rel="replies" type="text/html" href="https://www.blogger.com/comment.g?blogID=876358347971598886&amp;postID=393637844853939244&amp;isPopup=true" title="0 Comments" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/876358347971598886/posts/default/393637844853939244?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/876358347971598886/posts/default/393637844853939244?v=2" /><link rel="alternate" type="text/html" href="http://feedproxy.google.com/~r/yuvalkogman/~3/dVsJUA8Dquw/yapctiny-yapcasia.html" title="YAPC::Tiny, YAPC::Asia" /><author><name>nothingmuch</name><uri>http://www.blogger.com/profile/03975438115490089158</uri><email>nothingmuch@woobling.org</email><gd:extendedProperty name="OpenSocialUserId" value="04344917020781355723" /></author><thr:total xmlns:thr="http://purl.org/syndication/thread/1.0">0</thr:total><feedburner:origLink>http://blog.woobling.org/2009/09/yapctiny-yapcasia.html</feedburner:origLink></entry></feed>
