<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:sy="http://purl.org/rss/1.0/modules/syndication/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:creativeCommons="http://backend.userland.com/creativeCommonsRssModule" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>A Foolish Manifesto</title>
	
	<link>http://blog.afoolishmanifesto.com</link>
	<description>fREWdiculous!</description>
	<lastBuildDate>Tue, 09 Mar 2010 01:28:40 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/rss+xml" href="http://feeds.feedburner.com/AFoolishManifesto" /><feedburner:info uri="afoolishmanifesto" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><creativeCommons:license>http://creativecommons.org/licenses/by-sa/3.0/</creativeCommons:license><image><link>http://creativecommons.org/licenses/by-sa/3.0/</link><url>http://creativecommons.org/images/public/somerights20.gif</url><title>Some Rights Reserved</title></image><feedburner:feedFlare href="http://add.my.yahoo.com/rss?url=http%3A%2F%2Ffeeds.feedburner.com%2FAFoolishManifesto" src="http://us.i1.yimg.com/us.yimg.com/i/us/my/addtomyyahoo4.gif">Subscribe with My Yahoo!</feedburner:feedFlare><feedburner:feedFlare href="http://www.newsgator.com/ngs/subscriber/subext.aspx?url=http%3A%2F%2Ffeeds.feedburner.com%2FAFoolishManifesto" src="http://www.newsgator.com/images/ngsub1.gif">Subscribe with NewsGator</feedburner:feedFlare><feedburner:feedFlare href="http://feeds.my.aol.com/add.jsp?url=http%3A%2F%2Ffeeds.feedburner.com%2FAFoolishManifesto" src="http://o.aolcdn.com/favorites.my.aol.com/webmaster/ffclient/webroot/locale/en-US/images/myAOLButtonSmall.gif">Subscribe with My AOL</feedburner:feedFlare><feedburner:feedFlare href="http://www.bloglines.com/sub/http://feeds.feedburner.com/AFoolishManifesto" src="http://www.bloglines.com/images/sub_modern11.gif">Subscribe with Bloglines</feedburner:feedFlare><feedburner:feedFlare href="http://www.netvibes.com/subscribe.php?url=http%3A%2F%2Ffeeds.feedburner.com%2FAFoolishManifesto" src="http://www.netvibes.com/img/add2netvibes.gif">Subscribe with Netvibes</feedburner:feedFlare><feedburner:feedFlare href="http://fusion.google.com/add?feedurl=http%3A%2F%2Ffeeds.feedburner.com%2FAFoolishManifesto" src="http://buttons.googlesyndication.com/fusion/add.gif">Subscribe with Google</feedburner:feedFlare><feedburner:feedFlare href="http://www.pageflakes.com/subscribe.aspx?url=http%3A%2F%2Ffeeds.feedburner.com%2FAFoolishManifesto" src="http://www.pageflakes.com/ImageFile.ashx?instanceId=Static_4&amp;fileName=ATP_blu_91x17.gif">Subscribe with Pageflakes</feedburner:feedFlare><feedburner:feedFlare href="http://www.plusmo.com/add?url=http%3A%2F%2Ffeeds.feedburner.com%2FAFoolishManifesto" src="http://plusmo.com/res/graphics/fbplusmo.gif">Subscribe with Plusmo</feedburner:feedFlare><feedburner:feedFlare href="http://www.thefreedictionary.com/_/hp/AddRSS.aspx?http%3A%2F%2Ffeeds.feedburner.com%2FAFoolishManifesto" src="http://img.tfd.com/hp/addToTheFreeDictionary.gif">Subscribe with The Free Dictionary</feedburner:feedFlare><feedburner:feedFlare href="http://www.bitty.com/manual/?contenttype=rssfeed&amp;contentvalue=http%3A%2F%2Ffeeds.feedburner.com%2FAFoolishManifesto" src="http://www.bitty.com/img/bittychicklet_91x17.gif">Subscribe with Bitty Browser</feedburner:feedFlare><feedburner:feedFlare href="http://www.newsalloy.com/?rss=http%3A%2F%2Ffeeds.feedburner.com%2FAFoolishManifesto" src="http://www.newsalloy.com/subrss3.gif">Subscribe with NewsAlloy</feedburner:feedFlare><feedburner:feedFlare href="http://www.live.com/?add=http%3A%2F%2Ffeeds.feedburner.com%2FAFoolishManifesto" src="http://tkfiles.storage.msn.com/x1piYkpqHC_35nIp1gLE68-wvzLZO8iXl_JMledmJQXP-XTBOLfmQv4zhj4MhcWEJh_GtoBIiAl1Mjh-ndp9k47If7hTaFno0mxW9_i3p_5qQw">Subscribe with Live.com</feedburner:feedFlare><feedburner:feedFlare href="http://mix.excite.eu/add?feedurl=http%3A%2F%2Ffeeds.feedburner.com%2FAFoolishManifesto" src="http://image.excite.co.uk/mix/addtomix.gif">Subscribe with Excite MIX</feedburner:feedFlare><feedburner:feedFlare href="http://www.yourminis.com/subscribe.aspx?u=http%3A%2F%2Ffeeds.feedburner.com%2FAFoolishManifesto" src="http://www.yourminis.com/images/addtoyourminisbadge.gif">Subscribe with Yourminis.com</feedburner:feedFlare><feedburner:feedFlare href="http://download.attensa.com/app/get_attensa.html?feedurl=http%3A%2F%2Ffeeds.feedburner.com%2FAFoolishManifesto" src="http://www.attensa.com/blogs/attensa/WindowsLiveWriter/BadgeredintoBadges_10C02/attensa_feed_button5.gif">Subscribe with Attensa for Outlook</feedburner:feedFlare><feedburner:feedFlare href="http://www.webwag.com/wwgthis.php?url=http%3A%2F%2Ffeeds.feedburner.com%2FAFoolishManifesto" src="http://www.webwag.com/images/wwgthis.gif">Subscribe with Webwag</feedburner:feedFlare><feedburner:feedFlare href="http://hub.netomat.net/account/account.autoSubscribe.jspa?urls=http%3A%2F%2Ffeeds.feedburner.com%2FAFoolishManifesto" src="http://www.netomat.net/blogger/images/icon_netomat_feedbutton.gif">Subscribe with netomat Hub</feedburner:feedFlare><feedburner:feedFlare href="http://www.podcastready.com/oneclick_bookmark.php?url=http%3A%2F%2Ffeeds.feedburner.com%2FAFoolishManifesto" src="http://www.podcastready.com/images/podcastready_button.gif">Subscribe with Podcast Ready</feedburner:feedFlare><feedburner:feedFlare href="http://www.flurry.com/pushRssFeed.do?r=fb&amp;url=http%3A%2F%2Ffeeds.feedburner.com%2FAFoolishManifesto" src="http://www.flurry.com/images/flurry_rss_logo2.gif">Subscribe with Flurry</feedburner:feedFlare><feedburner:feedFlare href="http://www.wikio.com/subscribe?url=http%3A%2F%2Ffeeds.feedburner.com%2FAFoolishManifesto" src="http://www.wikio.com/shared/img/add2wikio.gif">Subscribe with Wikio</feedburner:feedFlare><feedburner:feedFlare href="http://www.dailyrotation.com/index.php?feed=http%3A%2F%2Ffeeds.feedburner.com%2FAFoolishManifesto" src="http://www.dailyrotation.com/rss-dr2.gif">Subscribe with Daily Rotation</feedburner:feedFlare><item>
		<title>The Rise and Fall of mod_perl</title>
		<link>http://feedproxy.google.com/~r/AFoolishManifesto/~3/sL1-Dm96dt0/1303</link>
		<comments>http://blog.afoolishmanifesto.com/archives/1303#comments</comments>
		<pubDate>Tue, 09 Mar 2010 01:28:40 +0000</pubDate>
		<dc:creator>fREW Schmidt</dc:creator>
				<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://blog.afoolishmanifesto.com/?p=1303</guid>
		<description><![CDATA[In February of 2008 I figured out how to switch our servers from IIS to Apache.  The main reason I did that was because if you print to STDERR in Perl while running under IIS the server would crash hard.  In general it just took some research and motivation.  All was well [...]]]></description>
			<content:encoded><![CDATA[<p>In February of 2008 I figured out how to <a href="http://blog.afoolishmanifesto.com/archives/59">switch our servers from IIS to Apache</a>.  The main reason I did that was because if you print to STDERR in Perl while running under IIS the server would crash hard.  In general it just took some research and motivation.  All was well with the world&#8230;.  For six months.</p>
<p>After switching to Apache we needed a way (previously accomplished with PerlEx from ActiveState) to run certain scripts persistently.  I did some research and discovered that <a href="http://blog.afoolishmanifesto.com/archives/402">using mod_perl in win32</a> was feasible and you can indeed turn it on for parts of your site.  Yet again, all was well with the world.</p>
<p>Unfortunately as time passed and we started using a deeper stack of Perl (we originally were just using <a href="http://search.cpan.org/perldoc?DBI">DBI</a>, <a href="http://search.cpan.org/perldoc?DBI">the Perl database layer</a>,  and <em>sometimes</em> using <a href="http://search.cpan.org/perldoc?Template">Template::Toolkit</a>, one of the most major <a href="http://search.cpan.org/perldoc?Template">Perl templating systems</a>,) we started seeing Apache crashing or leaking memory.  Unlike IIS crashes the cause and time till crash was unpredictable, but after some <a href="https://rt.cpan.org/Public/Bug/Display.html?id=50454">work</a> the issue was found and fixed.</p>
<p>During this time I and all but one of my coworkers switched to the most excellent <a href="http://strawberryperl.com/">Strawberry Perl</a>, the <a href="http://strawberryperl.com/">Windows Perl</a> one might say.  Logging in to the servers to install packages with PPM quickly soured for me and I spent probably 3 days worth of my time (half of which was unpaid!) trying to find a way to use Strawberry persistently.  If we could use Strawberry on the servers installing dependencies would boil down to</p>
<div class="codecolorer-container text vibrant" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">cpanm --installdeps .</div></td></tr></tbody></table></div>
<p>But I couldn&#8217;t seem to get mod_perl to build, mod_fcgid and mod_fastcgi were both unworkable (for me anyway,) and I couldn&#8217;t get lighttpd + FastCGI to work.  So I gave up on that endeavor.</p>
<p>Nearly four months have passed since the crashing Apache issue was originally solved and just days ago we deployed our <a href="http://blog.afoolishmanifesto.com/archives/1039">first Catalyst project</a> (we have two more in the pipeline now!)  We deployed onto mod_perl and Apache on Windows.  I would never recommend deploying onto Windows, but I also realize that there are business reasons to do so and sometimes it&#8217;s just what you have to do.</p>
<p>And all was well with the world&#8230;for two page requests.  It turns out that <strong>somewhere</strong> in our stack of Perl, Apache, mod_perl, and Windows there was an issue that made the server consistently crash after nearly every other request.  I did some <a href="http://perl.apache.org/docs/2.0/api/Apache2/SizeLimit.html">research</a>, and even built up a replica of our deploy on my machine (linux) to see if the issue was generic mod_perl.  If it <strong>were</strong> a problem in Linux it would be much easier to get free help from the community, but alas, it ran perfectly on my machine.</p>
<p>While I was driving to a friend&#8217;s recently I had a thought; <em>why not just use the Catalyst development server or some other Perl based server and just proxy to it with Apache?</em>  Heck, it&#8217;s actually very similar to one of the recommended ways to deploy Catalyst in <a href="http://www.amazon.com/gp/product/1430223650?ie=UTF8&#038;tag=afooman-20&#038;linkCode=as2&#038;camp=1789&#038;creative=390957&#038;creativeASIN=1430223650">the Catalyst book</a><img src="http://www.assoc-amazon.com/e/ir?t=afooman-20&#038;l=as2&#038;o=1&#038;a=1430223650" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" />.</p>
<p>Before I get into the details of this I need to point out that we are <strong>not</strong> using HTTP::Prefork, thanks to Windows.  If you have a large site you really should not use Windows, for numerous reasons.  That was the conclusion that my boss and I came to anyway.</p>
<p>First off, here is the Apache configuration we ended up with:</p>
<div class="codecolorer-container text vibrant" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br />33<br />34<br />35<br />36<br />37<br />38<br />39<br />40<br />41<br />42<br /></div></td><td><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">ServerRoot &quot;C:/Program Files (x86)/Apache Software Foundation/Apache2.2&quot;<br />
ServerName &quot;ourapp.foo.com&quot;<br />
Listen 80<br />
LoadModule alias_module modules/mod_alias.so<br />
LoadModule deflate_module modules/mod_deflate.so<br />
LoadModule expires_module modules/mod_expires.so<br />
LoadModule env_module modules/mod_env.so<br />
LoadModule log_config_module modules/mod_log_config.so<br />
LoadModule mime_module modules/mod_mime.so<br />
LoadModule setenvif_module modules/mod_setenvif.so<br />
LoadModule proxy_module modules/mod_proxy.so<br />
LoadModule proxy_http_module modules/mod_proxy_http.so<br />
LoadModule proxy_balancer_module modules/mod_proxy_balancer.so<br />
<br />
ExpiresActive On<br />
ProxyRequests Off<br />
<br />
&lt;Proxy balancer://my_cluster&gt;<br />
&nbsp; &nbsp;BalancerMember http://127.0.0.1:39564<br />
&nbsp; &nbsp;BalancerMember http://127.0.0.1:39565<br />
&lt;/Proxy&gt;<br />
ProxyPass / balancer://my_cluster/<br />
# we don't use this because our app is a single page<br />
# javascript application<br />
# ProxyPassReverse / balancer://my_cluster/<br />
<br />
DocumentRoot &quot;C:/myapp/root/&quot;<br />
&lt;Location /static&gt;<br />
&nbsp; &nbsp;SetOutputFilter DEFLATE<br />
&nbsp; &nbsp;SetEnvIfNoCase Request_URI \.(?:gif|jpe?g|png)$ no-gzip dont-vary<br />
&nbsp; &nbsp;SetHandler default-handler<br />
&lt;/Location&gt;<br />
<br />
LogLevel warn<br />
<br />
LogFormat &quot;%h %l %u %t \&quot;%r\&quot; %&gt;s %b \&quot;%{Referer}i\&quot; \&quot;%{User-Agent}i\&quot;&quot; combined<br />
LogFormat &quot;%h %l %u %t \&quot;%r\&quot; %&gt;s %b&quot; common<br />
CustomLog &quot;logs/access.log&quot; common<br />
DefaultType text/plain<br />
TypesConfig conf/mime.types<br />
AddType application/x-compress .Z<br />
AddType application/x-gzip .gz .tgz</div></td></tr></tbody></table></div>
<p>So basically all we do in this configuration is have Apache serve the static files and then proxy the requests to a couple of catalyst dev servers.  I used <a href="http://support.microsoft.com/kb/137890">Srvany.exe</a> and a couple of .bat files to start the catalyst dev servers.  It works <strong>much</strong> better than using mod_perl, and each server sits at about 90M a piece.  If we ended up getting a huge site and for some strange reason needed to keep our outfacing server windows, we could actually serve the catalyst parts on a linux server and have apache proxy to those, so it scales very nicely.</p>
<p>Anyway, here&#8217;s to the next 6 months of serving! <img src='http://blog.afoolishmanifesto.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<div id="crp_related"><h2>Related Posts:</h2><ul><li><a href="http://blog.afoolishmanifesto.com/archives/59" rel="bookmark" class="crp_title">Migrating from IIS to Apache</a></li><li><a href="http://blog.afoolishmanifesto.com/archives/402" rel="bookmark" class="crp_title">mod_perl: For Your Health!</a></li><li><a href="http://blog.afoolishmanifesto.com/archives/707" rel="bookmark" class="crp_title">What I want from the Perl 5 support policy</a></li><li><a href="http://blog.afoolishmanifesto.com/archives/596" rel="bookmark" class="crp_title">PerlCritic for Web Developers</a></li><li><a href="http://blog.afoolishmanifesto.com/archives/1075" rel="bookmark" class="crp_title">Metrics + Debug!</a></li><li>Powered by <a href="http://ajaydsouza.com/wordpress/plugins/contextual-related-posts/">Contextual Related Posts</a></li></ul></div><img src="http://feeds.feedburner.com/~r/AFoolishManifesto/~4/sL1-Dm96dt0" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.afoolishmanifesto.com/archives/1303/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://blog.afoolishmanifesto.com/archives/1303</feedburner:origLink></item>
		<item>
		<title>Announcing Log::Contextual</title>
		<link>http://feedproxy.google.com/~r/AFoolishManifesto/~3/j8ExIZyHiY4/1300</link>
		<comments>http://blog.afoolishmanifesto.com/archives/1300#comments</comments>
		<pubDate>Tue, 23 Feb 2010 04:45:11 +0000</pubDate>
		<dc:creator>fREW Schmidt</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[cpan]]></category>
		<category><![CDATA[Log::Contextual]]></category>
		<category><![CDATA[perl]]></category>

		<guid isPermaLink="false">http://blog.afoolishmanifesto.com/?p=1300</guid>
		<description><![CDATA[I really should have posted this sooner.  Certainly before I began my next project.  Oh well.
I am proud to announce the next bit of mstware!  Log::Contextual is a small module for making your life easier when it comes to logging.  Instead of bringing yet another logging infrastructure into the mix (see [...]]]></description>
			<content:encoded><![CDATA[<p>I really should have posted this sooner.  Certainly before I began my <a href="http://git.shadowcat.co.uk/gitweb/gitweb.cgi?p=dbsrgits/DBIx-Class-DeploymentHandler.git">next project</a>.  Oh well.</p>
<p>I am proud to announce the next bit of mstware!  <a href="http://search.cpan.org/perldoc?Log::Contextual">Log::Contextual</a> is a small module for making your life easier when it comes to logging.  Instead of bringing yet another logging infrastructure into the mix (see <a href="http://search.cpan.org/perldoc?Log::Log4perl">Log::Log4perl</a> and <a href="http://search.cpan.org/perldoc?Log::Dispatch">Log::Dispatch</a>), this module is a thin wrapper around any logging system you choose to use.  (Note: we are working with authors of major logging packages to work seamlessly with L::C, but at the time of writing most need some form of adapter.)</p>
<p>There are a few major features worth noting.  First off, ridiculously convenient interface.  Once you&#8217;ve set up your logger (presumably in the startup of your app or whatever) all your logging code will look like the following:</p>
<div class="codecolorer-container perl vibrant" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br /></div></td><td><div class="perl codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">use</span> Log<span style="color: #339933;">::</span><span style="color: #006600;">Contextual</span> <a href="http://perldoc.perl.org/functions/qw.html"><span style="color: #000066;">qw</span></a><span style="color: #009900;">&#40;</span> <span style="color: #339933;">:</span><a href="http://perldoc.perl.org/functions/log.html"><span style="color: #000066;">log</span></a> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #000000; font-weight: bold;">sub</span> hello_world <span style="color: #009900;">&#123;</span><br />
&nbsp; log_trace <span style="color: #009900;">&#123;</span> <span style="color: #ff0000;">'entered hello world'</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span><br />
&nbsp; <span style="color: #666666; font-style: italic;"># ...</span><br />
<span style="color: #009900;">&#125;</span></div></td></tr></tbody></table></div>
<p>Another great thing is that, like <a href="http://search.cpan.org/perldoc?Devel::Dwarn">Devel::Dwarn</a>, all of the logging functions are <a href="http://en.wikipedia.org/wiki/Identity_function">identity functions</a>; that is, they return their arguments.  That means you can do cool things like the following:</p>
<div class="codecolorer-container perl vibrant" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br /></div></td><td><div class="perl codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">use</span> Log<span style="color: #339933;">::</span><span style="color: #006600;">Contextual</span> <a href="http://perldoc.perl.org/functions/qw.html"><span style="color: #000066;">qw</span></a><span style="color: #009900;">&#40;</span> <span style="color: #339933;">:</span><a href="http://perldoc.perl.org/functions/log.html"><span style="color: #000066;">log</span></a> <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #000000; font-weight: bold;">sub</span> hello_world <span style="color: #009900;">&#123;</span><br />
&nbsp; <span style="color: #b1b100;">my</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$arg1</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">$arg2</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">=</span> log_trace <span style="color: #009900;">&#123;</span> <span style="color: #ff0000;">&quot;entered hello world with args $_[0], $_[1]&quot;</span> <span style="color: #009900;">&#125;</span> <span style="color: #0000ff;">@_</span><span style="color: #339933;">;</span><br />
&nbsp; <br />
&nbsp; <span style="color: #666666; font-style: italic;"># ...</span><br />
<span style="color: #009900;">&#125;</span></div></td></tr></tbody></table></div>
<p>Of course, in Perl you may be passing around complex references and the above will get cumbersome fast, so we added shortcuts specifically for logging out data structures:</p>
<div class="codecolorer-container perl vibrant" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br /></div></td><td><div class="perl codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">use</span> Log<span style="color: #339933;">::</span><span style="color: #006600;">Contextual</span> <a href="http://perldoc.perl.org/functions/qw.html"><span style="color: #000066;">qw</span></a><span style="color: #009900;">&#40;</span> <span style="color: #339933;">:</span>dlog <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #000000; font-weight: bold;">sub</span> hello_world <span style="color: #009900;">&#123;</span><br />
&nbsp; <span style="color: #b1b100;">my</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$arg1</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">$arg2</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">=</span> Dlog_trace <span style="color: #009900;">&#123;</span> <span style="color: #ff0000;">&quot;entered hello world with args $_&quot;</span> <span style="color: #009900;">&#125;</span> <span style="color: #0000ff;">@_</span><span style="color: #339933;">;</span><br />
&nbsp; <br />
&nbsp; <span style="color: #666666; font-style: italic;"># ...</span><br />
<span style="color: #009900;">&#125;</span></div></td></tr></tbody></table></div>
<p>The automatic stringification is done with <a href="http://search.cpan.org/perldoc?Data::Dumper::Concise">Data::Dumper::Concise</a>, so you will get reasonably indented output for free.</p>
<p>In a separate package we are going to provide a module to basically turn the logging functions into no-ops at compile time, thus giving you the ability to have your code run just as fast if it never had the logging functions in in the first place.  I&#8217;ll post more on that once it&#8217;s released.</p>
<p>So what are you waiting for?  Go log stuff!</p>
<div id="crp_related"><h2>Related Posts:</h2><ul><li><a href="http://blog.afoolishmanifesto.com/archives/635" rel="bookmark" class="crp_title">Profilers or more specifically NYTProf</a></li><li><a href="http://blog.afoolishmanifesto.com/archives/633" rel="bookmark" class="crp_title">Future Perl</a></li><li><a href="http://blog.afoolishmanifesto.com/archives/59" rel="bookmark" class="crp_title">Migrating from IIS to Apache</a></li><li><a href="http://blog.afoolishmanifesto.com/archives/1032" rel="bookmark" class="crp_title">My New Hammers</a></li><li><a href="http://blog.afoolishmanifesto.com/archives/1234" rel="bookmark" class="crp_title">New stuff in DBIx::Class::Helpers</a></li><li>Powered by <a href="http://ajaydsouza.com/wordpress/plugins/contextual-related-posts/">Contextual Related Posts</a></li></ul></div><img src="http://feeds.feedburner.com/~r/AFoolishManifesto/~4/j8ExIZyHiY4" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.afoolishmanifesto.com/archives/1300/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://blog.afoolishmanifesto.com/archives/1300</feedburner:origLink></item>
		<item>
		<title>New DBIx::Class::Journal</title>
		<link>http://feedproxy.google.com/~r/AFoolishManifesto/~3/pYdFpBA1W2Q/1296</link>
		<comments>http://blog.afoolishmanifesto.com/archives/1296#comments</comments>
		<pubDate>Thu, 18 Feb 2010 17:04:11 +0000</pubDate>
		<dc:creator>fREW Schmidt</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[cpan]]></category>
		<category><![CDATA[dbix::class]]></category>
		<category><![CDATA[DBIx::class::journal]]></category>
		<category><![CDATA[perl]]></category>

		<guid isPermaLink="false">http://blog.afoolishmanifesto.com/?p=1296</guid>
		<description><![CDATA[We are planning on using DBIx::Class::Journal in a couple different projects of ours.  Unfortunately DBICJ has foundered for more than a year as a dev release, and even that won&#8217;t test correctly on win32.  So I&#8217;ve done some work on it to get it in a more releasable state.  I just released [...]]]></description>
			<content:encoded><![CDATA[<p>We are planning on using <a href="http://search.cpan.org/perldoc?DBIx::Class::Journal">DBIx::Class::Journal</a> in a couple different projects of ours.  Unfortunately DBICJ has foundered for more than a year as a dev release, and even that won&#8217;t test correctly on win32.  So I&#8217;ve done some work on it to get it in a more releasable state.  I just released a developer release to CPAN and if you currently use DBICJ please test it out.  Even if you don&#8217;t use it at least test it so I can see if I get failures.  The release should end up <a href="http://search.cpan.org/~frew/DBIx-Class-Journal-0.900001_03/">here</a>, but it will take a couple hours.</p>
<div id="crp_related"><h2>Related Posts:</h2><ul><li><a href="http://blog.afoolishmanifesto.com/archives/1289" rel="bookmark" class="crp_title">New stuff in DBIx::Class::Helpers 2.00200</a></li><li><a href="http://blog.afoolishmanifesto.com/archives/1202" rel="bookmark" class="crp_title">Writing vs. Writing</a></li><li><a href="http://blog.afoolishmanifesto.com/archives/1234" rel="bookmark" class="crp_title">New stuff in DBIx::Class::Helpers</a></li><li><a href="http://blog.afoolishmanifesto.com/archives/1261" rel="bookmark" class="crp_title">Latest additions to DBIC::Helpers</a></li><li><a href="http://blog.afoolishmanifesto.com/archives/1207" rel="bookmark" class="crp_title">JAP(5|6)H</a></li><li>Powered by <a href="http://ajaydsouza.com/wordpress/plugins/contextual-related-posts/">Contextual Related Posts</a></li></ul></div><img src="http://feeds.feedburner.com/~r/AFoolishManifesto/~4/pYdFpBA1W2Q" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.afoolishmanifesto.com/archives/1296/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://blog.afoolishmanifesto.com/archives/1296</feedburner:origLink></item>
		<item>
		<title>New stuff in DBIx::Class::Helpers 2.00200</title>
		<link>http://feedproxy.google.com/~r/AFoolishManifesto/~3/6_jPhoWHg2E/1289</link>
		<comments>http://blog.afoolishmanifesto.com/archives/1289#comments</comments>
		<pubDate>Sun, 07 Feb 2010 07:32:24 +0000</pubDate>
		<dc:creator>fREW Schmidt</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[cpan]]></category>
		<category><![CDATA[dbix::class]]></category>
		<category><![CDATA[dbix::class::helpers]]></category>
		<category><![CDATA[perl]]></category>

		<guid isPermaLink="false">http://blog.afoolishmanifesto.com/?p=1289</guid>
		<description><![CDATA[A new release of the resplendent Perl ORM DBIx::Class means new release of DBIx::Class::Helpers
The ResultSet::Random helper had the wrong function used for MySQL.  That was fixed thanks to an RT from pldoh.
get_namespace_parts from the util package was unnecessarily strict.  Thanks to melo for the prodding to do that.
I refactored some of the code [...]]]></description>
			<content:encoded><![CDATA[<p>A new release of the resplendent <a href="http://search.cpan.org/perldoc?DBIx::Class">Perl ORM</a> <a href="http://search.cpan.org/perldoc?DBIx::Class">DBIx::Class</a> means new release of <a href="http://search.cpan.org/perldoc?DBIx::Class::Helpers">DBIx::Class::Helpers</a></p>
<p>The <a href="http://search.cpan.org/~frew/DBIx-Class-Helpers-2.00200/lib/DBIx/Class/Helper/ResultSet/Random.pm">ResultSet::Random helper</a> had the wrong function used for MySQL.  That was fixed thanks to an RT from pldoh.</p>
<p>get_namespace_parts from <A href="http://search.cpan.org/~frew/DBIx-Class-Helpers-2.00200/lib/DBIx/Class/Helpers/Util.pm">the util package</a> was unnecessarily strict.  Thanks to melo for the prodding to do that.</p>
<p>I refactored some of the code in core DBIx::Class so that I can more easily detect is_numeric with <a href="http://search.cpan.org/~frew/DBIx-Class-Helpers-2.00200/lib/DBIx/Class/Helper/Row/NumifyGet.pm">Row::NumifyGet</a>, instead of requiring the user to specify it.  Normally DBIx::Class autodetects it based on column type, but that code wasn&#8217;t quite generic enough until now.  Nice!</p>
<p>And then the most exciting bit is a new helper entirely for the suite: <a href="http://search.cpan.org/~frew/DBIx-Class-Helpers-2.00200/lib/DBIx/Class/Helper/Row/ToJSON.pm">Row::ToJSON</a>.  Basically I was sick of doing this:</p>
<div class="codecolorer-container perl vibrant" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br /></div></td><td><div class="perl codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><a href="http://perldoc.perl.org/functions/package.html"><span style="color: #000066;">package</span></a> ACD<span style="color: #339933;">::</span><span style="color: #006600;">Schema</span><span style="color: #339933;">::</span><span style="color: #006600;">Result</span><span style="color: #339933;">::</span><span style="color: #006600;">Foo</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #666666; font-style: italic;"># regular package stuff here</span><br />
<br />
<span style="color: #000000; font-weight: bold;">sub</span> TO_JSON <span style="color: #009900;">&#123;</span><br />
&nbsp; <span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$self</span> <span style="color: #339933;">=</span> <a href="http://perldoc.perl.org/functions/shift.html"><span style="color: #000066;">shift</span></a><span style="color: #339933;">;</span><br />
&nbsp; <a href="http://perldoc.perl.org/functions/return.html"><span style="color: #000066;">return</span></a> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; id <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">$self</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">id</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; foo <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">$self</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">foo</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; <span style="color: #666666; font-style: italic;"># etc etc ad nausium </span><br />
&nbsp; <span style="color: #009900;">&#125;</span><br />
<span style="color: #009900;">&#125;</span><br />
<br />
<span style="color: #ff0000;">&quot;distraction&quot;</span><span style="color: #339933;">;</span></div></td></tr></tbody></table></div>
<p>Of course that can be shortened to:</p>
<div class="codecolorer-container perl vibrant" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br /></div></td><td><div class="perl codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">sub</span> TO_JSON <span style="color: #009900;">&#123;</span><br />
&nbsp; <span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$self</span> <span style="color: #339933;">=</span> <a href="http://perldoc.perl.org/functions/shift.html"><span style="color: #000066;">shift</span></a><span style="color: #339933;">;</span><br />
&nbsp; <a href="http://perldoc.perl.org/functions/return.html"><span style="color: #000066;">return</span></a> <span style="color: #009900;">&#123;</span> <a href="http://perldoc.perl.org/functions/map.html"><span style="color: #000066;">map</span></a> <span style="color: #339933;">+</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">$_</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">$self</span><span style="color: #339933;">-&gt;</span><span style="color: #0000ff;">$_</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <a href="http://perldoc.perl.org/functions/qw.html"><span style="color: #000066;">qw</span></a><span style="color: #009900;">&#123;</span>id foo <span style="color: #339933;">...</span><span style="color: #009900;">&#125;</span> <span style="color: #009900;">&#125;</span><br />
<span style="color: #009900;">&#125;</span></div></td></tr></tbody></table></div>
<p>But I still have to make that stupid columns list!  This shiny new helper makes a TO_JSON method that will simply include all of your columns except for the &#8220;heavy&#8221; ones like TEXT, NTEXT, or BLOB.  Of course you can have finer-grained control than that by explicitly saying to include (or not) a column in it&#8217;s configuration.  See <a href="http://search.cpan.org/~frew/DBIx-Class-Helpers-2.00200/lib/DBIx/Class/Helper/Row/ToJSON.pm">the docs</a> for all the nitty gritty details.</p>
<div id="crp_related"><h2>Related Posts:</h2><ul><li><a href="http://blog.afoolishmanifesto.com/archives/1261" rel="bookmark" class="crp_title">Latest additions to DBIC::Helpers</a></li><li><a href="http://blog.afoolishmanifesto.com/archives/1234" rel="bookmark" class="crp_title">New stuff in DBIx::Class::Helpers</a></li><li><a href="http://blog.afoolishmanifesto.com/archives/1296" rel="bookmark" class="crp_title">New DBIx::Class::Journal</a></li><li><a href="http://blog.afoolishmanifesto.com/archives/1273" rel="bookmark" class="crp_title">Solution on how to serialize dates nicely</a></li><li><a href="http://blog.afoolishmanifesto.com/archives/274" rel="bookmark" class="crp_title">Paranoid Deletion in DBIx::Class</a></li><li>Powered by <a href="http://ajaydsouza.com/wordpress/plugins/contextual-related-posts/">Contextual Related Posts</a></li></ul></div><img src="http://feeds.feedburner.com/~r/AFoolishManifesto/~4/6_jPhoWHg2E" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.afoolishmanifesto.com/archives/1289/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://blog.afoolishmanifesto.com/archives/1289</feedburner:origLink></item>
		<item>
		<title>Do Passwords Right</title>
		<link>http://feedproxy.google.com/~r/AFoolishManifesto/~3/FdcDwbcx__I/1286</link>
		<comments>http://blog.afoolishmanifesto.com/archives/1286#comments</comments>
		<pubDate>Thu, 04 Feb 2010 05:20:47 +0000</pubDate>
		<dc:creator>fREW Schmidt</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[catalyst]]></category>
		<category><![CDATA[dbix::class]]></category>
		<category><![CDATA[dbix::class::encodedcolumn]]></category>
		<category><![CDATA[eksblowfish]]></category>
		<category><![CDATA[perl]]></category>

		<guid isPermaLink="false">http://blog.afoolishmanifesto.com/?p=1286</guid>
		<description><![CDATA[You all know not to put your passwords into the database in plaintext.  Catalyst and DBIx::Class::EncodedColumn make doing this super easy and completely secure.
First off, you might want to check out the wikipedia article about cryptographic hash functions.  The gist of it though is this: a password stored in plain text is obviously [...]]]></description>
			<content:encoded><![CDATA[<p>You all know not to put your passwords into the database in plaintext.  <a href="http://search.cpan.org/perldoc?Catalyst::Runtime">Catalyst</a> and <a href="http://search.cpan.org/perldoc?DBIx::Class::EncodedColumn">DBIx::Class::EncodedColumn</a> make doing this super easy and completely secure.</p>
<p>First off, you might want to check out the <a href="http://en.wikipedia.org/wiki/Cryptographic_hash_function">wikipedia article</a> about cryptographic hash functions.  The gist of it though is this: a password stored in plain text is obviously compromised if the passwords file gets into the hands of evildoers.  You can &#8220;hash&#8221; the passwords and they are now harder for the attackers to transform into plain-text.  If your password is good it is nearly impossible, but basically what can happen is that the attacker uses the algorithm to generate hashes for every word in the dictionary or whatever and now they basically can crack all the basic passwords.  </p>
<p>You can take it a step further and &#8220;salt&#8221; your passwords (<a href"http://en.wikipedia.org/wiki/Salt_%28cryptography%29">wikipedia salt article</a>.)  A simple way of doing that is just to concatenate some string onto the end of all of your passwords.  This will make dictionary attempts useless unless they know your salt.  Typically when using a salt the salt is kept secret.</p>
<p>And then you can have a unique salt per password.  Imagine a scheme where the salt is $username$id.  It would require the attackers to basically generate a dictionary per user!</p>
<p>The scheme we&#8217;ve settled on uses <a href="http://en.wikipedia.org/wiki/Crypt_(Unix)#Blowfish-based_scheme">Eksblowfish</a>.  The <a href="http://search.cpan.org/~frew/DBIx-Class-EncodedColumn-0.00006/lib/DBIx/Class/EncodedColumn/Crypt/Eksblowfish/Bcrypt.pm">DBIC Component</a> for it actually uses a 16 character randomly generated salt for every password.  Nice!</p>
<p>Ok, so how does one apply such sweet, sweet code?  First, (always) set up your model.  This is a slightly trimmed version of ours:</p>
<div class="codecolorer-container perl vibrant" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br />33<br />34<br />35<br />36<br />37<br /></div></td><td><div class="perl codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><a href="http://perldoc.perl.org/functions/package.html"><span style="color: #000066;">package</span></a> MTSI<span style="color: #339933;">::</span><span style="color: #006600;">Schema</span><span style="color: #339933;">::</span><span style="color: #006600;">Result</span><span style="color: #339933;">::</span><span style="color: #006600;">User</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #000000; font-weight: bold;">use</span> strict<span style="color: #339933;">;</span><br />
<span style="color: #000000; font-weight: bold;">use</span> warnings<span style="color: #339933;">;</span><br />
<br />
<span style="color: #000000; font-weight: bold;">use</span> parent <span style="color: #ff0000;">'DBIx::Class::Core'</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #000000; font-weight: bold;">use</span> CLASS<span style="color: #339933;">;</span><br />
<br />
CLASS<span style="color: #339933;">-&gt;</span><span style="color: #006600;">load_components</span><span style="color: #009900;">&#40;</span><span style="color: #009966; font-style: italic;">qw/EncodedColumn/</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
CLASS<span style="color: #339933;">-&gt;</span><span style="color: #006600;">table</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">'users'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
CLASS<span style="color: #339933;">-&gt;</span><span style="color: #006600;">add_columns</span><span style="color: #009900;">&#40;</span><br />
&nbsp; &nbsp;id <span style="color: #339933;">=&gt;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; data_type &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #339933;">=&gt;</span> <span style="color: #ff0000;">'integer'</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; is_numeric &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; is_nullable &nbsp; &nbsp; &nbsp; <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; is_auto_increment <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp;<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp;username <span style="color: #339933;">=&gt;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; data_type &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #339933;">=&gt;</span> <span style="color: #ff0000;">'varchar'</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; size &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">50</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; is_nullable &nbsp; &nbsp; &nbsp; <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp;<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp;password <span style="color: #339933;">=&gt;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; data_type &nbsp; &nbsp; <span style="color: #339933;">=&gt;</span> <span style="color: #ff0000;">'CHAR'</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; size &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">59</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; encode_column <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; encode_class &nbsp;<span style="color: #339933;">=&gt;</span> <span style="color: #ff0000;">'Crypt::Eksblowfish::Bcrypt'</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; encode_args &nbsp; <span style="color: #339933;">=&gt;</span> <span style="color: #009900;">&#123;</span> key_nul <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">0</span><span style="color: #339933;">,</span> cost <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">8</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; encode_check_method <span style="color: #339933;">=&gt;</span> <span style="color: #ff0000;">'check_password'</span><span style="color: #339933;">,</span><br />
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
CLASS<span style="color: #339933;">-&gt;</span><span style="color: #006600;">set_primary_key</span><span style="color: #009900;">&#40;</span><span style="color: #ff0000;">'id'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span></div></td></tr></tbody></table></div>
<p>Easy peasy!  The encode_check_method option for password basically puts a method in your result class that you can call with a plaintext password and it returns true or false if the password is legitimate.  The nice thing about that is that if you decide to switch to some other kind of hashing, your controller stays the same.  Model code for the win!</p>
<p>Next up, the Catalyst configuration.  This was what took me a while to find, but thanks to <a href="http://www.shadowcat.co.uk/blog/matt-s-trout/">mst</a> I finally found it yesterday.  The package we use for auth is the same one everyone uses in Cat: <a href="http://search.cpan.org/perldoc?Catalyst::Plugin::Authentication">Catalyst::Plugin::Authentication</a>.  The docs that I was looking for specifically were the ones for <a href="http://search.cpan.org/perldoc?Catalyst::Authentication::Credential::Password">Catalyst::Authentication::Credential::Password</a>.  So after reading those docs, the following is the catalyst config snippet one would use for these nice passwords:</p>
<div class="codecolorer-container perl vibrant" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br /></div></td><td><div class="perl codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp; &nbsp;<span style="color: #ff0000;">'Plugin::Authentication'</span> <span style="color: #339933;">=&gt;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; use_session <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; default <span style="color: #339933;">=&gt;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;credential <span style="color: #339933;">=&gt;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; class &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #339933;">=&gt;</span> <span style="color: #ff0000;">'Password'</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; password_type &nbsp; &nbsp; &nbsp;<span style="color: #339933;">=&gt;</span> <span style="color: #ff0000;">'self_check'</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;store <span style="color: #339933;">=&gt;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; class &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #339933;">=&gt;</span> <span style="color: #ff0000;">'DBIx::Class'</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; user_model &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #339933;">=&gt;</span> <span style="color: #ff0000;">'DB::User'</span><span style="color: #339933;">,</span> <span style="color: #666666; font-style: italic;">#&lt;-- DB refers to the name of the </span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; role_relation &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #339933;">=&gt;</span> <span style="color: #ff0000;">'roles'</span><span style="color: #339933;">,</span> &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #666666; font-style: italic;"># &nbsp; &nbsp; model class we are using</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; use_userdata_from_session <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp;<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span></div></td></tr></tbody></table></div>
<p>Note: the password_type of self_check is what tells the controller to just call $result->check_password($plaintext).</p>
<p>So there you have it.  That&#8217;s <strong>all the code</strong> you need for secure passwords with Catalyst.  If you make a new project and your users passwords get compromised it is <strong>your fault</strong>.</p>
<p>Have a nice day <img src='http://blog.afoolishmanifesto.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<div id="crp_related"><h2>Related Posts:</h2><ul><li><a href="http://blog.afoolishmanifesto.com/archives/1028" rel="bookmark" class="crp_title">PerlMonks Getting Hacked and My Solution</a></li><li><a href="http://blog.afoolishmanifesto.com/archives/913" rel="bookmark" class="crp_title">OpenID with Catalyst and more</a></li><li><a href="http://blog.afoolishmanifesto.com/archives/1289" rel="bookmark" class="crp_title">New stuff in DBIx::Class::Helpers 2.00200</a></li><li><a href="http://blog.afoolishmanifesto.com/archives/1261" rel="bookmark" class="crp_title">Latest additions to DBIC::Helpers</a></li><li><a href="http://blog.afoolishmanifesto.com/archives/274" rel="bookmark" class="crp_title">Paranoid Deletion in DBIx::Class</a></li><li>Powered by <a href="http://ajaydsouza.com/wordpress/plugins/contextual-related-posts/">Contextual Related Posts</a></li></ul></div><img src="http://feeds.feedburner.com/~r/AFoolishManifesto/~4/FdcDwbcx__I" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.afoolishmanifesto.com/archives/1286/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<feedburner:origLink>http://blog.afoolishmanifesto.com/archives/1286</feedburner:origLink></item>
		<item>
		<title>An Exposition on Specific Time Saving Code</title>
		<link>http://feedproxy.google.com/~r/AFoolishManifesto/~3/W0P6dXZpHXQ/1282</link>
		<comments>http://blog.afoolishmanifesto.com/archives/1282#comments</comments>
		<pubDate>Fri, 29 Jan 2010 08:19:18 +0000</pubDate>
		<dc:creator>fREW Schmidt</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[cpan]]></category>
		<category><![CDATA[DBIC]]></category>
		<category><![CDATA[dbix::class]]></category>
		<category><![CDATA[extjs]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[perl]]></category>

		<guid isPermaLink="false">http://blog.afoolishmanifesto.com/?p=1282</guid>
		<description><![CDATA[I write a lot of ExtJS grids at work.  I have written JavaScript classes for our Ext grids that generate as much as possible automatically, but the actual column definitions of the grids are almost always unique.  The project I am on now is nearing our first real deploy, and we&#8217;re late, so [...]]]></description>
			<content:encoded><![CDATA[<p>I write a lot of ExtJS grids at work.  I have written JavaScript classes for our Ext grids that generate as much as possible automatically, but the actual column definitions of the grids are almost always unique.  The project I am on now is nearing our first real deploy, and we&#8217;re late, so things have been really, really busy.  </p>
<p>It wasn&#8217;t until recently that I realized just how much time I spent working on grids and their related records (representation of the rows of a grid.)  Although even if I&#8217;d known just how much I do this at the beginning of the project, I certainly didn&#8217;t know <a href="http://search.cpan.org/perldoc?DBIx::Class">DBIx::Class</a> as much as I do now, in addition to the other 4 non-core modules that I&#8217;ll mention.</p>
<p>Because I&#8217;ve been working all these super long hours (12-14 a day), often after a frustrating day I&#8217;ll try to code something more relaxing and rewarding at home or at work but not during work.  So today I decided to finally take the plunge and do what I&#8217;ve been pondering for a few months and write some code to generate Ext scaffolding for me.  So I&#8217;m going to walk you through the script that I wrote (and will probably work on more as time goes by.)</p>
<p>This isn&#8217;t a full module, not even in my repo yet, so it&#8217;s all just in one file.  Here&#8217;s the boilerplate intro:</p>
<div class="codecolorer-container perl vibrant" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br /></div></td><td><div class="perl codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #666666; font-style: italic;">#!perl</span><br />
<br />
<span style="color: #000000; font-weight: bold;">use</span> strict<span style="color: #339933;">;</span><br />
<span style="color: #000000; font-weight: bold;">use</span> warnings<span style="color: #339933;">;</span><br />
<br />
<span style="color: #000000; font-weight: bold;">use</span> feature <span style="color: #ff0000;">':5.10'</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #000000; font-weight: bold;">use</span> Syntax<span style="color: #339933;">::</span><span style="color: #006600;">Keyword</span><span style="color: #339933;">::</span><span style="color: #006600;">Gather</span><span style="color: #339933;">;</span><br />
<span style="color: #000000; font-weight: bold;">use</span> String<span style="color: #339933;">::</span><span style="color: #006600;">CamelCase</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #000000; font-weight: bold;">use</span> Lingua<span style="color: #339933;">::</span><span style="color: #006600;">EN</span><span style="color: #339933;">::</span><span style="color: #006600;">Inflect</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #000000; font-weight: bold;">use</span> List<span style="color: #339933;">::</span><span style="color: #006600;">Util</span><span style="color: #339933;">;</span><br />
<span style="color: #000000; font-weight: bold;">use</span> Statistics<span style="color: #339933;">::</span><span style="color: #006600;">Basic</span> <span style="color: #ff0000;">'mean'</span><span style="color: #339933;">;</span></div></td></tr></tbody></table></div>
<p>That&#8217;s pretty basic.  We use a bunch of modules that I&#8217;ve used in at least 1 other project before and was happy with.</p>
<div class="codecolorer-container perl vibrant" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br /></div></td><td><div class="perl codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">use</span> FindBin<span style="color: #339933;">;</span><br />
<span style="color: #000000; font-weight: bold;">use</span> lib <span style="color: #ff0000;">&quot;$FindBin::Bin/../local/lib&quot;</span><span style="color: #339933;">,</span> <span style="color: #ff0000;">&quot;$FindBin::Bin/../lib&quot;</span><span style="color: #339933;">;</span><br />
<span style="color: #000000; font-weight: bold;">use</span> ACD<span style="color: #339933;">::</span><span style="color: #006600;">Schema</span><span style="color: #339933;">;</span><br />
<span style="color: #000000; font-weight: bold;">use</span> Config<span style="color: #339933;">::</span><span style="color: #006600;">JFDI</span><span style="color: #339933;">;</span><br />
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$config</span> <span style="color: #339933;">=</span> Config<span style="color: #339933;">::</span><span style="color: #006600;">JFDI</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">new</span><span style="color: #009900;">&#40;</span>name <span style="color: #339933;">=&gt;</span> <span style="color: #ff0000;">'acd'</span><span style="color: #339933;">,</span> path <span style="color: #339933;">=&gt;</span> <span style="color: #ff0000;">&quot;$FindBin::Bin/../acd&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$config_hash</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$config</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">get</span><span style="color: #339933;">;</span><br />
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$connect_info</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$config_hash</span><span style="color: #339933;">-&gt;</span><span style="color: #009900;">&#123;</span>Model<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#123;</span>DB<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#123;</span>connect_info<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span><br />
<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$schema</span> <span style="color: #339933;">=</span> ACD<span style="color: #339933;">::</span><span style="color: #006600;">Schema</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">connect</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$connect_info</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></td></tr></tbody></table></div>
<p>That&#8217;s the code to parse any kind of Catalyst config file and the grab a new schema based on it.  It&#8217;s a ton of biolerplate but I live with it.</p>
<p>So next up is a basic inflection function that gives us all the different forms of a word we might need.  It starts with either &#8220;single_foo&#8221; or &#8220;SingleBar&#8221; and gives us six variations based on that:</p>
<div class="codecolorer-container perl vibrant" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br />33<br /></div></td><td><div class="perl codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">sub</span> inflect <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp;<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$word</span> <span style="color: #339933;">=</span> <a href="http://perldoc.perl.org/functions/shift.html"><span style="color: #000066;">shift</span></a><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp;<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$return</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span> singular <span style="color: #339933;">=&gt;</span> <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span> plural <span style="color: #339933;">=&gt;</span> <span style="color: #009900;">&#123;</span><span style="color: #009900;">&#125;</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp;<span style="color: #b1b100;">if</span> <span style="color: #009900;">&#40;</span> <a href="http://perldoc.perl.org/functions/defined.html"><span style="color: #000066;">defined</span></a> <span style="color: #0000ff;">$word</span><span style="color: #339933;">-&gt;</span><span style="color: #009900;">&#123;</span>camel<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #0000ff;">$word</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$word</span><span style="color: #339933;">-&gt;</span><span style="color: #009900;">&#123;</span>camel<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #0000ff;">$return</span><span style="color: #339933;">-&gt;</span><span style="color: #009900;">&#123;</span>singular<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#123;</span>camel<span style="color: #009900;">&#125;</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$word</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #0000ff;">$return</span><span style="color: #339933;">-&gt;</span><span style="color: #009900;">&#123;</span>singular<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#123;</span>noncamel<span style="color: #009900;">&#125;</span> <span style="color: #339933;">=</span> String<span style="color: #339933;">::</span><span style="color: #006600;">CamelCase</span><span style="color: #339933;">::</span><span style="color: #006600;">decamelize</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$word</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp;<span style="color: #009900;">&#125;</span> <span style="color: #b1b100;">else</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #0000ff;">$word</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$word</span><span style="color: #339933;">-&gt;</span><span style="color: #009900;">&#123;</span>noncamel<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #0000ff;">$return</span><span style="color: #339933;">-&gt;</span><span style="color: #009900;">&#123;</span>singular<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#123;</span>camel<span style="color: #009900;">&#125;</span> <span style="color: #339933;">=</span> String<span style="color: #339933;">::</span><span style="color: #006600;">CamelCase</span><span style="color: #339933;">::</span><span style="color: #006600;">camelize</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$word</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #0000ff;">$return</span><span style="color: #339933;">-&gt;</span><span style="color: #009900;">&#123;</span>singular<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#123;</span>noncamel<span style="color: #009900;">&#125;</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$word</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp;<span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp;<span style="color: #0000ff;">$return</span><span style="color: #339933;">-&gt;</span><span style="color: #009900;">&#123;</span>singular<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#123;</span>human<span style="color: #009900;">&#125;</span> <span style="color: #339933;">=</span> <a href="http://perldoc.perl.org/functions/join.html"><span style="color: #000066;">join</span></a><span style="color: #009900;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; <a href="http://perldoc.perl.org/functions/q.html"><span style="color: #000066;">q</span></a><span style="color: #009900;">&#123;</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span> <a href="http://perldoc.perl.org/functions/map.html"><span style="color: #000066;">map</span></a> <a href="http://perldoc.perl.org/functions/ucfirst.html"><span style="color: #000066;">ucfirst</span></a> <span style="color: #0000ff;">$_</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; <a href="http://perldoc.perl.org/functions/split.html"><span style="color: #000066;">split</span></a> <span style="color: #009966; font-style: italic;">/_/</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">$return</span><span style="color: #339933;">-&gt;</span><span style="color: #009900;">&#123;</span>singular<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#123;</span>noncamel<span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp;<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp;<span style="color: #0000ff;">$return</span><span style="color: #339933;">-&gt;</span><span style="color: #009900;">&#123;</span>plural<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#123;</span>noncamel<span style="color: #009900;">&#125;</span> <span style="color: #339933;">=</span> <a href="http://perldoc.perl.org/functions/join.html"><span style="color: #000066;">join</span></a><span style="color: #009900;">&#40;</span> <a href="http://perldoc.perl.org/functions/q.html"><span style="color: #000066;">q</span></a><span style="color: #009900;">&#123;</span>_<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span> <a href="http://perldoc.perl.org/functions/split.html"><span style="color: #000066;">split</span></a> <span style="color: #009966; font-style: italic;">/ /</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; Lingua<span style="color: #339933;">::</span><span style="color: #006600;">EN</span><span style="color: #339933;">::</span><span style="color: #006600;">Inflect</span><span style="color: #339933;">::</span><span style="color: #006600;">PL</span><span style="color: #009900;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<a href="http://perldoc.perl.org/functions/join.html"><span style="color: #000066;">join</span></a> <a href="http://perldoc.perl.org/functions/q.html"><span style="color: #000066;">q</span></a><span style="color: #009900;">&#123;</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<a href="http://perldoc.perl.org/functions/split.html"><span style="color: #000066;">split</span></a> <span style="color: #009966; font-style: italic;">/_/</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #0000ff;">$return</span><span style="color: #339933;">-&gt;</span><span style="color: #009900;">&#123;</span>singular<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#123;</span>noncamel<span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#41;</span><br />
&nbsp; &nbsp;<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp;<span style="color: #0000ff;">$return</span><span style="color: #339933;">-&gt;</span><span style="color: #009900;">&#123;</span>plural<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#123;</span>camel<span style="color: #009900;">&#125;</span> <span style="color: #339933;">=</span> String<span style="color: #339933;">::</span><span style="color: #006600;">CamelCase</span><span style="color: #339933;">::</span><span style="color: #006600;">camelize</span><span style="color: #009900;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #0000ff;">$return</span><span style="color: #339933;">-&gt;</span><span style="color: #009900;">&#123;</span>plural<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#123;</span>noncamel<span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp;<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp;<span style="color: #0000ff;">$return</span><span style="color: #339933;">-&gt;</span><span style="color: #009900;">&#123;</span>plural<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#123;</span>human<span style="color: #009900;">&#125;</span> <span style="color: #339933;">=</span> <a href="http://perldoc.perl.org/functions/join.html"><span style="color: #000066;">join</span></a><span style="color: #009900;">&#40;</span> <a href="http://perldoc.perl.org/functions/q.html"><span style="color: #000066;">q</span></a><span style="color: #009900;">&#123;</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span> <a href="http://perldoc.perl.org/functions/map.html"><span style="color: #000066;">map</span></a> <a href="http://perldoc.perl.org/functions/ucfirst.html"><span style="color: #000066;">ucfirst</span></a> <span style="color: #0000ff;">$_</span><span style="color: #339933;">,</span> <a href="http://perldoc.perl.org/functions/split.html"><span style="color: #000066;">split</span></a> <span style="color: #009966; font-style: italic;">/_/</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #0000ff;">$return</span><span style="color: #339933;">-&gt;</span><span style="color: #009900;">&#123;</span>plural<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#123;</span>noncamel<span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp;<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp;<a href="http://perldoc.perl.org/functions/return.html"><span style="color: #000066;">return</span></a> <span style="color: #0000ff;">$return</span><br />
<span style="color: #009900;">&#125;</span></div></td></tr></tbody></table></div>
<p>So that uses <a href="http://search.cpan.org/perldoc?String::CamelCase">String::CamelCase</a> and <a href="http://search.cpan.org/perldoc?Lingua::EN::Inflect">Lingua::EN::Inflect</a> combined with join and split mostly.</p>
<p>We&#8217;re *almost* ready to generate a record.  But first we need to define a mapping from the data type in the database to the data type that Ext uses:</p>
<div class="codecolorer-container perl vibrant" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br /></div></td><td><div class="perl codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$types_xform</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp;<a href="http://perldoc.perl.org/functions/int.html"><span style="color: #000066;">int</span></a> <span style="color: #339933;">=&gt;</span> <span style="color: #ff0000;">'int'</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp;float <span style="color: #339933;">=&gt;</span> <span style="color: #ff0000;">'float'</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp;varchar <span style="color: #339933;">=&gt;</span> <span style="color: #ff0000;">'string'</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp;bit <span style="color: #339933;">=&gt;</span> <span style="color: #ff0000;">'boolean'</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp;datetime <span style="color: #339933;">=&gt;</span> <span style="color: #ff0000;">'date'</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp;money <span style="color: #339933;">=&gt;</span> <span style="color: #ff0000;">'float'</span><span style="color: #339933;">,</span><br />
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span></div></td></tr></tbody></table></div>
<p>Ok, now let&#8217;s look at the code to generate an Ext.record:</p>
<div class="codecolorer-container perl vibrant" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br /></div></td><td><div class="perl codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">sub</span> generate_record <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp;<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$schema</span> <span style="color: #339933;">=</span> <a href="http://perldoc.perl.org/functions/shift.html"><span style="color: #000066;">shift</span></a><span style="color: #339933;">;</span><br />
&nbsp; &nbsp;<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$source_name</span> <span style="color: #339933;">=</span> <a href="http://perldoc.perl.org/functions/shift.html"><span style="color: #000066;">shift</span></a><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp;<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$source</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$schema</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">source</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$source_name</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp;<a href="http://perldoc.perl.org/functions/return.html"><span style="color: #000066;">return</span></a> <a href="http://perldoc.perl.org/functions/qq.html"><span style="color: #000066;">qq</span></a><span style="color: #009900;">&#123;</span>Ext<span style="color: #339933;">.</span>ns<span style="color: #009900;">&#40;</span><span style="color: #ff0000;">'ACDRI.record'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
ACDRI<span style="color: #339933;">.</span>record<span style="color: #339933;">.</span><span style="color: #0000ff;">$source_name</span> <span style="color: #339933;">=</span> Ext<span style="color: #339933;">.</span>data<span style="color: #339933;">.</span>Record<span style="color: #339933;">.</span>create<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#91;</span><span style="color: #0000ff;">\n</span><span style="color: #009900;">&#125;</span> <span style="color: #339933;">.</span><br />
&nbsp; &nbsp;<a href="http://perldoc.perl.org/functions/join.html"><span style="color: #000066;">join</span></a><span style="color: #009900;">&#40;</span><a href="http://perldoc.perl.org/functions/qq.html"><span style="color: #000066;">qq</span></a><span style="color: #009900;">&#123;</span><span style="color: #339933;">,</span><span style="color: #0000ff;">\n</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span> <a href="http://perldoc.perl.org/functions/sort.html"><span style="color: #000066;">sort</span></a> <span style="color: #009900;">&#123;</span> <span style="color: #0000ff;">$a</span> <span style="color: #b1b100;">cmp</span> <span style="color: #0000ff;">$b</span> <span style="color: #009900;">&#125;</span> gather <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">for</span> <span style="color: #009900;">&#40;</span><a href="http://perldoc.perl.org/functions/map.html"><span style="color: #000066;">map</span></a> <span style="color: #009900;">&#91;</span><span style="color: #0000ff;">$_</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">$source</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">column_info</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$_</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">$source</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">columns</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #b1b100;">my</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$column</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">$info</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">=</span> <span style="color: #339933;">@</span><span style="color: #009900;">&#123;</span><span style="color: #0000ff;">$_</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;take <span style="color: #ff0000;">&quot; &nbsp; {name: '$column', type: '$types_xform-&gt;{$info-&gt;{data_type}}'}&quot;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp;<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">.</span> &nbsp;<span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>]);&quot;</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #009900;">&#125;</span></div></td></tr></tbody></table></div>
<p>So what&#8217;s going on here is that we get the <a href="http://search.cpan.org/perldoc?DBIx::Class::ResultSource">source</a> from the <a href="http://search.cpan.org/perldoc?DBIx::Class::Schema">schema</a>.  The source could be considered something like a table definition, although it can also point at a view or whatever too.  Then we start generating the string representing our record, and then we use a join/<a href="http://search.cpan.org/perldoc?Syntax::Keyword::Gather">gather</a> combo to get the column data the way we want it. </p>
<p>We could certainly just use a more complex map instead of the for+gather that we have, but I personally feel than any map where you *must* use the block form is cumbersome.  So we join together all of the strings that gather took, and then append the end of the definition, and voilà, we have a record!</p>
<p>Here&#8217;s example output on our Customer source:</p>
<div class="codecolorer-container javascript vibrant" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br /></div></td><td><div class="javascript codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">Ext.<span style="color: #660066;">ns</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'ACDRI.record'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
ACDRI.<span style="color: #660066;">record</span>.<span style="color: #660066;">Customer</span> <span style="color: #339933;">=</span> Ext.<span style="color: #660066;">data</span>.<span style="color: #660066;">Record</span>.<span style="color: #660066;">create</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#91;</span><br />
&nbsp; &nbsp;<span style="color: #009900;">&#123;</span><span style="color: #000066;">name</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">'color_code'</span><span style="color: #339933;">,</span> type<span style="color: #339933;">:</span> <span style="color: #3366CC;">'string'</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp;<span style="color: #009900;">&#123;</span><span style="color: #000066;">name</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">'comments'</span><span style="color: #339933;">,</span> type<span style="color: #339933;">:</span> <span style="color: #3366CC;">'string'</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp;<span style="color: #009900;">&#123;</span><span style="color: #000066;">name</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">'id'</span><span style="color: #339933;">,</span> type<span style="color: #339933;">:</span> <span style="color: #3366CC;">'string'</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp;<span style="color: #009900;">&#123;</span><span style="color: #000066;">name</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">'last_edited_date'</span><span style="color: #339933;">,</span> type<span style="color: #339933;">:</span> <span style="color: #3366CC;">'date'</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp;<span style="color: #009900;">&#123;</span><span style="color: #000066;">name</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">'name'</span><span style="color: #339933;">,</span> type<span style="color: #339933;">:</span> <span style="color: #3366CC;">'string'</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp;<span style="color: #009900;">&#123;</span><span style="color: #000066;">name</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">'price_approval_required'</span><span style="color: #339933;">,</span> type<span style="color: #339933;">:</span> <span style="color: #3366CC;">'boolean'</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp;<span style="color: #009900;">&#123;</span><span style="color: #000066;">name</span><span style="color: #339933;">:</span> <span style="color: #3366CC;">'sales_representative_id'</span><span style="color: #339933;">,</span> type<span style="color: #339933;">:</span> <span style="color: #3366CC;">'int'</span><span style="color: #009900;">&#125;</span><br />
<span style="color: #009900;">&#93;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></td></tr></tbody></table></div>
<p>If you&#8217;re still following along you should be fine with the next, much more impressive functionality.</p>
<p>I&#8217;d like to have the script do as much as possible to speed up my work, so let&#8217;s see how far we can take this.  First, I made a mapping from type to renderer, so that things that are datetimes use our custom datetime renderer, same with booleans:</p>
<div class="codecolorer-container perl vibrant" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br /></div></td><td><div class="perl codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$renderer_from_type</span> <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp;datetime <span style="color: #339933;">=&gt;</span> <span style="color: #ff0000;">'ACDRI.fn.Renderers.dateTime'</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp;bit <span style="color: #339933;">=&gt;</span> <span style="color: #ff0000;">'ACDRI.fn.Renderers.bool'</span><span style="color: #339933;">,</span><br />
<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span></div></td></tr></tbody></table></div>
<p>Next, I wrote a function that would try it&#8217;s best to guess how wide a column should be based on it&#8217;s header and the average width of the strings inside of it:</p>
<div class="codecolorer-container perl vibrant" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br /></div></td><td><div class="perl codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">sub</span> avg_width <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp;<span style="color: #b1b100;">my</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$rs</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">$col</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">$header</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">@_</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp;List<span style="color: #339933;">::</span><span style="color: #006600;">Util</span><span style="color: #339933;">::</span><span style="color: #006600;">max</span> <span style="color: #009900;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; mean<span style="color: #009900;">&#40;</span><a href="http://perldoc.perl.org/functions/map.html"><span style="color: #000066;">map</span></a> <span style="color: #339933;">+</span><span style="color: #009900;">&#40;</span> <a href="http://perldoc.perl.org/functions/defined.html"><span style="color: #000066;">defined</span></a><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$_</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">?</span> <a href="http://perldoc.perl.org/functions/length.html"><span style="color: #000066;">length</span></a> <span style="color: #ff0000;">&quot;$_&quot;</span> <span style="color: #339933;">:</span> 0 <span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">$rs</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">get_column</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$col</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">all</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> <span style="color: #666666; font-style: italic;"># average width of field</span><br />
&nbsp; &nbsp; &nbsp; <a href="http://perldoc.perl.org/functions/length.html"><span style="color: #000066;">length</span></a> <span style="color: #0000ff;">$header</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #666666; font-style: italic;"># col header</span><br />
&nbsp; &nbsp;<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span></div></td></tr></tbody></table></div>
<p>Now finally we have the grid function:</p>
<div class="codecolorer-container perl vibrant" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br />33<br />34<br />35<br />36<br />37<br />38<br />39<br />40<br />41<br />42<br />43<br />44<br />45<br />46<br />47<br />48<br />49<br />50<br />51<br />52<br />53<br />54<br />55<br />56<br />57<br />58<br />59<br />60<br />61<br />62<br />63<br />64<br />65<br />66<br />67<br />68<br />69<br />70<br />71<br />72<br />73<br />74<br />75<br />76<br />77<br /></div></td><td><div class="perl codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #000000; font-weight: bold;">sub</span> generate_grid <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp;<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$schema</span> <span style="color: #339933;">=</span> <a href="http://perldoc.perl.org/functions/shift.html"><span style="color: #000066;">shift</span></a><span style="color: #339933;">;</span><br />
&nbsp; &nbsp;<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$source_name</span> <span style="color: #339933;">=</span> <a href="http://perldoc.perl.org/functions/shift.html"><span style="color: #000066;">shift</span></a><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp;<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$source_names</span> <span style="color: #339933;">=</span> inflect<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span> camel <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">$source_name</span> <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp;<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$source</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$schema</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">source</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$source_name</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp;<a href="http://perldoc.perl.org/functions/return.html"><span style="color: #000066;">return</span></a> <a href="http://perldoc.perl.org/functions/qq.html"><span style="color: #000066;">qq</span></a><span style="color: #ff0000;">`/*global Ext */<br />
/*global ACDRI */<br />
/*global MTSI */<br />
Ext.ns('ACDRI.ui.grid');<br />
<br />
/**<br />
&nbsp;* <span style="color: #000099; font-weight: bold;">\@</span>class ACDRI.ui.grid.$source_names-&gt;{plural}{camel}<br />
&nbsp;* <span style="color: #000099; font-weight: bold;">\@</span>extends MTSI.ui.Grid<br />
&nbsp;*/<br />
ACDRI.ui.grid.$source_names-&gt;{plural}{camel} = Ext.extend(MTSI.ui.Grid, {<br />
&nbsp; &nbsp;title: '$source_names-&gt;{plural}{human}',<br />
&nbsp; &nbsp;record: ACDRI.record.$source_names-&gt;{singular}{camel},<br />
&nbsp; &nbsp;updateConfig: {<br />
&nbsp; &nbsp; &nbsp; xtype: 'ACDRI.ui.form.$source_names-&gt;{singular}{camel}'<br />
&nbsp; &nbsp;},<br />
&nbsp; &nbsp;addConfig: {<br />
&nbsp; &nbsp; &nbsp; xtype: 'ACDRI.ui.form.$source_names-&gt;{singular}{camel}',<br />
&nbsp; &nbsp;},<br />
&nbsp; &nbsp;initComponent: function () {<br />
&nbsp; &nbsp; &nbsp; //this.sortInfo = {<br />
&nbsp; &nbsp; &nbsp; // &nbsp; field: 'part_id',<br />
&nbsp; &nbsp; &nbsp; // &nbsp; direction: 'asc'<br />
&nbsp; &nbsp; &nbsp; //};<br />
&nbsp; &nbsp; &nbsp; var config = {<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;url: '$source_names-&gt;{plural}{noncamel}',<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;itemName: '$source_names-&gt;{singular}{human}',<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;columns: [`</span> <span style="color: #339933;">.</span><br />
&nbsp; &nbsp;<a href="http://perldoc.perl.org/functions/join.html"><span style="color: #000066;">join</span></a> <span style="color: #009900;">&#40;</span><a href="http://perldoc.perl.org/functions/qq.html"><span style="color: #000066;">qq</span></a><span style="color: #009900;">&#123;</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span> gather <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #b1b100;">for</span> <span style="color: #009900;">&#40;</span><a href="http://perldoc.perl.org/functions/map.html"><span style="color: #000066;">map</span></a> <span style="color: #009900;">&#91;</span><span style="color: #0000ff;">$_</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">$source</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">column_info</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$_</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">$source</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">columns</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #b1b100;">my</span> <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$column</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">$info</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">=</span> <span style="color: #339933;">@</span><span style="color: #009900;">&#123;</span><span style="color: #0000ff;">$_</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$colnames</span> <span style="color: #339933;">=</span> inflect<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span> noncamel <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">$column</span> <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$renderer</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$renderer_from_type</span><span style="color: #339933;">-&gt;</span><span style="color: #009900;">&#123;</span><span style="color: #0000ff;">$info</span><span style="color: #339933;">-&gt;</span><span style="color: #009900;">&#123;</span>data_type<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #339933;">?</span> <span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\n</span> &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;renderer: $renderer_from_type-&gt;{$info-&gt;{data_type}},&quot;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #339933;">:</span> <span style="color: #ff0000;">''</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$width</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;given <span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$info</span><span style="color: #339933;">-&gt;</span><span style="color: #009900;">&#123;</span>data_type<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; when <span style="color: #009900;">&#40;</span><span style="color: #ff0000;">'varchar'</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #0000ff;">$width</span> <span style="color: #339933;">=</span> <a href="http://perldoc.perl.org/functions/int.html"><span style="color: #000066;">int</span></a> <span style="color: #cc66cc;">7</span><span style="color: #0000ff;">*avg_width</span><span style="color: #009900;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #0000ff;">$source</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">resultset</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">$column</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">$colnames</span><span style="color: #339933;">-&gt;</span><span style="color: #009900;">&#123;</span>singular<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#123;</span>human<span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; when <span style="color: #009900;">&#40;</span><span style="color: #ff0000;">'datetime'</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #0000ff;">$width</span> <span style="color: #339933;">=</span> List<span style="color: #339933;">::</span><span style="color: #006600;">Util</span><span style="color: #339933;">::</span><span style="color: #006600;">max</span><span style="color: #009900;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <a href="http://perldoc.perl.org/functions/int.html"><span style="color: #000066;">int</span></a> 7 <span style="color: #339933;">*</span> <a href="http://perldoc.perl.org/functions/length.html"><span style="color: #000066;">length</span></a> <span style="color: #0000ff;">$colnames</span><span style="color: #339933;">-&gt;</span><span style="color: #009900;">&#123;</span>singular<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#123;</span>human<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 57<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; default <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #0000ff;">$width</span> <span style="color: #339933;">=</span> <a href="http://perldoc.perl.org/functions/int.html"><span style="color: #000066;">int</span></a> 7 <span style="color: #339933;">*</span> <a href="http://perldoc.perl.org/functions/length.html"><span style="color: #000066;">length</span></a> <span style="color: #0000ff;">$colnames</span><span style="color: #339933;">-&gt;</span><span style="color: #009900;">&#123;</span>singular<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#123;</span>human<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;take <a href="http://perldoc.perl.org/functions/qq.html"><span style="color: #000066;">qq</span></a><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; header<span style="color: #339933;">:</span> <span style="color: #ff0000;">'$colnames-&gt;{singular}{human}'</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dataIndex<span style="color: #339933;">:</span> <span style="color: #ff0000;">'$column'</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sortable<span style="color: #339933;">:</span> true<span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; hidden<span style="color: #339933;">:</span> false<span style="color: #339933;">,</span><span style="color: #0000ff;">$renderer</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; width<span style="color: #339933;">:</span> <span style="color: #0000ff;">$width</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#93;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp;<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">.</span> &nbsp;<a href="http://perldoc.perl.org/functions/qq.html"><span style="color: #000066;">qq</span></a><span style="color: #ff0000;">`]<br />
&nbsp; &nbsp; &nbsp; };<br />
<br />
&nbsp; &nbsp; &nbsp; Ext.apply(this, Ext.apply(this.initialConfig, config));<br />
&nbsp; &nbsp; &nbsp; ACDRI.ui.grid.$source_names-&gt;{plural}{camel}.superclass.initComponent.apply(this, arguments);<br />
&nbsp; &nbsp;}<br />
});<br />
<br />
Ext.reg('ACDRI.ui.grid.$source_names-&gt;{plural}{camel}', ACDRI.ui.grid.$source_names-&gt;{plural}{camel});<br />
`</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span></div></td></tr></tbody></table></div>
<p>We see nearly the same structure here that we did with the record, except much more intricate.   Notice the code to generate the width uses the magic constant 7.  As I played with this I found that 7 seemed to work for the font that Ext uses by default (Arial?)  Optimally I would actually use some kind of metrics package to ask it for the width of all of the strings that I generated in the function above and average that, instead of averaging character lengths.  But this seems to work really, really well, so the ROI is pretty good.</p>
<p>Also note the code to pick and insert the renderer.  It&#8217;s not complex or anything, but it yields very convenient results.   Here&#8217;s the output of running this one on the same source we used for the record:</p>
<div class="codecolorer-container javascript vibrant" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br />32<br />33<br />34<br />35<br />36<br />37<br />38<br />39<br />40<br />41<br />42<br />43<br />44<br />45<br />46<br />47<br />48<br />49<br />50<br />51<br />52<br />53<br />54<br />55<br />56<br />57<br />58<br />59<br />60<br />61<br />62<br />63<br />64<br />65<br />66<br />67<br />68<br />69<br />70<br />71<br />72<br />73<br />74<br />75<br />76<br />77<br />78<br />79<br /></div></td><td><div class="javascript codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #006600; font-style: italic;">/*global Ext */</span><br />
<span style="color: #009966; font-style: italic;">/*global ACDRI */</span><br />
<span style="color: #009966; font-style: italic;">/*global MTSI */</span><br />
Ext.<span style="color: #660066;">ns</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'ACDRI.ui.grid'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #006600; font-style: italic;">/**<br />
&nbsp;* @class ACDRI.ui.grid.Customers<br />
&nbsp;* @extends MTSI.ui.Grid<br />
&nbsp;*/</span><br />
ACDRI.<span style="color: #660066;">ui</span>.<span style="color: #660066;">grid</span>.<span style="color: #660066;">Customers</span> <span style="color: #339933;">=</span> Ext.<span style="color: #660066;">extend</span><span style="color: #009900;">&#40;</span>MTSI.<span style="color: #660066;">ui</span>.<span style="color: #660066;">Grid</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp;title<span style="color: #339933;">:</span> <span style="color: #3366CC;">'Customers'</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp;record<span style="color: #339933;">:</span> ACDRI.<span style="color: #660066;">record</span>.<span style="color: #660066;">Customer</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp;updateConfig<span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; xtype<span style="color: #339933;">:</span> <span style="color: #3366CC;">'ACDRI.ui.form.Customer'</span><br />
&nbsp; &nbsp;<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp;addConfig<span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; xtype<span style="color: #339933;">:</span> <span style="color: #3366CC;">'ACDRI.ui.form.Customer'</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp;<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp;initComponent<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">function</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #006600; font-style: italic;">//this.sortInfo = {</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #006600; font-style: italic;">// &nbsp; field: 'part_id',</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #006600; font-style: italic;">// &nbsp; direction: 'asc'</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #006600; font-style: italic;">//};</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #003366; font-weight: bold;">var</span> config <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;url<span style="color: #339933;">:</span> <span style="color: #3366CC;">'customers'</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;itemName<span style="color: #339933;">:</span> <span style="color: #3366CC;">'Customer'</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;columns<span style="color: #339933;">:</span> <span style="color: #009900;">&#91;</span><span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; header<span style="color: #339933;">:</span> <span style="color: #3366CC;">'Comments'</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dataIndex<span style="color: #339933;">:</span> <span style="color: #3366CC;">'comments'</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sortable<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; hidden<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; width<span style="color: #339933;">:</span> <span style="color: #CC0000;">226</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; header<span style="color: #339933;">:</span> <span style="color: #3366CC;">'Color Code'</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dataIndex<span style="color: #339933;">:</span> <span style="color: #3366CC;">'color_code'</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sortable<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; hidden<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; width<span style="color: #339933;">:</span> <span style="color: #CC0000;">70</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; header<span style="color: #339933;">:</span> <span style="color: #3366CC;">'Id'</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dataIndex<span style="color: #339933;">:</span> <span style="color: #3366CC;">'id'</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sortable<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; hidden<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; width<span style="color: #339933;">:</span> <span style="color: #CC0000;">35</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; header<span style="color: #339933;">:</span> <span style="color: #3366CC;">'Last Edited Date'</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dataIndex<span style="color: #339933;">:</span> <span style="color: #3366CC;">'last_edited_date'</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sortable<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; hidden<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; renderer<span style="color: #339933;">:</span> ACDRI.<span style="color: #660066;">fn</span>.<span style="color: #660066;">Renderers</span>.<span style="color: #660066;">dateTime</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; width<span style="color: #339933;">:</span> <span style="color: #CC0000;">112</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; header<span style="color: #339933;">:</span> <span style="color: #3366CC;">'Name'</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dataIndex<span style="color: #339933;">:</span> <span style="color: #3366CC;">'name'</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sortable<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; hidden<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; width<span style="color: #339933;">:</span> <span style="color: #CC0000;">136</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; header<span style="color: #339933;">:</span> <span style="color: #3366CC;">'Price Approval Required'</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dataIndex<span style="color: #339933;">:</span> <span style="color: #3366CC;">'price_approval_required'</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sortable<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; hidden<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; renderer<span style="color: #339933;">:</span> ACDRI.<span style="color: #660066;">fn</span>.<span style="color: #660066;">Renderers</span>.<span style="color: #660066;">bool</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; width<span style="color: #339933;">:</span> <span style="color: #CC0000;">161</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #009900;">&#125;</span><span style="color: #339933;">,</span> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; header<span style="color: #339933;">:</span> <span style="color: #3366CC;">'Sales Representative Id'</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; dataIndex<span style="color: #339933;">:</span> <span style="color: #3366CC;">'sales_representative_id'</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; sortable<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">true</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; hidden<span style="color: #339933;">:</span> <span style="color: #003366; font-weight: bold;">false</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; width<span style="color: #339933;">:</span> 161<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#93;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp; &nbsp; Ext.<span style="color: #660066;">apply</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #339933;">,</span> Ext.<span style="color: #660066;">apply</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span>.<span style="color: #660066;">initialConfig</span><span style="color: #339933;">,</span> config<span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp; &nbsp; ACDRI.<span style="color: #660066;">ui</span>.<span style="color: #660066;">grid</span>.<span style="color: #660066;">Customers</span>.<span style="color: #660066;">superclass</span>.<span style="color: #660066;">initComponent</span>.<span style="color: #660066;">apply</span><span style="color: #009900;">&#40;</span><span style="color: #000066; font-weight: bold;">this</span><span style="color: #339933;">,</span> arguments<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp;<span style="color: #009900;">&#125;</span><br />
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
Ext.<span style="color: #660066;">reg</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'ACDRI.ui.grid.Customers'</span><span style="color: #339933;">,</span> ACDRI.<span style="color: #660066;">ui</span>.<span style="color: #660066;">grid</span>.<span style="color: #660066;">Customers</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></td></tr></tbody></table></div>
<p>Note that there are probably some things that we could do a little better.  For instance, we should probably check for text fields and not include them in the grid.  We could also be clever and look for anything ending with _id and have it hidden by default.  But in general, the above is very nice results.  At the very least you are probably going to need to reorder the columns (although you could give some kind of grid_order_id to the column definition in the Schema::Result code, but I don&#8217;t think that&#8217;s worth it.)</p>
<p>So I hope someone else enjoyed reading this as much as I did writing it.  After I&#8217;ve exhausted all of the little Ext things I can use this for (form, etc) I will probably look into messing with <a href="http://search.cpan.org/perldoc?DBICx::AutoDoc">DBICx::AutoDoc</a> to add in Dia outputs.</p>
<div id="crp_related"><h2>Related Posts:</h2><ul><li><a href="http://blog.afoolishmanifesto.com/archives/304" rel="bookmark" class="crp_title">Javascript scope</a></li><li><a href="http://blog.afoolishmanifesto.com/archives/521" rel="bookmark" class="crp_title">Ext Conference, Day 1</a></li><li><a href="http://blog.afoolishmanifesto.com/archives/502" rel="bookmark" class="crp_title">Introducing SillyString: fix the past!</a></li><li><a href="http://blog.afoolishmanifesto.com/archives/94" rel="bookmark" class="crp_title">Javascript with Prototype: Hexstring to boolean array</a></li><li><a href="http://blog.afoolishmanifesto.com/archives/986" rel="bookmark" class="crp_title">REST REST REST REST REST</a></li><li>Powered by <a href="http://ajaydsouza.com/wordpress/plugins/contextual-related-posts/">Contextual Related Posts</a></li></ul></div><img src="http://feeds.feedburner.com/~r/AFoolishManifesto/~4/W0P6dXZpHXQ" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.afoolishmanifesto.com/archives/1282/feed</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://blog.afoolishmanifesto.com/archives/1282</feedburner:origLink></item>
		<item>
		<title>Template.Tiny</title>
		<link>http://feedproxy.google.com/~r/AFoolishManifesto/~3/phRTNDLamic/1277</link>
		<comments>http://blog.afoolishmanifesto.com/archives/1277#comments</comments>
		<pubDate>Tue, 26 Jan 2010 06:53:34 +0000</pubDate>
		<dc:creator>fREW Schmidt</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[cpan]]></category>
		<category><![CDATA[extjs]]></category>
		<category><![CDATA[javascript]]></category>
		<category><![CDATA[Template-Toolkit]]></category>
		<category><![CDATA[Template.Tiny]]></category>
		<category><![CDATA[Template::Tiny]]></category>

		<guid isPermaLink="false">http://blog.afoolishmanifesto.com/?p=1277</guid>
		<description><![CDATA[(Sorry if you heard this already   )
At $work we do as much &#8220;view&#8221; type code as we can in JavaScript with the ExtJS framework.  I have personally found it to be a great framework to work with, although often it is lacking in the non-UI department.  One thing that at first [...]]]></description>
			<content:encoded><![CDATA[<p>(Sorry if you <a href="http://use.perl.org/~Alias/journal/40126?from=rss">heard this already</a> <img src='http://blog.afoolishmanifesto.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' />  )</p>
<p>At $work we do as much &#8220;view&#8221; type code as we can in JavaScript with the ExtJS framework.  I have personally found it to be a great framework to work with, although often it is lacking in the non-UI department.  One thing that at first I really liked about Ext was their <a href="http://www.extjs.com/deploy/dev/docs/?class=Ext.Template">Template</a> and <a href="http://www.extjs.com/deploy/dev/docs/?class=Ext.XTemplate">XTemplate</a> classes.  But as time went on I got more and more annoyed with those modules.</p>
<p>I&#8217;ve always thought that <a href="http://search.cpan.org/perldoc?Template">Template-Toolkit</a> was a really nice templating library to work with.  I hate templating html because of all the weird little gotchas having to do with CSS and whatnot, but doing almost all that kind of work in JavaScript I have started missing Template-Toolkit.  At some point I heard about <a href="http://search.cpan.org/perldoc?Template::Tiny">Template::Tiny</a> and this past Saturday I thought, &#8220;that&#8217;s like, 160 LOC&#8230;I could probably port that to javascript!&#8221;</p>
<p>So I did!  It&#8217;s not really done yet, but the current code is <a href="http://github.com/frioux/Template-Tiny-js/blob/master/lib/Template.Tiny.js">at github</a>.  I need to finish porting the test suite from Perl 5 to JavaScript so that I can ensure correctness (I am certain I screwed up some stuff.)</p>
<p>Alias mentioned in his post that I use XRegExp (600 LOC) to help out with the Regular Expression support in JavaScript for this module.  I actually wasn&#8217;t going to, since the only thing I needed it for was the /x flag, or to be more clear telling the parser to ignore whitespace, but I want to keep Template.Tiny in sync with the Perl version, and I really don&#8217;t want to strip out all the whitespace by hand.  If someone takes issue with the dep they can fork away <img src='http://blog.afoolishmanifesto.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<p>So once it is fully ported I fully intend to use it entirely from now on instead of the Ext templating.  But take note, Ext templates and Template.Tinies (what?) really solve different problems and have different goals.  The following is a list of Pros and Cons of each:</p>
<h3>Ext.(X)Template</h3>
<p>Pros:</p>
<ul>
<li>Can be compiled to JavaScript, for speed</li>
<li>Allows complex expressions in &#8220;if&#8221; blocks (see Example 1)</li>
<li>Interesting &#8220;topicalizing&#8221; feature (Example 2)</li>
<li>Crashes when you leave out a variable (no mystery as to why a field is blank) (Example 3)</li>
<li>Can execute arbitrary JavaScript code in a template for complex stuff  (Example 4)</li>
<li>Neat automatic &#8220;current item&#8221; style variables when you are iterating over an array (Example 5)</li>
<li>Basic Math Support</li>
<li>Ability to call functions associated with Template object</li>
<li>Very cool builtin Renderer support (Example 6)</li>
</ul>
<p>Cons:</p>
<ul>
<li>No else if.  If you want something like that you must do if !expr.  Lame.</li>
<li>Crashes when you leave out a variable (mostly that&#8217;s just annoying)</li>
<li>This is almost entirely subjective, but having xml as a templating thing is kinda gross.</li>
<li>Not really open source, so I can&#8217;t use it in personal projects and have people use my code in a corporate setting</li>
</ul>
<p>Example 1:</p>
<div class="codecolorer-container javascript vibrant" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br /></div></td><td><div class="javascript codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #003366; font-weight: bold;">var</span> data <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span> age<span style="color: #339933;">:</span> 21 <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #006600; font-style: italic;">// XTPL</span><br />
<span style="color: #003366; font-weight: bold;">var</span> tpl <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> Ext.<span style="color: #660066;">XTemplate</span><span style="color: #009900;">&#40;</span> <span style="color: #3366CC;">&quot;&lt;tpl if='age &gt; 18'&gt;Can Vote!&lt;/tpl&gt;&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #003366; font-weight: bold;">var</span> str <span style="color: #339933;">=</span> tpl.<span style="color: #660066;">apply</span><span style="color: #009900;">&#40;</span>data<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #006600; font-style: italic;">// TT</span><br />
<span style="color: #003366; font-weight: bold;">var</span> tmp <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> Template.<span style="color: #660066;">Tiny</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #003366; font-weight: bold;">var</span> str <span style="color: #339933;">=</span> tmp.<span style="color: #660066;">process</span><span style="color: #009900;">&#40;</span><br />
&nbsp; &nbsp;<span style="color: #3366CC;">&quot;[% IF old_enough %]Can Vote![% END %]&quot;</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp;<span style="color: #009900;">&#123;</span> old_enough<span style="color: #339933;">:</span> <span style="color: #009900;">&#40;</span>age <span style="color: #339933;">&gt;</span> 18 <span style="color: #009900;">&#41;</span><span style="color: #009900;">&#125;</span><br />
<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></td></tr></tbody></table></div>
<p>Example 2:</p>
<div class="codecolorer-container javascript vibrant" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br /></div></td><td><div class="javascript codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #003366; font-weight: bold;">var</span> data <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span> person<span style="color: #339933;">:</span> <span style="color: #009900;">&#123;</span>first_name<span style="color: #339933;">:</span> <span style="color: #3366CC;">'fREW'</span><span style="color: #339933;">,</span> last_name<span style="color: #339933;">:</span> <span style="color: #3366CC;">'Schmidt'</span><span style="color: #339933;">,</span> title<span style="color: #339933;">:</span> <span style="color: #3366CC;">'Mr.'</span> <span style="color: #009900;">&#125;</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span><br />
<span style="color: #006600; font-style: italic;">// XTPL</span><br />
<span style="color: #003366; font-weight: bold;">var</span> id <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> Ext.<span style="color: #660066;">XTemplate</span><span style="color: #009900;">&#40;</span> <span style="color: #3366CC;">&quot;&lt;tpl for='person'&gt;{title} {first_name} {last_name}&lt;/tpl&gt;&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #003366; font-weight: bold;">var</span> str <span style="color: #339933;">=</span> tpl.<span style="color: #660066;">apply</span><span style="color: #009900;">&#40;</span>data<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #006600; font-style: italic;">// TT</span><br />
<span style="color: #003366; font-weight: bold;">var</span> tmp <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> Template.<span style="color: #660066;">Tiny</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #003366; font-weight: bold;">var</span> str <span style="color: #339933;">=</span> tmp.<span style="color: #660066;">process</span><span style="color: #009900;">&#40;</span><br />
&nbsp; &nbsp;<span style="color: #3366CC;">&quot;[% person.title %] [% person.first_name %] [% person.last_name %]&quot;</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp;data<br />
<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></td></tr></tbody></table></div>
<p>Example 3:</p>
<div class="codecolorer-container javascript vibrant" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br /></div></td><td><div class="javascript codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #003366; font-weight: bold;">var</span> data <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span> werld<span style="color: #339933;">:</span> <span style="color: #3366CC;">'fail'</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #006600; font-style: italic;">// XTPL</span><br />
<span style="color: #003366; font-weight: bold;">var</span> tpl <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> Ext.<span style="color: #660066;">XTemplate</span><span style="color: #009900;">&#40;</span> <span style="color: #3366CC;">&quot;Hello {world}&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #003366; font-weight: bold;">var</span> str <span style="color: #339933;">=</span> tpl.<span style="color: #660066;">apply</span><span style="color: #009900;">&#40;</span>data<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// error message</span><br />
<br />
<span style="color: #006600; font-style: italic;">// TT</span><br />
<span style="color: #003366; font-weight: bold;">var</span> tmp <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> Template.<span style="color: #660066;">Tiny</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #003366; font-weight: bold;">var</span> str <span style="color: #339933;">=</span> tmp.<span style="color: #660066;">process</span><span style="color: #009900;">&#40;</span><br />
&nbsp; &nbsp;<span style="color: #3366CC;">&quot;Hello [% world %]&quot;</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp;data<br />
<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// silent failure</span></div></td></tr></tbody></table></div>
<p>Example 4:</p>
<div class="codecolorer-container javascript vibrant" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br /></div></td><td><div class="javascript codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #003366; font-weight: bold;">var</span> data <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span> foo<span style="color: #339933;">:</span> 1 <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #006600; font-style: italic;">// XTPL</span><br />
<span style="color: #003366; font-weight: bold;">var</span> id <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> Ext.<span style="color: #660066;">XTemplate</span><span style="color: #009900;">&#40;</span> <span style="color: #3366CC;">&quot;{[someComplexRenderer(values.foo)]&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #003366; font-weight: bold;">var</span> str <span style="color: #339933;">=</span> tpl.<span style="color: #660066;">apply</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#123;</span> foo<span style="color: #339933;">:</span> 1<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #006600; font-style: italic;">// TT</span><br />
<span style="color: #003366; font-weight: bold;">var</span> tmp <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> Template.<span style="color: #660066;">Tiny</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #003366; font-weight: bold;">var</span> str <span style="color: #339933;">=</span> tmp.<span style="color: #660066;">process</span><span style="color: #009900;">&#40;</span><br />
&nbsp; &nbsp;<span style="color: #3366CC;">&quot;[% foo %]&quot;</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp;<span style="color: #009900;">&#123;</span> foo<span style="color: #339933;">:</span> someComplexRenderer<span style="color: #009900;">&#40;</span>data.<span style="color: #660066;">foo</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#125;</span><br />
<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></td></tr></tbody></table></div>
<p>Example 5:</p>
<div class="codecolorer-container javascript vibrant" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br /></div></td><td><div class="javascript codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #003366; font-weight: bold;">var</span> data <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span> arr<span style="color: #339933;">:</span> <span style="color: #009900;">&#91;</span><span style="color: #3366CC;">'foo'</span><span style="color: #339933;">,</span><span style="color: #3366CC;">'bar'</span><span style="color: #339933;">,</span><span style="color: #3366CC;">'baz'</span><span style="color: #009900;">&#93;</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #006600; font-style: italic;">// XTPL</span><br />
<span style="color: #003366; font-weight: bold;">var</span> tpl <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> Ext.<span style="color: #660066;">XTemplate</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'&lt;tpl for=&quot;arr&quot;&gt;({#}. {.})&lt;/tpl&gt;'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #003366; font-weight: bold;">var</span> str <span style="color: #339933;">=</span> tpl.<span style="color: #660066;">apply</span><span style="color: #009900;">&#40;</span>data<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// &quot;(1. foo)(2. bar)(3. baz)&quot;;</span><br />
<br />
<span style="color: #006600; font-style: italic;">// TT</span><br />
<span style="color: #003366; font-weight: bold;">var</span> tmp <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> Template.<span style="color: #660066;">Tiny</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #003366; font-weight: bold;">var</span> idx <span style="color: #339933;">=</span> <span style="color: #CC0000;">0</span><span style="color: #339933;">;</span><br />
<span style="color: #003366; font-weight: bold;">var</span> str <span style="color: #339933;">=</span> tmp.<span style="color: #660066;">process</span><span style="color: #009900;">&#40;</span><br />
&nbsp; &nbsp;<span style="color: #3366CC;">&quot;[% FOREACH x IN arr %]([% x.i %]. [% x.var %][% END %]&quot;</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp;<span style="color: #009900;">&#123;</span> arr<span style="color: #339933;">:</span> data.<span style="color: #660066;">arr</span>.<span style="color: #660066;">map</span><span style="color: #009900;">&#40;</span><span style="color: #003366; font-weight: bold;">function</span><span style="color: #009900;">&#40;</span>x<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span> <span style="color: #000066; font-weight: bold;">return</span> <span style="color: #009900;">&#123;</span> i<span style="color: #339933;">:</span> idx<span style="color: #339933;">++,</span> <span style="color: #003366; font-weight: bold;">var</span><span style="color: #339933;">:</span> x <span style="color: #009900;">&#125;</span> <span style="color: #009900;">&#125;</span> <span style="color: #009900;">&#125;</span><br />
<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></td></tr></tbody></table></div>
<p>Example 6:</p>
<div class="codecolorer-container javascript vibrant" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br /></div></td><td><div class="javascript codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #003366; font-weight: bold;">var</span> data <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span> longtext<span style="color: #339933;">:</span> <span style="color: #3366CC;">&quot;this won't fit!&quot;</span><span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #006600; font-style: italic;">// XTPL</span><br />
<span style="color: #003366; font-weight: bold;">var</span> tpl <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> Ext.<span style="color: #660066;">XTemplate</span><span style="color: #009900;">&#40;</span><span style="color: #3366CC;">'{longtext:ellipsis(5)}'</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #003366; font-weight: bold;">var</span> str <span style="color: #339933;">=</span> tpl.<span style="color: #660066;">apply</span><span style="color: #009900;">&#40;</span>data<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span> <span style="color: #006600; font-style: italic;">// &quot;this ...&quot;;</span><br />
<br />
<span style="color: #006600; font-style: italic;">// TT</span><br />
<span style="color: #003366; font-weight: bold;">var</span> tmp <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> Template.<span style="color: #660066;">Tiny</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #003366; font-weight: bold;">var</span> str <span style="color: #339933;">=</span> tmp.<span style="color: #660066;">process</span><span style="color: #009900;">&#40;</span><br />
&nbsp; &nbsp;<span style="color: #3366CC;">&quot;[% longtext %]&quot;</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp;<span style="color: #009900;">&#123;</span> longtext<span style="color: #339933;">:</span> Ext.<span style="color: #660066;">util</span>.<span style="color: #660066;">Format</span><span style="color: #009900;">&#40;</span> data.<span style="color: #660066;">longtext</span><span style="color: #339933;">,</span> 5<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#125;</span><br />
<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></td></tr></tbody></table></div>
<h3>Template.Tiny</h3>
<p>Pros:</p>
<ul>
<li>Has IF/ELSE (Example 7)</li>
<li>Doesn&#8217;t crash on undefined fields</li>
<li>Nicely Licenced (Perl License)</li>
</ul>
<p>Cons:</p>
<ul>
<li>No complex expressions, math, or external javascript support</li>
<li>No topicalizing</li>
<li>Doesn&#8217;t crash on undefined fields (could be nice for debugging)</li>
<li>Probably slower (haven&#8217;t checked that yet)</li>
</ul>
<p>Example 7:</p>
<div class="codecolorer-container javascript vibrant" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br /></div></td><td><div class="javascript codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">&nbsp; &nbsp;<span style="color: #003366; font-weight: bold;">var</span> data <span style="color: #339933;">=</span> <span style="color: #009900;">&#123;</span> jack_slocum<span style="color: #339933;">:</span> 1 <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp;<span style="color: #006600; font-style: italic;">// TT</span><br />
&nbsp; &nbsp;<span style="color: #003366; font-weight: bold;">var</span> tmp <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> Template.<span style="color: #660066;">Tiny</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp;<span style="color: #003366; font-weight: bold;">var</span> str <span style="color: #339933;">=</span> tmp.<span style="color: #660066;">process</span><span style="color: #009900;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #3366CC;">&quot;[% IF jack_slocum %]We don't appreciate else-ifs[% ELSE %] Woot![% END %]&quot;</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; data<br />
&nbsp; &nbsp;<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp;<span style="color: #006600; font-style: italic;">// XTPL</span><br />
&nbsp; &nbsp;<span style="color: #003366; font-weight: bold;">var</span> tpl <span style="color: #339933;">=</span> <span style="color: #003366; font-weight: bold;">new</span> Ext.<span style="color: #660066;">XTemplate</span><span style="color: #009900;">&#40;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #3366CC;">'&lt;tpl if=&quot;jack_slocum&quot;&gt;We don<span style="color: #000099; font-weight: bold;">\'</span>t appreciate else-ifs&lt;/tpl&gt;&lt;tpl if=&quot;!jack_slocum&quot;&gt;Woot!&lt;/tpl&gt;'</span><br />
&nbsp; &nbsp; &nbsp; <span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp;<span style="color: #003366; font-weight: bold;">var</span> str <span style="color: #339933;">=</span> tpl.<span style="color: #660066;">apply</span><span style="color: #009900;">&#40;</span>data<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></div></td></tr></tbody></table></div>
<p>I am planning on making a wrapper for TT for our stuff that will allow an anonymous function that will do data transformation like above.  But as you can see above XTemplate really has more to offer, it just annoys the heck out of me on a regular basis <img src='http://blog.afoolishmanifesto.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<div id="crp_related"><h2>Related Posts:</h2><ul><li><a href="http://blog.afoolishmanifesto.com/archives/304" rel="bookmark" class="crp_title">Javascript scope</a></li><li><a href="http://blog.afoolishmanifesto.com/archives/94" rel="bookmark" class="crp_title">Javascript with Prototype: Hexstring to boolean array</a></li><li><a href="http://blog.afoolishmanifesto.com/archives/527" rel="bookmark" class="crp_title">Ext Conference Day 2</a></li><li><a href="http://blog.afoolishmanifesto.com/archives/521" rel="bookmark" class="crp_title">Ext Conference, Day 1</a></li><li><a href="http://blog.afoolishmanifesto.com/archives/1282" rel="bookmark" class="crp_title">An Exposition on Specific Time Saving Code</a></li><li>Powered by <a href="http://ajaydsouza.com/wordpress/plugins/contextual-related-posts/">Contextual Related Posts</a></li></ul></div><img src="http://feeds.feedburner.com/~r/AFoolishManifesto/~4/phRTNDLamic" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.afoolishmanifesto.com/archives/1277/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://blog.afoolishmanifesto.com/archives/1277</feedburner:origLink></item>
		<item>
		<title>Solution on how to serialize dates nicely</title>
		<link>http://feedproxy.google.com/~r/AFoolishManifesto/~3/KOlRljykXLU/1273</link>
		<comments>http://blog.afoolishmanifesto.com/archives/1273#comments</comments>
		<pubDate>Thu, 21 Jan 2010 16:27:00 +0000</pubDate>
		<dc:creator>fREW Schmidt</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[DateTime]]></category>
		<category><![CDATA[dbix::class]]></category>
		<category><![CDATA[perl]]></category>
		<category><![CDATA[Prototypical OO]]></category>
		<category><![CDATA[serialization]]></category>

		<guid isPermaLink="false">http://blog.afoolishmanifesto.com/?p=1273</guid>
		<description><![CDATA[So after discussing this problem with the inimitable ribasushi we came up with a good solution.  It&#8217;s not quite generic, but it solves the current problem very nicely.  First, we subclass DateTime:
123456789package MTSI::DateTime;
use strict;
use warnings;

use parent 'DateTime';

sub TO_JSON &#123; shift-&#62;ymd &#125;

1;
Next, in the base class we use for all of our Result classes [...]]]></description>
			<content:encoded><![CDATA[<p>So after discussing <a href="/archives/1269">this problem</a> with the inimitable ribasushi we came up with a good solution.  It&#8217;s not quite generic, but it solves the current problem very nicely.  First, we subclass DateTime:</p>
<div class="codecolorer-container perl vibrant" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br /></div></td><td><div class="perl codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><a href="http://perldoc.perl.org/functions/package.html"><span style="color: #000066;">package</span></a> MTSI<span style="color: #339933;">::</span><span style="color: #006600;">DateTime</span><span style="color: #339933;">;</span><br />
<span style="color: #000000; font-weight: bold;">use</span> strict<span style="color: #339933;">;</span><br />
<span style="color: #000000; font-weight: bold;">use</span> warnings<span style="color: #339933;">;</span><br />
<br />
<span style="color: #000000; font-weight: bold;">use</span> parent <span style="color: #ff0000;">'DateTime'</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #000000; font-weight: bold;">sub</span> TO_JSON <span style="color: #009900;">&#123;</span> shift<span style="color: #339933;">-&gt;</span><span style="color: #006600;">ymd</span> <span style="color: #009900;">&#125;</span><br />
<br />
<span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span></div></td></tr></tbody></table></div>
<p>Next, in the base class we use for all of our Result classes in our Schema, we override _inflate_to_datetime to rebless the returned value into our subclass:</p>
<div class="codecolorer-container perl vibrant" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br /></div></td><td><div class="perl codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><a href="http://perldoc.perl.org/functions/package.html"><span style="color: #000066;">package</span></a> ACD<span style="color: #339933;">::</span><span style="color: #006600;">Schema</span><span style="color: #339933;">::</span><span style="color: #006600;">Result</span><span style="color: #339933;">;</span><br />
<span style="color: #000000; font-weight: bold;">use</span> strict<span style="color: #339933;">;</span><br />
<span style="color: #000000; font-weight: bold;">use</span> warnings<span style="color: #339933;">;</span><br />
<br />
<span style="color: #000000; font-weight: bold;">use</span> parent <span style="color: #ff0000;">'DBIx::Class::Core'</span><span style="color: #339933;">;</span><br />
<br />
__PACKAGE__<span style="color: #339933;">-&gt;</span><span style="color: #006600;">load_components</span><span style="color: #009900;">&#40;</span><a href="http://perldoc.perl.org/functions/qw.html"><span style="color: #000066;">qw</span></a><span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp;TimeStamp<br />
&nbsp; &nbsp;Helper<span style="color: #339933;">::</span><span style="color: #006600;">Row</span><span style="color: #339933;">::</span><span style="color: #006600;">NumifyGet</span><br />
<span style="color: #009900;">&#125;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #000000; font-weight: bold;">use</span> MTSI<span style="color: #339933;">::</span><span style="color: #006600;">DateTime</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #000000; font-weight: bold;">sub</span> _inflate_to_datetime <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp;<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$self</span> <span style="color: #339933;">=</span> <a href="http://perldoc.perl.org/functions/shift.html"><span style="color: #000066;">shift</span></a><span style="color: #339933;">;</span><br />
&nbsp; &nbsp;<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$val</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">$self</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">next</span><span style="color: #339933;">::</span><span style="color: #006600;">method</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">@_</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
&nbsp; &nbsp;<a href="http://perldoc.perl.org/functions/return.html"><span style="color: #000066;">return</span></a> <a href="http://perldoc.perl.org/functions/bless.html"><span style="color: #000066;">bless</span></a> <span style="color: #0000ff;">$val</span><span style="color: #339933;">,</span> <span style="color: #ff0000;">'MTSI::DateTime'</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span><br />
<br />
<span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span></div></td></tr></tbody></table></div>
<p>And lastly, in our JSON view, we ensure that convert_blessed is on so that json will automatically call our TO_JSON method:</p>
<div class="codecolorer-container perl vibrant" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br /></div></td><td><div class="perl codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><a href="http://perldoc.perl.org/functions/package.html"><span style="color: #000066;">package</span></a> ACD<span style="color: #339933;">::</span><span style="color: #006600;">View</span><span style="color: #339933;">::</span><span style="color: #006600;">JSON</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #000000; font-weight: bold;">use</span> Moose<span style="color: #339933;">;</span><br />
extends <span style="color: #ff0000;">'Catalyst::View::JSON'</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #000000; font-weight: bold;">use</span> JSON<span style="color: #339933;">::</span><span style="color: #006600;">XS</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
has encoder <span style="color: #339933;">=&gt;</span> <span style="color: #009900;">&#40;</span><br />
&nbsp; &nbsp;is <span style="color: #339933;">=&gt;</span> <span style="color: #ff0000;">'ro'</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp;lazy_build <span style="color: #339933;">=&gt;</span> 1<span style="color: #339933;">,</span><br />
<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #000000; font-weight: bold;">sub</span> _build_encoder <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp;<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$self</span> <span style="color: #339933;">=</span> <a href="http://perldoc.perl.org/functions/shift.html"><span style="color: #000066;">shift</span></a><span style="color: #339933;">;</span><br />
&nbsp; &nbsp;<a href="http://perldoc.perl.org/functions/return.html"><span style="color: #000066;">return</span></a> JSON<span style="color: #339933;">::</span><span style="color: #006600;">XS</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">new</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">utf8</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">convert_blessed</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span><br />
<br />
<br />
<span style="color: #000000; font-weight: bold;">sub</span> encode_json <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp;<span style="color: #b1b100;">my</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$self</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">$c</span><span style="color: #339933;">,</span> <span style="color: #0000ff;">$data</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">=</span> <span style="color: #0000ff;">@_</span><span style="color: #339933;">;</span><br />
&nbsp; &nbsp;<span style="color: #0000ff;">$self</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">encoder</span><span style="color: #339933;">-&gt;</span><span style="color: #006600;">encode</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">$data</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span><br />
<br />
<span style="color: #cc66cc;">1</span><span style="color: #339933;">;</span></div></td></tr></tbody></table></div>
<p>And that&#8217;s all there is to it!  Thanks Perl for allowing me to rebless my objects <img src='http://blog.afoolishmanifesto.com/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' /> </p>
<div id="crp_related"><h2>Related Posts:</h2><ul><li><a href="http://blog.afoolishmanifesto.com/archives/1269" rel="bookmark" class="crp_title">What is the right way to serialize X object generically?</a></li><li><a href="http://blog.afoolishmanifesto.com/archives/274" rel="bookmark" class="crp_title">Paranoid Deletion in DBIx::Class</a></li><li><a href="http://blog.afoolishmanifesto.com/archives/1289" rel="bookmark" class="crp_title">New stuff in DBIx::Class::Helpers 2.00200</a></li><li><a href="http://blog.afoolishmanifesto.com/archives/739" rel="bookmark" class="crp_title">Don&#8217;t Repeat Yourself: JSON</a></li><li><a href="http://blog.afoolishmanifesto.com/archives/1261" rel="bookmark" class="crp_title">Latest additions to DBIC::Helpers</a></li><li>Powered by <a href="http://ajaydsouza.com/wordpress/plugins/contextual-related-posts/">Contextual Related Posts</a></li></ul></div><img src="http://feeds.feedburner.com/~r/AFoolishManifesto/~4/KOlRljykXLU" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.afoolishmanifesto.com/archives/1273/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://blog.afoolishmanifesto.com/archives/1273</feedburner:origLink></item>
		<item>
		<title>What is the right way to serialize X object generically?</title>
		<link>http://feedproxy.google.com/~r/AFoolishManifesto/~3/9bfocbDOfCs/1269</link>
		<comments>http://blog.afoolishmanifesto.com/archives/1269#comments</comments>
		<pubDate>Thu, 21 Jan 2010 03:03:01 +0000</pubDate>
		<dc:creator>fREW Schmidt</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[perl]]></category>
		<category><![CDATA[serialization]]></category>

		<guid isPermaLink="false">http://blog.afoolishmanifesto.com/?p=1269</guid>
		<description><![CDATA[Background: dates in our database automatically get &#8220;inflated&#8221; to DateTime objects.  That works pretty much perfectly.  We use JSON to serialize all of our objects to go to our JavaScript stuff on the client side.  The way that works is basically like the following:
12345678910# this should probably be called something more generic, [...]]]></description>
			<content:encoded><![CDATA[<p>Background: dates in our database automatically get &#8220;inflated&#8221; to <a href="http://search.cpan.org/perldoc?DateTime">DateTime</a> objects.  That works pretty much perfectly.  We use JSON to serialize all of our objects to go to our JavaScript stuff on the client side.  The way that works is basically like the following:</p>
<div class="codecolorer-container perl vibrant" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br /></div></td><td><div class="perl codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #666666; font-style: italic;"># this should probably be called something more generic, like serialize</span><br />
<span style="color: #666666; font-style: italic;"># but this decision was made by someone else and I'm not going to</span><br />
<span style="color: #666666; font-style: italic;"># spend time solving that for now</span><br />
<span style="color: #000000; font-weight: bold;">sub</span> TO_JSON <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp;<span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$self</span> <span style="color: #339933;">=</span> <a href="http://perldoc.perl.org/functions/shift.html"><span style="color: #000066;">shift</span></a><span style="color: #339933;">;</span><br />
&nbsp; &nbsp;<a href="http://perldoc.perl.org/functions/return.html"><span style="color: #000066;">return</span></a> <span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp; &nbsp; <a href="http://perldoc.perl.org/functions/map.html"><span style="color: #000066;">map</span></a> <span style="color: #339933;">+</span><span style="color: #009900;">&#40;</span> <span style="color: #0000ff;">$_</span> <span style="color: #339933;">=&gt;</span> <span style="color: #0000ff;">$self</span><span style="color: #339933;">-&gt;</span><span style="color: #0000ff;">$_</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<a href="http://perldoc.perl.org/functions/qw.html"><span style="color: #000066;">qw</span></a><span style="color: #009900;">&#123;</span>id name when_created<span style="color: #009900;">&#125;</span><br />
&nbsp; &nbsp;<span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span><br />
<span style="color: #009900;">&#125;</span></div></td></tr></tbody></table></div>
<p>which expands to:</p>
<div class="codecolorer-container perl vibrant" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br />5<br /></div></td><td><div class="perl codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #009900;">&#123;</span><br />
&nbsp; &nbsp;id <span style="color: #339933;">=&gt;</span> <span style="color: #cc66cc;">1</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp;name <span style="color: #339933;">=&gt;</span> <span style="color: #ff0000;">'frew'</span><span style="color: #339933;">,</span><br />
&nbsp; &nbsp;when_created <span style="color: #339933;">=&gt;</span> DateTime<span style="color: #339933;">-&gt;</span><span style="color: #006600;">new</span><span style="color: #009900;">&#40;</span><span style="color: #339933;">...</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">,</span> &nbsp;<span style="color: #666666; font-style: italic;"># &lt;-- not ok</span><br />
<span style="color: #009900;">&#125;</span></div></td></tr></tbody></table></div>
<p>Problematically, DateTime has no TO_JSON method.  I see two solutions to this, both of which kinda suck.</p>
<h3>Monkey Patch</h3>
<p>I could do something like:</p>
<div class="codecolorer-container perl vibrant" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br /></div></td><td><div class="perl codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><a href="http://perldoc.perl.org/functions/no.html"><span style="color: #000066;">no</span></a> strict <span style="color: #ff0000;">'refs'</span><span style="color: #339933;">;</span><br />
<span style="color: #0000ff;">*DateTime</span><span style="color: #339933;">::</span><span style="color: #006600;">TO_JSON</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">sub</span> <span style="color: #009900;">&#123;</span> shift<span style="color: #339933;">-&gt;</span><span style="color: #006600;">ymd</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span><br />
<span style="color: #000000; font-weight: bold;">use</span> strict<span style="color: #339933;">;</span></div></td></tr></tbody></table></div>
<p>but we all know that Monkey Patching is Sketch Towne City.  Since perl is a prototypical language there is certainly a way to do something like:</p>
<div class="codecolorer-container perl vibrant" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br /></div></td><td><div class="perl codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><span style="color: #b1b100;">my</span> <span style="color: #0000ff;">$f</span> <span style="color: #339933;">=</span> DateTime<span style="color: #339933;">-&gt;</span><span style="color: #006600;">now</span><span style="color: #339933;">;</span><br />
<span style="color: #0000ff;">$f</span><span style="color: #339933;">::</span><span style="color: #006600;">TO_JSON</span> <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">sub</span> <span style="color: #009900;">&#123;</span> shift<span style="color: #339933;">-&gt;</span><span style="color: #006600;">ymd</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span></div></td></tr></tbody></table></div>
<p>but I couldn&#8217;t really figure out how to do it.  And even if I could that (probably easy with <a href="http://search.cpan.org/perldoc?Class::MOP">Class::MOP</a>) I&#8217;d still have to make hooks to do that to all to all of our DateTime objects (which still sucks.)  And then I could effectively do the same thing&#8230;</p>
<h3>Subclass DateTime</h3>
<div class="codecolorer-container perl vibrant" style="overflow:auto;white-space:nowrap;border: 1px solid #9F9F9F;width:435px;"><table cellspacing="0" cellpadding="0"><tbody><tr><td style="padding:5px;text-align:center;color:#888888;background-color:#EEEEEE;border-right: 1px solid #9F9F9F;font: normal 12px/1.4em Monaco, Lucida Console, monospace;"><div>1<br />2<br />3<br />4<br /></div></td><td><div class="perl codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap"><a href="http://perldoc.perl.org/functions/package.html"><span style="color: #000066;">package</span></a> DateTime<span style="color: #339933;">::</span><span style="color: #006600;">Frew</span><span style="color: #339933;">;</span><br />
<span style="color: #000000; font-weight: bold;">use</span> parent <span style="color: #ff0000;">'DateTime'</span><span style="color: #339933;">;</span><br />
<br />
<span style="color: #000000; font-weight: bold;">sub</span> TO_JSON <span style="color: #009900;">&#123;</span> shift<span style="color: #339933;">-&gt;</span><span style="color: #006600;">ymd</span> <span style="color: #009900;">&#125;</span><span style="color: #339933;">;</span></div></td></tr></tbody></table></div>
<p>And then do some kind of trickery in DBIC-land to make the DateTime instantiation able to use other classes.  But that&#8217;s not as simple as it might sound (due to design issues in DBIC that are not easy to solve as far as I can see.)</p>
<p>I&#8217;m pretty sure that there is a good solution that I&#8217;m missing.  What is it?  Can anyone tell me?</p>
<div id="crp_related"><h2>Related Posts:</h2><ul><li><a href="http://blog.afoolishmanifesto.com/archives/1273" rel="bookmark" class="crp_title">Solution on how to serialize dates nicely</a></li><li><a href="http://blog.afoolishmanifesto.com/archives/274" rel="bookmark" class="crp_title">Paranoid Deletion in DBIx::Class</a></li><li><a href="http://blog.afoolishmanifesto.com/archives/1289" rel="bookmark" class="crp_title">New stuff in DBIx::Class::Helpers 2.00200</a></li><li><a href="http://blog.afoolishmanifesto.com/archives/739" rel="bookmark" class="crp_title">Don&#8217;t Repeat Yourself: JSON</a></li><li><a href="http://blog.afoolishmanifesto.com/archives/503" rel="bookmark" class="crp_title">DBIx::Class: A Love Story</a></li><li>Powered by <a href="http://ajaydsouza.com/wordpress/plugins/contextual-related-posts/">Contextual Related Posts</a></li></ul></div><img src="http://feeds.feedburner.com/~r/AFoolishManifesto/~4/9bfocbDOfCs" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.afoolishmanifesto.com/archives/1269/feed</wfw:commentRss>
		<slash:comments>3</slash:comments>
		<feedburner:origLink>http://blog.afoolishmanifesto.com/archives/1269</feedburner:origLink></item>
		<item>
		<title>So Long IronMan….Sortof…</title>
		<link>http://feedproxy.google.com/~r/AFoolishManifesto/~3/DRJfx0NMvWQ/1264</link>
		<comments>http://blog.afoolishmanifesto.com/archives/1264#comments</comments>
		<pubDate>Wed, 20 Jan 2010 02:44:19 +0000</pubDate>
		<dc:creator>fREW Schmidt</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[ironman]]></category>
		<category><![CDATA[perl]]></category>

		<guid isPermaLink="false">http://blog.afoolishmanifesto.com/?p=1264</guid>
		<description><![CDATA[The IronMan initiative is awesome!  No one should misunderstand that.  But I am getting WAY TOO MANY things in my feed reader.  So here&#8217;s my solution: 

unsubscribe from from the vanilla feed.
Add the OPML to my feed reader and then unsubscribe from the non-english and spam feeds
work on the IronMan code base [...]]]></description>
			<content:encoded><![CDATA[<p>The <a href="http://ironman.enlightenedperl.org/">IronMan</a> initiative is awesome!  No one should misunderstand that.  But I am getting WAY TOO MANY things in my feed reader.  So here&#8217;s my solution: </p>
<ol>
<li>unsubscribe from from the vanilla feed.</li>
<li>Add the <a href="http://ironman.enlightenedperl.org/subscriptions.opml">OPML</a> to my feed reader and then unsubscribe from the non-english and spam feeds</li>
<li>work on the IronMan code base to add another feed of when people add their feed, and then subscribe to that so I know when people join</li>
<li>profit!</li>
</ol>
<p>Anyway, if anyone wants to help with that second to last one I&#8217;d appreciate it since plagger is CRAZY.</p>
<div id="crp_related"><h2>Related Posts:</h2><ul><li><a href="http://blog.afoolishmanifesto.com/archives/1207" rel="bookmark" class="crp_title">JAP(5|6)H</a></li><li><a href="http://blog.afoolishmanifesto.com/archives/1241" rel="bookmark" class="crp_title">Goals for the New Year</a></li><li><a href="http://blog.afoolishmanifesto.com/archives/940" rel="bookmark" class="crp_title">July 2009, DFW.p6m</a></li><li><a href="http://blog.afoolishmanifesto.com/archives/1238" rel="bookmark" class="crp_title">Processing is sweet!</a></li><li><a href="http://blog.afoolishmanifesto.com/archives/54" rel="bookmark" class="crp_title">Two Months and 10 000 Miles Later&#8230;</a></li><li>Powered by <a href="http://ajaydsouza.com/wordpress/plugins/contextual-related-posts/">Contextual Related Posts</a></li></ul></div><img src="http://feeds.feedburner.com/~r/AFoolishManifesto/~4/DRJfx0NMvWQ" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://blog.afoolishmanifesto.com/archives/1264/feed</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://blog.afoolishmanifesto.com/archives/1264</feedburner:origLink></item>
	</channel>
</rss><!-- Dynamic page generated in 7.992 seconds. --><!-- Cached page generated by WP-Super-Cache on 2010-03-08 18:29:32 -->
