<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	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/"
	>

<channel>
	<title>SIMOTRONE WEB PAGE &#187; Perl</title>
	<atom:link href="http://www.simotrone.it/tag/perl/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.simotrone.it</link>
	<description>Simotrone is always here!</description>
	<lastBuildDate>Sat, 04 Feb 2012 18:30:44 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1</generator>
		<item>
		<title>Mojolicious respond_to</title>
		<link>http://www.simotrone.it/2012/02/04/mojolicious-respond_to/</link>
		<comments>http://www.simotrone.it/2012/02/04/mojolicious-respond_to/#comments</comments>
		<pubDate>Sat, 04 Feb 2012 16:21:07 +0000</pubDate>
		<dc:creator>Simotrone</dc:creator>
				<category><![CDATA[Binary People]]></category>
		<category><![CDATA[Mojolicious]]></category>
		<category><![CDATA[Perl]]></category>
		<category><![CDATA[REST]]></category>

		<guid isPermaLink="false">http://www.simotrone.it/?p=3755</guid>
		<description><![CDATA[Mentre la bufera di neve torna ad affliggere Bologna, io giochicchio con Mojolicious e mi segno un paio di note. Per provare a scimmiottare un&#8217;interfaccia REST seria, m&#8217;ero costruito a colpi di given un controller che generava la risposta in funzione dell&#8217;attributo format dello stash (solite cose: html, json, xml); per altro, poichè non stavo [...]]]></description>
			<content:encoded><![CDATA[<p>Mentre la bufera di neve torna ad affliggere Bologna, io giochicchio con Mojolicious e mi segno un paio di note.</p>
<p>Per provare a scimmiottare un&#8217;interfaccia REST seria, m&#8217;ero costruito a colpi di <strong>given</strong> un controller che generava la risposta in funzione dell&#8217;attributo format dello stash (solite cose: html, json, xml); per altro, poichè non stavo usando &#8220;<em>the right way</em>&#8221; mi stavo pure scontrando con alcune difficoltà implementative (1).</p>
<p>In realtà esiste un comodissimo metodo <a href="http://mojolicio.us/perldoc/Mojolicious/Controller#respond_to">respond_to</a> che già compie questa selezione internamente (il <a href="https://github.com/kraih/mojo/blob/master/lib/Mojolicious/Controller.pm#L397">codice</a>).</p>
<p>Dato questo codice:</p>
<div class="codesnip-container" >
<div class="codesnip" style="font-family: monospace;"><span class="co1">#!/usr/bin/env perl</span><br />
<span class="kw2">use</span> Mojolicious::<span class="me2">Lite</span>;<br />
get <span class="st0">&#8216;/test&#8217;</span> =&gt; <span class="kw2">sub</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">my</span> <span class="re0">$self</span> = <a href="http://perldoc.perl.org/functions/shift.html"><span class="kw3">shift</span></a>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">my</span> <span class="re0">$data</span> = <span class="br0">&#123;</span> a =&gt; <span class="nu0">1</span>, b =&gt; <span class="nu0">2</span>, c =&gt; <span class="nu0">3</span> <span class="br0">&#125;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$self</span>-&gt;<span class="me1">respond_to</span><span class="br0">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; json =&gt; <span class="br0">&#123;</span> json =&gt; <span class="re0">$data</span> <span class="br0">&#125;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; html =&gt; <span class="br0">&#123;</span> text =&gt; <span class="re0">$self</span>-&gt;<span class="me1">dumper</span><span class="br0">&#40;</span><span class="re0">$data</span><span class="br0">&#41;</span> <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#41;</span>;<br />
<span class="br0">&#125;</span>;<br />
app-&gt;<span class="me1">start</span>;</div>
</div>
<p>possiamo ottenere diverse risposte:</p>
<div class="codesnip-container" >
<div class="codesnip" style="font-family: monospace;"><span class="br0">&#40;</span><span class="nu0">1</span><span class="br0">&#41;</span> sim@titanio:/tmp$ mojo get -v -H <span class="st0">&#8216;Accept: text/html&#8217;</span> <span class="st0">&#8216;http://localhost:3001/test&#8217;</span><br />
GET /<span class="kw3">test</span> HTTP/<span class="nu0">1.1</span><br />
User-Agent: Mojolicious <span class="br0">&#40;</span>Perl<span class="br0">&#41;</span><br />
Accept: text/html<br />
Content-Length: <span class="nu0">0</span><br />
Host: localhost:<span class="nu0">3001</span></p>
<p>HTTP/<span class="nu0">1.1</span> <span class="nu0">200</span> OK<br />
X-Powered-By: Mojolicious <span class="br0">&#40;</span>Perl<span class="br0">&#41;</span><br />
Content-Type: text/html;<span class="re2">charset=</span>UTF<span class="nu0">-8</span><br />
Connection: keep-alive<br />
Date: Sat, <span class="nu0">04</span> Feb <span class="nu0">2012</span> <span class="nu0">15</span>:<span class="nu0">33</span>:<span class="nu0">23</span> GMT<br />
Server: Mojolicious <span class="br0">&#40;</span>Perl<span class="br0">&#41;</span><br />
Content-Length: <span class="nu0">39</span></p>
<p><span class="br0">&#123;</span><br />
&nbsp; <span class="st0">&#8216;c&#8217;</span> =&gt; <span class="nu0">3</span>,<br />
&nbsp; <span class="st0">&#8216;a&#8217;</span> =&gt; <span class="nu0">1</span>,<br />
&nbsp; <span class="st0">&#8216;b&#8217;</span> =&gt; <span class="nu0">2</span><br />
<span class="br0">&#125;</span><br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br />
<span class="br0">&#40;</span><span class="nu0">2</span><span class="br0">&#41;</span> sim@titanio:/tmp$ mojo get -v -H <span class="st0">&#8216;Accept: application/json&#8217;</span> <span class="st0">&#8216;http://localhost:3001/test&#8217;</span><br />
GET /<span class="kw3">test</span> HTTP/<span class="nu0">1.1</span><br />
User-Agent: Mojolicious <span class="br0">&#40;</span>Perl<span class="br0">&#41;</span><br />
Accept: application/json<br />
Content-Length: <span class="nu0">0</span><br />
Host: localhost:<span class="nu0">3001</span></p>
<p>HTTP/<span class="nu0">1.1</span> <span class="nu0">200</span> OK<br />
X-Powered-By: Mojolicious <span class="br0">&#40;</span>Perl<span class="br0">&#41;</span><br />
Content-Type: application/json<br />
Connection: keep-alive<br />
Date: Sat, <span class="nu0">04</span> Feb <span class="nu0">2012</span> <span class="nu0">15</span>:<span class="nu0">34</span>:<span class="nu0">01</span> GMT<br />
Server: Mojolicious <span class="br0">&#40;</span>Perl<span class="br0">&#41;</span><br />
Content-Length: <span class="nu0">19</span></p>
<p><span class="br0">&#123;</span><span class="st0">&quot;c&quot;</span>:<span class="nu0">3</span>,<span class="st0">&quot;a&quot;</span>:<span class="nu0">1</span>,<span class="st0">&quot;b&quot;</span>:<span class="nu0">2</span><span class="br0">&#125;</span><br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;<br />
<span class="br0">&#40;</span><span class="nu0">3</span><span class="br0">&#41;</span> sim@titanio:/tmp$ mojo get -v -H <span class="st0">&#8216;Accept: text/plain&#8217;</span> <span class="st0">&#8216;http://localhost:3001/test&#8217;</span>GET /<span class="kw3">test</span> HTTP/<span class="nu0">1.1</span><br />
User-Agent: Mojolicious <span class="br0">&#40;</span>Perl<span class="br0">&#41;</span><br />
Accept: text/plain<br />
Content-Length: <span class="nu0">0</span><br />
Host: localhost:<span class="nu0">3001</span></p>
<p>HTTP/<span class="nu0">1.1</span> <span class="nu0">204</span> No Content<br />
X-Powered-By: Mojolicious <span class="br0">&#40;</span>Perl<span class="br0">&#41;</span><br />
Connection: keep-alive<br />
Date: Sat, <span class="nu0">04</span> Feb <span class="nu0">2012</span> <span class="nu0">15</span>:<span class="nu0">34</span>:<span class="nu0">40</span> GMT<br />
Server: Mojolicious <span class="br0">&#40;</span>Perl<span class="br0">&#41;</span><br />
Content-Length: <span class="nu0">0</span><br />
&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8212;&#8211;<br />
<span class="br0">&#40;</span><span class="nu0">4</span><span class="br0">&#41;</span> sim@titanio:/tmp$ mojo get -v -H <span class="st0">&#8216;Accept: text/plainz&#8217;</span> <span class="st0">&#8216;http://localhost:3001/test&#8217;</span><br />
GET /<span class="kw3">test</span> HTTP/<span class="nu0">1.1</span><br />
User-Agent: Mojolicious <span class="br0">&#40;</span>Perl<span class="br0">&#41;</span><br />
Accept: text/plainz<br />
Content-Length: <span class="nu0">0</span><br />
Host: localhost:<span class="nu0">3001</span></p>
<p>HTTP/<span class="nu0">1.1</span> <span class="nu0">200</span> OK<br />
X-Powered-By: Mojolicious <span class="br0">&#40;</span>Perl<span class="br0">&#41;</span><br />
Content-Type: text/html;<span class="re2">charset=</span>UTF<span class="nu0">-8</span><br />
Connection: keep-alive<br />
Date: Sat, <span class="nu0">04</span> Feb <span class="nu0">2012</span> <span class="nu0">15</span>:<span class="nu0">35</span>:<span class="nu0">15</span> GMT<br />
Server: Mojolicious <span class="br0">&#40;</span>Perl<span class="br0">&#41;</span><br />
Content-Length: <span class="nu0">39</span></p>
<p><span class="br0">&#123;</span><br />
&nbsp; <span class="st0">&#8216;c&#8217;</span> =&gt; <span class="nu0">3</span>,<br />
&nbsp; <span class="st0">&#8216;a&#8217;</span> =&gt; <span class="nu0">1</span>,<br />
&nbsp; <span class="st0">&#8216;b&#8217;</span> =&gt; <span class="nu0">2</span><br />
<span class="br0">&#125;</span></div>
</div>
<p>Le prime tre sono corrette, poichè dati determinati header ottengo le risposte giuste:</p>
<ol>
<li>text/html &#8211; 200</li>
<li>application/json &#8211; 200</li>
<li>text/plain &#8211; 204 &#8211; nessuna rappresentazione corretta</li>
</ol>
<p>Il quarto a mio avviso è un <em>fail</em>, o meglio una scelta discutibile: invece che riconoscere l&#8217;header sbagliato  e mandare a spendere il client con un 204, gli serviamo html.</p>
<p>Benchè alla fine di quel metodo venga restituito un 204 se il $target non esite (<a href="https://github.com/kraih/mojo/blob/master/lib/Mojolicious/Controller.pm#L423">#L423</a>), il gioco &#8220;sporco&#8221; accade <a href="https://github.com/kraih/mojo/blob/master/lib/Mojolicious/Controller.pm#L406">20 righe prima</a> dove nel caso la rappresentazione passata non venga individuata, si ricade nella situazione di default (html di solito). Il problema a questo punto si incrocia con la possibilità che Mojolicious non abbia dentro di se la rappresentazione corretta benchè sia comune (openoffice, pdf &#8211; che forse ora sono stati inseriti, non so), cosa che può portare a conclusioni di default anche quando la rappresentazione richiesta è corretta ma non presente nei tipi di Mojo. In ogni caso, si può sempre aggiungere qualcosa ai <a href="http://mojolicio.us/perldoc/Mojolicious/Types">MIME</a>. </p>
<p>Ho comunque poi scoperto che la cosa è stata <a href="https://github.com/kraih/mojo/issues/237">discussa in passato</a> ed è stato deciso così.<br />
Well, basta saperlo. <img src='http://www.simotrone.it/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>PS: Io avrei lasciato i client mal fatti nel loro brodo, ma tant&#8217;è &#8211; probabilmente non capisco bene le implicazioni.</p>
<p>Note:<br />
(1) Le <a href="http://mojolicio.us/perldoc/Mojolicious/Routes">rotte</a> in Mojolicious permettono di selezionare il formato utilizzando un <em>array reference</em></p>
<div class="codesnip-container" >
<div class="codesnip" style="font-family: monospace;">get <span class="st0">&#8216;/formats&#8217;</span> =&gt; <span class="br0">&#91;</span><a href="http://perldoc.perl.org/functions/format.html"><span class="kw3">format</span></a> =&gt; <span class="br0">&#91;</span><span class="st0">&#8216;html&#8217;</span>,<span class="st0">&#8216;xml&#8217;</span><span class="br0">&#93;</span><span class="br0">&#93;</span> =&gt; <span class="kw2">sub</span> <span class="br0">&#123;</span> <span class="br0">&#125;</span>;</div>
</div>
<div class="codesnip-container" >
<div class="codesnip" style="font-family: monospace;">sim@titanio:/tmp$ <span class="kw2">perl</span> myapp.pl routes -v<br />
/formats &nbsp;GET &nbsp;formats &nbsp;^/formats\.<span class="br0">&#40;</span>xml|html<span class="br0">&#41;</span>$</div>
</div>
<p>ma, come si vede dalla regex, questo fa sì che la rotta &#8220;pulita&#8221; diventi &#8220;/formats.&#8221; che non è proprio quello che si vuole, di solito.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.simotrone.it/2012/02/04/mojolicious-respond_to/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Moose::Roles</title>
		<link>http://www.simotrone.it/2012/01/18/mooseroles/</link>
		<comments>http://www.simotrone.it/2012/01/18/mooseroles/#comments</comments>
		<pubDate>Wed, 18 Jan 2012 22:29:14 +0000</pubDate>
		<dc:creator>Simotrone</dc:creator>
				<category><![CDATA[Binary People]]></category>
		<category><![CDATA[moose]]></category>
		<category><![CDATA[Moose::Role]]></category>
		<category><![CDATA[object oriented]]></category>
		<category><![CDATA[OOP]]></category>
		<category><![CDATA[Perl]]></category>
		<category><![CDATA[ruoli]]></category>

		<guid isPermaLink="false">http://www.simotrone.it/?p=3745</guid>
		<description><![CDATA[Ho rispolverato alcuni appunti cartacei relativi i Ruoli di Perl Moose che riporto qui. I ruoli rappresentano comportamenti condivisi fra le classi La classe fa ciò che dice il ruolo. I ruoli non sono classi; infatti i ruoli non si ereditano e non si istanziano. I ruoli vengono consumati da classi o da altri ruoli. [...]]]></description>
			<content:encoded><![CDATA[<p>Ho rispolverato alcuni appunti cartacei relativi i Ruoli di Perl Moose che riporto qui.</p>
<ul>
<li>I ruoli rappresentano comportamenti condivisi fra le classi</li>
<li>La classe fa ciò che dice il ruolo.</li>
<li>I ruoli <strong>non</strong> sono classi; infatti i ruoli non si ereditano e non si istanziano.</li>
<li>I ruoli vengono <strong>consumati</strong> da classi o da altri ruoli.</li>
<li>I ruoli sono <strong>composti</strong> in una classe con la funzione <em>with</em>.</li>
<li>Tutti i metodi, modificatori, attributi definiti in un ruolo sono aggiunti direttamente alla classe che consuma il ruolo.</li>
<li>Attributi e metodi appariranno come se fossero definiti nella classe.</li>
<li>Una sottoclasse della classe consumata (cioè con il ruolo) eredita tutti questi metodi/attributi.</li>
</ul>
<div class="codesnip-container" >
<div class="codesnip" style="font-family: monospace;"><a href="http://perldoc.perl.org/functions/package.html"><span class="kw3">package</span></a> Breakable;<br />
<span class="kw2">use</span> Moose::<span class="me2">Role</span>;</p>
<p>has <span class="st0">&#8216;is_broken&#8217;</span> =&gt; <span class="br0">&#40;</span><br />
&nbsp; &nbsp; &nbsp; is &nbsp;=&gt; <span class="st0">&#8216;rw&#8217;</span>,<br />
&nbsp; &nbsp; &nbsp; isa =&gt; <span class="st0">&#8216;Bool&#8217;</span>,<br />
<span class="br0">&#41;</span>;</p>
<p><span class="kw2">sub</span> break <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; <span class="kw1">my</span> <span class="re0">$self</span> = <a href="http://perldoc.perl.org/functions/shift.html"><span class="kw3">shift</span></a>;<br />
&nbsp; &nbsp; &nbsp; <a href="http://perldoc.perl.org/functions/print.html"><span class="kw3">print</span></a> <span class="st0">&quot;I broke<span class="es0">\n</span>&quot;</span>;<br />
&nbsp; &nbsp; &nbsp; <span class="re0">$self</span>-&gt;<span class="me1">is_broken</span><span class="br0">&#40;</span><span class="nu0">1</span><span class="br0">&#41;</span>;<br />
<span class="br0">&#125;</span></div>
</div>
<div class="codesnip-container" >
<div class="codesnip" style="font-family: monospace;"><a href="http://perldoc.perl.org/functions/package.html"><span class="kw3">package</span></a> Car;<br />
<span class="kw2">use</span> Moose;<br />
with <span class="st0">&#8216;Breakable&#8217;</span>;</p>
<p>has <span class="st0">&#8216;engine&#8217;</span> =&gt; <span class="br0">&#40;</span><br />
&nbsp; &nbsp; &nbsp; is &nbsp;=&gt; <span class="st0">&#8216;ro&#8217;</span>,<br />
&nbsp; &nbsp; &nbsp; isa =&gt; <span class="st0">&#8216;Engine&#8217;</span>,<br />
<span class="br0">&#41;</span>;</div>
</div>
<div class="codesnip-container" >
<div class="codesnip" style="font-family: monospace;"><span class="kw1">my</span> <span class="re0">$car</span> = Car-&gt;<span class="me1">new</span><span class="br0">&#40;</span> engine =&gt; Engine-&gt;<span class="me1">new</span> <span class="br0">&#41;</span>;<br />
<a href="http://perldoc.perl.org/functions/print.html"><span class="kw3">print</span></a> <span class="re0">$car</span>-&gt;<span class="me1">is_broken</span> ? <span class="st0">&#8216;Busted&#8217;</span> : <span class="st0">&#8216;Still working&#8217;</span>; &nbsp; <span class="co1"># Still working</span><br />
<span class="re0">$car</span>-&gt;<span class="me1">break</span>; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<span class="co1"># I broke</span><br />
<a href="http://perldoc.perl.org/functions/print.html"><span class="kw3">print</span></a> <span class="re0">$car</span>-&gt;<span class="me1">is_broken</span> ? <span class="st0">&#8216;Busted&#8217;</span> : <span class="st0">&#8216;Still working&#8217;</span>; &nbsp; <span class="co1"># Busted</span><br />
<span class="re0">$car</span>-&gt;<span class="me1">does</span><span class="br0">&#40;</span><span class="st0">&#8216;Breakable&#8217;</span><span class="br0">&#41;</span></div>
</div>
<p>Riferimenti:</p>
<ul>
<li>Moose::Role</li>
<li><a href="http://search.cpan.org/~doy/Moose-2.0401/lib/Moose/Manual/Roles.pod">Moose::Manual::Roles</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.simotrone.it/2012/01/18/mooseroles/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Visualizzare utf-8 con Perl</title>
		<link>http://www.simotrone.it/2011/12/02/visualizzare-utf-8-con-perl/</link>
		<comments>http://www.simotrone.it/2011/12/02/visualizzare-utf-8-con-perl/#comments</comments>
		<pubDate>Fri, 02 Dec 2011 06:39:52 +0000</pubDate>
		<dc:creator>Simotrone</dc:creator>
				<category><![CDATA[Binary People]]></category>
		<category><![CDATA[Perl]]></category>
		<category><![CDATA[utf8]]></category>

		<guid isPermaLink="false">http://www.simotrone.it/?p=3680</guid>
		<description><![CDATA[Trovata qua una riga di comando che mostra un po&#8217; di caratteri utf-8 con Perl. $ perl -CS -e &#8216; &#160; &#160; for ($i = 128; $i &#60; 11_620; $i++) { &#160; &#160; &#160; &#160; print chr $i, $i%30 ? &#34; &#34; : &#34;\n$i &#34; &#160; &#160; }; &#160; &#160; print &#34;\n&#34; &#160;&#8217;]]></description>
			<content:encoded><![CDATA[<p>Trovata <a href="http://fruit.je/utf-8">qua</a> una riga di comando che mostra un po&#8217; di caratteri utf-8 con Perl.</p>
<div class="codesnip-container" >
<div class="codesnip" style="font-family: monospace;">$ perl -CS -e <span class="st0">&#8216;<br />
&nbsp; &nbsp; for ($i = 128; $i &lt; 11_620; $i++) {<br />
&nbsp; &nbsp; &nbsp; &nbsp; print chr $i, $i%30 ? &quot; &quot; : &quot;\n$i &quot;<br />
&nbsp; &nbsp; };<br />
&nbsp; &nbsp; print &quot;\n&quot;<br />
&nbsp;&#8217;</span></div>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.simotrone.it/2011/12/02/visualizzare-utf-8-con-perl/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>DBIC-&gt;create e relazioni</title>
		<link>http://www.simotrone.it/2011/11/02/dbic-create-e-relazioni/</link>
		<comments>http://www.simotrone.it/2011/11/02/dbic-create-e-relazioni/#comments</comments>
		<pubDate>Wed, 02 Nov 2011 06:25:00 +0000</pubDate>
		<dc:creator>Simotrone</dc:creator>
				<category><![CDATA[Binary People]]></category>
		<category><![CDATA[DBIx::Class]]></category>
		<category><![CDATA[Perl]]></category>

		<guid isPermaLink="false">http://www.simotrone.it/?p=3607</guid>
		<description><![CDATA[Ho già parlato di DBIx::Class. Avendo result source con relazioni si possono ottenere risultati interessanti. Esistono gli oggetti Folk ed Email, ove l&#8217;oggetto Folk sia in relazione con molteplici oggetti Email (folk has_many emails). package My::Schema::Result::Folk; &#91;&#8230;&#93; __PACKAGE__-&#62;has_many&#40;&#8216;emails&#8217;,&#8216;My::Schema::Result::Email&#8217;,&#8216;id&#8217;&#41;; E&#8217; possibile creare un record scrivendo i dati dell&#8217;oggetto/i relativo/i in un arrayref. my $folks_rs = $schema-&#62;resultset&#40;&#34;Folk&#34;&#41;; [...]]]></description>
			<content:encoded><![CDATA[<p>Ho già parlato di <a href="http://www.simotrone.it/tag/dbix::class/">DBIx::Class</a>.</p>
<p>Avendo <a href="http://search.cpan.org/~abraxxa/DBIx-Class-0.08195/lib/DBIx/Class/ResultSource.pm">result source</a> con <a href="http://search.cpan.org/~abraxxa/DBIx-Class-0.08195/lib/DBIx/Class/Relationship.pm#has_many">relazioni</a> si possono ottenere <a href="http://search.cpan.org/~abraxxa/DBIx-Class-0.08195/lib/DBIx/Class/ResultSet.pm#create">risultati</a> interessanti.</p>
<p>Esistono gli oggetti Folk ed Email, ove l&#8217;oggetto Folk sia in relazione con molteplici oggetti Email (folk has_many emails).</p>
<div class="codesnip-container" >
<div class="codesnip" style="font-family: monospace;"><a href="http://perldoc.perl.org/functions/package.html"><span class="kw3">package</span></a> My::<span class="me2">Schema</span>::<span class="me2">Result</span>::<span class="me2">Folk</span>;<br />
<span class="br0">&#91;</span>&#8230;<span class="br0">&#93;</span><br />
__PACKAGE__-&gt;<span class="me1">has_many</span><span class="br0">&#40;</span><span class="st0">&#8216;emails&#8217;</span>,<span class="st0">&#8216;My::Schema::Result::Email&#8217;</span>,<span class="st0">&#8216;id&#8217;</span><span class="br0">&#41;</span>;</div>
</div>
<p>E&#8217; possibile creare un record scrivendo i dati dell&#8217;oggetto/i relativo/i in un arrayref.</p>
<div class="codesnip-container" >
<div class="codesnip" style="font-family: monospace;"><span class="kw1">my</span> <span class="re0">$folks_rs</span> = <span class="re0">$schema</span>-&gt;<span class="me1">resultset</span><span class="br0">&#40;</span><span class="st0">&quot;Folk&quot;</span><span class="br0">&#41;</span>;<br />
<span class="kw1">my</span> <span class="re0">$new_folk</span> = <span class="re0">$folks_rs</span>-&gt;<span class="me1">create</span><span class="br0">&#40;</span><span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; name &nbsp; =&gt; <span class="st0">&#8216;Test folk&#8217;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; emails =&gt; <span class="br0">&#91;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; email &nbsp; =&gt; <span class="st0">&#8216;mail@casa.name&#8217;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; comment =&gt; <span class="st0">&#8216;Test mail casalinga&#8217;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; email &nbsp; =&gt; <span class="st0">&#8216;mail@azienda.org&#8217;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; comment =&gt; <span class="st0">&#8216;Test mail aziendale&#8217;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#93;</span>,<br />
<span class="br0">&#125;</span><span class="br0">&#41;</span>;</div>
</div>
<p>E ci si libera di tutto con un bel</p>
<div class="codesnip-container" >
<div class="codesnip" style="font-family: monospace;"><span class="re0">$new_folk</span>-&gt;<span class="me1">delete</span></div>
</div>
<p><span id="more-3607"></span><br />
Codice e output (con DBIC_TRACE attivo).</p>
<div class="codesnip-container" >
<div class="codesnip" style="font-family: monospace;"><span class="co1">#!/usr/bin/perl</span></p>
<p><span class="kw2">use</span> strict;<br />
<span class="kw2">use</span> warnings;<br />
<span class="kw2">use</span> My::<span class="me2">Schema</span>;<br />
<span class="kw2">use</span> DBIx::<span class="me2">Class</span>;</p>
<p><span class="kw1">my</span> <span class="re0">$schema</span> &nbsp; = My::<span class="me2">Schema</span>-&gt;<span class="me1">connect</span><span class="br0">&#40;</span><span class="st0">&quot;dbi:mysql:dbname=xxx&quot;</span>,<span class="st0">&quot;aaa&quot;</span>,<span class="st0">&quot;bbb&quot;</span><span class="br0">&#41;</span>;<br />
<span class="kw1">my</span> <span class="re0">$folks_rs</span> = <span class="re0">$schema</span>-&gt;<span class="me1">resultset</span><span class="br0">&#40;</span><span class="st0">&quot;Folk&quot;</span><span class="br0">&#41;</span>;</p>
<p><span class="kw1">my</span> <span class="re0">$new_folk</span> = <span class="re0">$folks_rs</span>-&gt;<span class="me1">create</span><span class="br0">&#40;</span><span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; name &nbsp; =&gt; <span class="st0">&#8216;Test folk&#8217;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; emails =&gt; <span class="br0">&#91;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span> email =&gt; <span class="st0">&#8216;mail@casa.name&#8217;</span>, comment =&gt; <span class="st0">&#8216;Test mail casalinga&#8217;</span> <span class="br0">&#125;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#123;</span> email =&gt; <span class="st0">&#8216;mail@azienda.org&#8217;</span>, comment =&gt; <span class="st0">&#8216;Test mail aziendale&#8217;</span> <span class="br0">&#125;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#93;</span>,<br />
<span class="br0">&#125;</span><span class="br0">&#41;</span>;<br />
show_folk<span class="br0">&#40;</span><span class="re0">$new_folk</span>-&gt;<span class="me1">id</span><span class="br0">&#41;</span>;<br />
<span class="re0">$new_folk</span>-&gt;<span class="me1">delete</span>;</p>
<p><span class="kw2">sub</span> show_folk <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">my</span> <span class="br0">&#40;</span><span class="re0">$id</span><span class="br0">&#41;</span> = <span class="re0">@_</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">my</span> <span class="re0">$folk</span> = <span class="re0">$folks_rs</span>-&gt;<span class="me1">find</span><span class="br0">&#40;</span><span class="re0">$id</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">my</span> <span class="re0">@emails</span> = <a href="http://perldoc.perl.org/functions/map.html"><span class="kw3">map</span></a> <span class="br0">&#123;</span> <span class="re0">$_</span>-&gt;<span class="me1">email</span> <span class="br0">&#125;</span> <span class="re0">$folk</span>-&gt;<span class="me1">emails</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <a href="http://perldoc.perl.org/functions/print.html"><span class="kw3">print</span></a> <span class="st0">&quot; &quot;</span>.<span class="re0">$folk</span>-&gt;<span class="me1">name</span>, <span class="st0">&quot; [$id]<span class="es0">\n</span> &quot;</span>, <a href="http://perldoc.perl.org/functions/join.html"><span class="kw3">join</span></a><span class="br0">&#40;</span><span class="st0">&quot;<span class="es0">\n</span> &quot;</span>,<span class="re0">@emails</span><span class="br0">&#41;</span> , <span class="st0">&quot;<span class="es0">\n</span>&quot;</span>;<br />
<span class="br0">&#125;</span></div>
</div>
<div class="codesnip-container" >
<div class="codesnip" style="font-family: monospace;">$ <span class="re2">DBIC_TRACE=</span><span class="nu0">1</span> <span class="kw2">perl</span> dbic_test.pl</p>
<p>BEGIN WORK<br />
INSERT INTO folks <span class="br0">&#40;</span> name<span class="br0">&#41;</span> VALUES <span class="br0">&#40;</span> ? <span class="br0">&#41;</span>: <span class="st0">&#8216;Test folk&#8217;</span><br />
INSERT INTO emails <span class="br0">&#40;</span> comment, email, <span class="kw2">id</span><span class="br0">&#41;</span> VALUES <span class="br0">&#40;</span> ?, ?, ? <span class="br0">&#41;</span>: <span class="st0">&#8216;Test mail casalinga&#8217;</span>, <span class="st0">&#8216;mail@casa.name&#8217;</span>, <span class="st0">&#8217;134&#8242;</span><br />
INSERT INTO emails <span class="br0">&#40;</span> comment, email, <span class="kw2">id</span><span class="br0">&#41;</span> VALUES <span class="br0">&#40;</span> ?, ?, ? <span class="br0">&#41;</span>: <span class="st0">&#8216;Test mail aziendale&#8217;</span>, <span class="st0">&#8216;mail@azienda.org&#8217;</span>, <span class="st0">&#8217;134&#8242;</span><br />
COMMIT</p>
<p>SELECT me.<span class="kw2">id</span>, me.name, me.surname, me.birth, me.gender, me.created, me.updated, me.active FROM folks me WHERE <span class="br0">&#40;</span> me.<span class="kw2">id</span> = ? <span class="br0">&#41;</span>: <span class="st0">&#8217;134&#8242;</span><br />
SELECT me.<span class="kw2">id</span>, me.email, me.comment FROM emails me WHERE <span class="br0">&#40;</span> me.<span class="kw2">id</span> = ? <span class="br0">&#41;</span>: <span class="st0">&#8217;134&#8242;</span><br />
&nbsp;Test folk <span class="br0">&#91;</span><span class="nu0">134</span><span class="br0">&#93;</span><br />
&nbsp;mail@azienda.org<br />
&nbsp;mail@casa.name<br />
BEGIN WORK<br />
DELETE FROM folks WHERE <span class="br0">&#40;</span> <span class="kw2">id</span> = ? <span class="br0">&#41;</span>: <span class="st0">&#8217;134&#8242;</span><br />
SELECT me.<span class="kw2">id</span>, me.email, me.comment FROM emails me WHERE <span class="br0">&#40;</span> me.<span class="kw2">id</span> = ? <span class="br0">&#41;</span>: <span class="st0">&#8217;134&#8242;</span><br />
DELETE FROM emails WHERE <span class="br0">&#40;</span> email = ? <span class="br0">&#41;</span>: <span class="st0">&#8216;mail@azienda.org&#8217;</span><br />
DELETE FROM emails WHERE <span class="br0">&#40;</span> email = ? <span class="br0">&#41;</span>: <span class="st0">&#8216;mail@casa.name&#8217;</span><br />
COMMIT</div>
</div>
<p>(Come si vede chiaramente con quel codice, le fasi di inserimento e selezione dei dati avvengono in due momenti distinti (ci sono due blocchi BEGIN/COMMIT infatti).</p>
]]></content:encoded>
			<wfw:commentRss>http://www.simotrone.it/2011/11/02/dbic-create-e-relazioni/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Perl debugger come interprete interattivo</title>
		<link>http://www.simotrone.it/2011/10/29/perl-debugger-come-interprete-interattivo/</link>
		<comments>http://www.simotrone.it/2011/10/29/perl-debugger-come-interprete-interattivo/#comments</comments>
		<pubDate>Sat, 29 Oct 2011 08:24:12 +0000</pubDate>
		<dc:creator>Simotrone</dc:creator>
				<category><![CDATA[Binary People]]></category>
		<category><![CDATA[interprete interattivo]]></category>
		<category><![CDATA[Perl]]></category>

		<guid isPermaLink="false">http://www.simotrone.it/?p=3621</guid>
		<description><![CDATA[Tempo addietro mi è stato chiesto se Perl aveva un interprete interattivo, e risposi di no. In effetti si può però usare un trucco che ne mette uno a disposizione (con anche qualche feature) sfruttando il debugger del linguaggio. Dato uno script pinco.pl è possibile debuggarlo lanciando il comando col flag -d: $ perl -d [...]]]></description>
			<content:encoded><![CDATA[<p>Tempo addietro mi è stato chiesto se Perl aveva un interprete interattivo, e risposi di no.</p>
<p>In effetti si può però usare un trucco che ne mette uno a disposizione (con anche qualche feature) sfruttando il debugger del linguaggio.</p>
<p>Dato uno script pinco.pl è possibile <a href="http://perldoc.perl.org/perldebug.html">debuggarlo</a> lanciando il comando col flag -d:</p>
<div class="codesnip-container" >
<div class="codesnip" style="font-family: monospace;">$ <span class="kw2">perl</span> -d pinco.pl</div>
</div>
<p>Dunque, come ottenere un interprete?</p>
<div class="codesnip-container" >
<div class="codesnip" style="font-family: monospace;">$ <span class="kw2">perl</span> -d -e <span class="nu0">1</span></div>
</div>
<p>Questo comando lancia il debugger su uno script (-e) inesistente, e da quel momento in poi possiamo usare tutti gli strumenti di Perl (print per stampare valori, use per caricare moduli) più tutti gli strumenti del debugger (x per avere un dump delle strutture dati, b per creare un breakpoint) e così via.</p>
<p>Meglio di una gomitata in un occhio, invero.</p>
<p>Un video a riguardo l&#8217;ha girato <a href="http://szabgab.com/blog/2011/06/using-the-built-in-debugger-of-perl-as-repl.html">Gabor Szabo</a>.</p>
<p><iframe width="560" height="315" src="http://www.youtube.com/embed/pL_nDlXNqLY" frameborder="0" allowfullscreen></iframe></p>
]]></content:encoded>
			<wfw:commentRss>http://www.simotrone.it/2011/10/29/perl-debugger-come-interprete-interattivo/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Pod::Strip</title>
		<link>http://www.simotrone.it/2011/10/10/podstrip/</link>
		<comments>http://www.simotrone.it/2011/10/10/podstrip/#comments</comments>
		<pubDate>Mon, 10 Oct 2011 05:19:02 +0000</pubDate>
		<dc:creator>Simotrone</dc:creator>
				<category><![CDATA[Binary People]]></category>
		<category><![CDATA[codice]]></category>
		<category><![CDATA[Perl]]></category>
		<category><![CDATA[Pod]]></category>

		<guid isPermaLink="false">http://www.simotrone.it/?p=3562</guid>
		<description><![CDATA[Metodo grezzissimo per strippare il pod dal modulo perl e stampare il codice. sim@idrogeno:/tmp$ cat /usr/share/perl5/path/al/modulo.pm &#124; perl -MPod::Strip -e &#8216; my $p=Pod::Strip-&#62;new&#40;&#41;; &#160; &#160; my $podless; &#160; &#160; $p-&#62;output_string&#40;\$podless&#41;; &#160; &#160; my @rows = &#60;&#62;; &#160; &#160; my $text = join&#40;&#34;&#34;,@rows&#41;; &#160; &#160; $p-&#62;parse_string_document&#40;$text&#41;; &#160; &#160; print $podless &#8216; &#124; a2ps]]></description>
			<content:encoded><![CDATA[<p>Metodo grezzissimo per <em>strippare</em> il pod dal modulo perl e stampare il codice.</p>
<div class="codesnip-container" >
<div class="codesnip" style="font-family: monospace;">sim@idrogeno:/tmp$ <span class="kw2">cat</span> /usr/share/perl5/path/al/modulo.pm | <span class="kw2">perl</span> -MPod::Strip -e <span class="st0">&#8216;</span></div>
</div>
<div class="codesnip-container" >
<div class="codesnip" style="font-family: monospace;"><span class="kw1">my</span> <span class="re0">$p</span>=Pod::<span class="me2">Strip</span>-&gt;<span class="me1">new</span><span class="br0">&#40;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; <span class="kw1">my</span> <span class="re0">$podless</span>;<br />
&nbsp; &nbsp; <span class="re0">$p</span>-&gt;<span class="me1">output_string</span><span class="br0">&#40;</span>\<span class="re0">$podless</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; <span class="kw1">my</span> <span class="re0">@rows</span> = &lt;&gt;;<br />
&nbsp; &nbsp; <span class="kw1">my</span> <span class="re0">$text</span> = <a href="http://perldoc.perl.org/functions/join.html"><span class="kw3">join</span></a><span class="br0">&#40;</span><span class="st0">&quot;&quot;</span>,<span class="re0">@rows</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; <span class="re0">$p</span>-&gt;<span class="me1">parse_string_document</span><span class="br0">&#40;</span><span class="re0">$text</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; <a href="http://perldoc.perl.org/functions/print.html"><span class="kw3">print</span></a> <span class="re0">$podless</span></div>
</div>
<div class="codesnip-container" >
<div class="codesnip" style="font-family: monospace;"><span class="st0">&#8216; | a2ps</span></div>
</div>
]]></content:encoded>
			<wfw:commentRss>http://www.simotrone.it/2011/10/10/podstrip/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Module builderz</title>
		<link>http://www.simotrone.it/2011/10/06/module-builderz/</link>
		<comments>http://www.simotrone.it/2011/10/06/module-builderz/#comments</comments>
		<pubDate>Thu, 06 Oct 2011 05:25:52 +0000</pubDate>
		<dc:creator>Simotrone</dc:creator>
				<category><![CDATA[Binary People]]></category>
		<category><![CDATA[h2xs]]></category>
		<category><![CDATA[lib]]></category>
		<category><![CDATA[module-starter]]></category>
		<category><![CDATA[Perl]]></category>

		<guid isPermaLink="false">http://www.simotrone.it/?p=3549</guid>
		<description><![CDATA[Volevo annotarmi le differenze tra i vari modi per creare una distro software. Pacchetti sfruttati: module-starter con ExtUtils::MakeMaker, Module::Build, Module::Install e h2xs. sim@idrogeno:/tmp$ module-starter --author=sim --email=xxx@xxxxx.xxx --module=Test::Build --mb Added to MANIFEST: Build.PL Added to MANIFEST: Changes Added to MANIFEST: ignore.txt Added to MANIFEST: lib/Test/Build.pm Added to MANIFEST: MANIFEST Added to MANIFEST: README Added to MANIFEST: [...]]]></description>
			<content:encoded><![CDATA[<p>Volevo annotarmi le differenze tra i vari modi per creare una distro software.</p>
<p>Pacchetti sfruttati: <a href="http://search.cpan.org/~xsawyerx/Module-Starter-1.58/lib/Module/Starter.pm">module-starter</a> con <a href="http://search.cpan.org/~jkeenan/ExtUtils-ModuleMaker-0.51/lib/ExtUtils/ModuleMaker.pm">ExtUtils::MakeMaker</a>, <a href="http://search.cpan.org/~dagolden/Module-Build-0.3800/lib/Module/Build.pm">Module::Build</a>, <a href="http://search.cpan.org/~adamk/Module-Install-1.01/lib/Module/Install.pod">Module::Install</a> e <a href="http://search.cpan.org/~flora/perl-5.14.2/utils/h2xs.PL">h2xs</a>.</p>
<pre>sim@idrogeno:/tmp$ module-starter --author=sim
          --email=xxx@xxxxx.xxx --module=Test::Build --mb

Added to MANIFEST: Build.PL
Added to MANIFEST: Changes
Added to MANIFEST: ignore.txt
Added to MANIFEST: lib/Test/Build.pm
Added to MANIFEST: MANIFEST
Added to MANIFEST: README
Added to MANIFEST: t/00-load.t
Added to MANIFEST: t/boilerplate.t
Added to MANIFEST: t/manifest.t
Added to MANIFEST: t/pod-coverage.t
Added to MANIFEST: t/pod.t
Created starter directories and files

sim@idrogeno:/tmp$ module-starter --author=sim
          --email=xxx@xxxxx.xxx --module=Test::Install --mi

Added to MANIFEST: Changes
Added to MANIFEST: ignore.txt
Added to MANIFEST: lib/Test/Install.pm
Added to MANIFEST: Makefile.PL
Added to MANIFEST: MANIFEST
Added to MANIFEST: README
Added to MANIFEST: t/00-load.t
Added to MANIFEST: t/boilerplate.t
Added to MANIFEST: t/manifest.t
Added to MANIFEST: t/pod-coverage.t
Added to MANIFEST: t/pod.t
Created starter directories and files

sim@idrogeno:/tmp$ module-starter --author=sim
          --email=xxx@xxxxx.xxx --module=Test::EUMM --eumm

Added to MANIFEST: Changes
Added to MANIFEST: ignore.txt
Added to MANIFEST: lib/Test/EUMM.pm
Added to MANIFEST: Makefile.PL
Added to MANIFEST: MANIFEST
Added to MANIFEST: README
Added to MANIFEST: t/00-load.t
Added to MANIFEST: t/boilerplate.t
Added to MANIFEST: t/manifest.t
Added to MANIFEST: t/pod-coverage.t
Added to MANIFEST: t/pod.t
Created starter directories and files

sim@idrogeno:/tmp$ h2xs -XAn Test::H2xs

Defaulting to backwards compatibility with perl 5.12.4
If you intend this module to be compatible with earlier perl
versions, please specify a minimum perl version with the -b
option.

Writing Test-H2xs/lib/Test/H2xs.pm
Writing Test-H2xs/Makefile.PL
Writing Test-H2xs/README
Writing Test-H2xs/t/Test-H2xs.t
Writing Test-H2xs/Changes
Writing Test-H2xs/MANIFEST</pre>
<p>Tutti e 4 i modi scrivono i file Changes, MANIFEST, README, il package principale della lib e il test corrispondente.<br />
Le tre distribuzioni Perl sfruttate da module-starter scrivono anche diversi test in più (per lo più inutili a mio avviso) ed un file ignore.txt che non ho capito ancora a cosa serve (*).</p>
<p>Quindi alla fine della fiera, buttando via la &#8220;fuffa&#8221; ci resta:</p>
<ul>
<li>Module::Build crea Build.PL</li>
<li>Module::Install crea Makefile.PL</li>
<li>ExtUtils::MakeMaker crea Makefile.PL</li>
<li>h2xs crea Makefile.PL</li>
</ul>
<p>Il Makefile.PL più stringato è quello di Module::Install (e ha una costruzione diversa), mentre i due Makefile.PL di h2xs e ExtUtils::MakeMaker sono praticamente identici (e si basano entrambi su WriteMakefile &#8211; anche h2xs usa ExtUtils::MakeMaker). Infine Build.PL ha il suo proprio modo per scriversi la configurazione, ma comunque pare abbastanza intuitivo.</p>
<p>I Makefile.PL di h2xs e EUMM sono virtualmente identici, e producono lo stesso risultato (un makefile che poi copia la lib in blib e generano le man page).</p>
<p>Il Makefile.PL di Module::Install genera un META.yml e una serie di file nella directory inc/ , infine il makefile che produce il solito output.</p>
<pre>sim@idrogeno:/tmp/Test-Install$ perl Makefile.PL

include /tmp/Test-Install/inc/Module/Install.pm
include inc/Module/Install/Metadata.pm
include inc/Module/Install/Base.pm
include inc/Module/Install/Makefile.pm
include inc/Module/Install/AutoInstall.pm
include inc/Module/Install/Include.pm
include inc/Module/AutoInstall.pm
*** Module::AutoInstall version 1.03
*** Checking for Perl dependencies...
[Core Features]
- Test::More ...loaded. (0.98)
*** Module::AutoInstall configuration finished.
include inc/Module/Install/WriteAll.pm
include inc/Module/Install/Win32.pm
include inc/Module/Install/Can.pm
include inc/Module/Install/Fetch.pm
Checking if your kit is complete...
Looks good
Writing Makefile for Test::Install
Writing META.yml</pre>
<p>Il file Build.PL di Module::Build genera un ulteriore script Build e delle configurazioni (json e yml); il tutto è gestito in Perl senza l&#8217;intervento di make e l&#8217;effetto è identico (./Build produce il solito blib/ ). La <a href="http://search.cpan.org/~dagolden/Module-Build-0.3800/lib/Module/Build.pm">documentazione</a> spiega un po&#8217; meglio.</p>
<p>(*) Svelato l&#8217;arcano <a href="http://cpansearch.perl.org/src/XSAWYERX/Module-Starter-1.58/getting-started.html">qui</a>.</p>
<blockquote><p>.cvsignore</p>
<p>    Module::Starter assumes you&#8217;ll be using CVS for revision control, and provides a .cvsignore file with the names of files that are auto-generated and not to be tracked with revision control. At Perl Training Australia we use git for new projects, and so we rename this to .gitignore.</p>
<p>    <em>(As of version 1.52, this file is now called &#8220;ignores.txt&#8221;, so you can use it however you like.)</em>
</p></blockquote>
]]></content:encoded>
			<wfw:commentRss>http://www.simotrone.it/2011/10/06/module-builderz/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Coerce e DateTime::Format::ISO8601</title>
		<link>http://www.simotrone.it/2011/09/30/coerce-e-datetimeformatiso8601/</link>
		<comments>http://www.simotrone.it/2011/09/30/coerce-e-datetimeformatiso8601/#comments</comments>
		<pubDate>Fri, 30 Sep 2011 05:58:00 +0000</pubDate>
		<dc:creator>Simotrone</dc:creator>
				<category><![CDATA[Binary People]]></category>
		<category><![CDATA[coerce]]></category>
		<category><![CDATA[moose]]></category>
		<category><![CDATA[Mouse]]></category>
		<category><![CDATA[OOP]]></category>
		<category><![CDATA[Perl]]></category>

		<guid isPermaLink="false">http://www.simotrone.it/?p=3541</guid>
		<description><![CDATA[In Moose (e sistemi derivati &#8211; Mouse) si può fissare un tipo di dato per attributo (isa). has &#8216;points&#8217; &#160; =&#62; &#40; isa =&#62; &#8216;Int&#8217;, is =&#62; &#8216;rw&#8217;, default =&#62; 0 &#41;; # points deve essere (is a) un Int(ero) Questo controllo può diventare rognoso se il tipo di attributo è complesso: ad esempio DateTime. [...]]]></description>
			<content:encoded><![CDATA[<p>In <a href="https://metacpan.org/module/Moose">Moose</a> (e sistemi derivati &#8211; <a href="https://metacpan.org/module/Mouse">Mouse</a>) si può fissare un tipo di dato per attributo (<strong>isa</strong>).</p>
<div class="codesnip-container" >
<div class="codesnip" style="font-family: monospace;">has <span class="st0">&#8216;points&#8217;</span> &nbsp; =&gt; <span class="br0">&#40;</span> isa =&gt; <span class="st0">&#8216;Int&#8217;</span>, is =&gt; <span class="st0">&#8216;rw&#8217;</span>, default =&gt; <span class="nu0">0</span> <span class="br0">&#41;</span>;<br />
<span class="co1"># points deve essere (is a) un Int(ero)</span></div>
</div>
<p>Questo controllo può diventare rognoso se il tipo di attributo è complesso: ad esempio <a href="http://search.cpan.org/~drolsky/DateTime-0.70/lib/DateTime.pm">DateTime</a>.</p>
<p>Può capitare di dover inserire nell&#8217;attributo un oggetto DateTime che rappresenta una data ed un tempo, ma come posso inserire il dato direttamente senza calcolare l&#8217;oggetto (ad esempio in lettura da un file)?<br />
Qui entrano in gioco coerce, subtype, ecc.</p>
<div class="codesnip-container" >
<div class="codesnip" style="font-family: monospace;">subtype <span class="st0">&#8216;My::DateTime&#8217;</span> =&gt; as <span class="st0">&#8216;Object&#8217;</span> =&gt; where <span class="br0">&#123;</span> <span class="re0">$_</span>-&gt;<span class="me1">isa</span><span class="br0">&#40;</span><span class="st0">&#8216;DateTime&#8217;</span><span class="br0">&#41;</span> <span class="br0">&#125;</span>;</p>
<p>has <span class="st0">&#8216;datetime&#8217;</span> =&gt; <span class="br0">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; isa =&gt; <span class="st0">&#8216;My::DateTime&#8217;</span>, is =&gt; <span class="st0">&#8216;rw&#8217;</span>, required =&gt; <span class="nu0">1</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; default =&gt; <span class="kw2">sub</span> <span class="br0">&#123;</span> DateTime-&gt;<span class="me1">now</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#125;</span><br />
<span class="br0">&#41;</span>;</div>
</div>
<p>Questo attributo deve essere un DateTime (per l&#8217;esattezza un My::DateTime, ma questo serve solo per non inquinare i namespace in cui lavora Perl), ma vuole gli vengano passati solo oggetti DateTime.<br />
Nel caso decidessi di passare un numero intero all&#8217;attributo <strong>datetime</strong> (es: <strong>$self->datetime(1)</strong>) intendendendo <a href="http://en.wikipedia.org/wiki/Unix_time">unix time</a> l&#8217;isa genererebbe un errore; comportamento identico se passassi una stringa come &#8220;2004-09-16T23:59:58&#8243;.</p>
<p>Grazie alla proprietà <strong>coerce</strong> è possibile &#8220;costringere&#8221; un dato in entrata a traformarsi in DateTime anche se parte come qualcosa di diverso.</p>
<div class="codesnip-container" >
<div class="codesnip" style="font-family: monospace;">subtype <span class="st0">&#8216;My::DateTime&#8217;</span> =&gt; as <span class="st0">&#8216;Object&#8217;</span> =&gt; where <span class="br0">&#123;</span> <span class="re0">$_</span>-&gt;<span class="me1">isa</span><span class="br0">&#40;</span><span class="st0">&#8216;DateTime&#8217;</span><span class="br0">&#41;</span> <span class="br0">&#125;</span>;</p>
<p>coerce <span class="st0">&#8216;My::DateTime&#8217;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; =&gt; from <span class="st0">&#8216;Num&#8217;</span> =&gt; via <span class="br0">&#123;</span> DateTime-&gt;<span class="me1">from_epoch</span><span class="br0">&#40;</span> epoch =&gt; <span class="re0">$_</span> <span class="br0">&#41;</span> <span class="br0">&#125;</span> <br />
&nbsp; &nbsp; &nbsp; &nbsp; =&gt; from <span class="st0">&#8216;Str&#8217;</span> =&gt; via <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">my</span> <span class="br0">&#40;</span><span class="re0">$Y</span>,<span class="re0">$M</span>,<span class="re0">$D</span>,<span class="re0">$h</span>,<span class="re0">$m</span>,<span class="re0">$s</span><span class="br0">&#41;</span> = <a href="http://perldoc.perl.org/functions/uc.html"><span class="kw3">uc</span></a><span class="br0">&#40;</span><span class="re0">$_</span><span class="br0">&#41;</span> =~ <a href="http://perldoc.perl.org/functions/m.html"><span class="kw3">m</span></a>/^<span class="br0">&#40;</span>\d<span class="br0">&#123;</span><span class="nu0">4</span><span class="br0">&#125;</span><span class="br0">&#41;</span>-<span class="br0">&#40;</span>\d<span class="br0">&#123;</span><span class="nu0">2</span><span class="br0">&#125;</span><span class="br0">&#41;</span>-<span class="br0">&#40;</span>\d<span class="br0">&#123;</span><span class="nu0">2</span><span class="br0">&#125;</span><span class="br0">&#41;</span>T<span class="br0">&#40;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <a href="http://perldoc.perl.org/functions/return.html"><span class="kw3">return</span></a> DateTime-&gt;<span class="me1">new</span><span class="br0">&#40;</span> year =&gt; <span class="re0">$Y</span>, month =&gt; <span class="re0">$M</span>, day =&gt; <span class="re0">$D</span>, hour ;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>;</p>
<p>has <span class="st0">&#8216;datetime&#8217;</span> =&gt; <span class="br0">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; isa =&gt; <span class="st0">&#8216;My::DateTime&#8217;</span>, is =&gt; <span class="st0">&#8216;rw&#8217;</span>, required =&gt; <span class="nu0">1</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; coerce =&gt; <span class="nu0">1</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; default =&gt; <span class="kw2">sub</span> <span class="br0">&#123;</span> DateTime-&gt;<span class="me1">now</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#125;</span><br />
<span class="br0">&#41;</span>;</div>
</div>
<p>In questo caso abbiamo definito due trasformazioni: in caso l&#8217;input sia un &#8216;Num&#8217;, esegui DateTime->from_epoch( epoch => $_ ); in caso sia una stringa passa il valore attraverso quella regex e ritorna un oggetto DateTime.</p>
<p>La cosa funzionava&#8230; poi mi è stato indicato <a href="http://search.cpan.org/~jhoblitt/DateTime-Format-ISO8601-0.07/lib/DateTime/Format/ISO8601.pod">DateTime::Format::ISO8601</a>. Troppo bello.</p>
<div class="codesnip-container" >
<div class="codesnip" style="font-family: monospace;">subtype <span class="st0">&#8216;My::DateTime&#8217;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; =&gt; as <span class="st0">&#8216;Object&#8217;</span> =&gt; where <span class="br0">&#123;</span> <span class="re0">$_</span>-&gt;<span class="me1">isa</span><span class="br0">&#40;</span><span class="st0">&#8216;DateTime&#8217;</span><span class="br0">&#41;</span> <span class="br0">&#125;</span>;<br />
coerce <span class="st0">&#8216;My::DateTime&#8217;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; =&gt; from <span class="st0">&#8216;Num&#8217;</span> =&gt; via <span class="br0">&#123;</span> DateTime-&gt;<span class="me1">from_epoch</span><span class="br0">&#40;</span>epoch =&gt; <span class="re0">$_</span><span class="br0">&#41;</span> <span class="br0">&#125;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; =&gt; from <span class="st0">&#8216;Str&#8217;</span> =&gt; via <span class="br0">&#123;</span> DateTime::<span class="me2">Format</span>::<span class="me2">ISO8601</span>-&gt;<span class="me1">parse_datetime</span><span class="br0">&#40;</span><span class="re0">$_</span><span class="br0">&#41;</span> <span class="br0">&#125;</span>;</p>
<p>has <span class="st0">&#8216;datetime&#8217;</span> =&gt; <span class="br0">&#40;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; isa =&gt; <span class="st0">&#8216;My::DateTime&#8217;</span>, is =&gt; <span class="st0">&#8216;rw&#8217;</span>, required =&gt; <span class="nu0">1</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; coerce =&gt; <span class="nu0">1</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; default =&gt; <span class="kw2">sub</span> <span class="br0">&#123;</span> DateTime-&gt;<span class="me1">now</span><span class="br0">&#40;</span><span class="br0">&#41;</span> <span class="br0">&#125;</span><br />
<span class="br0">&#41;</span>;</div>
</div>
<p>Facile, sintetico&#8230; elegante.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.simotrone.it/2011/09/30/coerce-e-datetimeformatiso8601/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>HTTP::Message</title>
		<link>http://www.simotrone.it/2011/09/20/httpmessage/</link>
		<comments>http://www.simotrone.it/2011/09/20/httpmessage/#comments</comments>
		<pubDate>Tue, 20 Sep 2011 05:31:44 +0000</pubDate>
		<dc:creator>Simotrone</dc:creator>
				<category><![CDATA[Binary People]]></category>
		<category><![CDATA[cookie]]></category>
		<category><![CDATA[header]]></category>
		<category><![CDATA[lwp]]></category>
		<category><![CDATA[Perl]]></category>
		<category><![CDATA[Web]]></category>

		<guid isPermaLink="false">http://www.simotrone.it/?p=3520</guid>
		<description><![CDATA[Pistolando con LWP e qualche chiamata HTTP, avevo bisogno di rendermi conto che cosa mi stesse passando il server. Ho trovato estremamente utile a scopo di debugging il metodo headers_as_string proprio della risposta (HTTP::Response) che lo eredita da HTTP::Message. Direi che è l&#8217;equivalente del flag -e di lwp-request. sim@idrogeno:~$ lwp-request -dsUe www.google.com GET http://www.google.it/ User-Agent: [...]]]></description>
			<content:encoded><![CDATA[<p>Pistolando con <a href="http://search.cpan.org/~gaas/libwww-perl-6.02/lib/LWP.pm">LWP</a> e qualche chiamata HTTP, avevo bisogno di rendermi conto che cosa mi stesse passando il server.</p>
<p>Ho trovato estremamente utile a scopo di debugging il metodo <strong>headers_as_string</strong> proprio della risposta (HTTP::Response) che lo eredita da <strong>HTTP::Message</strong>.</p>
<p>Direi che è l&#8217;equivalente del flag <strong>-e</strong> di <a href="http://linux.die.net/man/1/lwp-request">lwp-request</a>.</p>
<div class="codesnip-container" >
<div class="codesnip" style="font-family: monospace;">sim@idrogeno:~$ lwp-request -dsUe www.google.com<br />
GET http://www.google.it/<br />
User-Agent: lwp-request/<span class="nu0">5.827</span> libwww-<span class="kw2">perl</span>/<span class="nu0">6.02</span></p>
<p><span class="nu0">200</span> OK<br />
Cache-Control: private, max-<span class="re2">age=</span><span class="nu0">0</span><br />
Connection: close<br />
Date: Sun, <span class="nu0">18</span> Sep <span class="nu0">2011</span> <span class="nu0">13</span>:<span class="nu0">39</span>:<span class="nu0">47</span> GMT<br />
Server: gws<br />
Content-Type: text/html; <span class="re2">charset=</span>ISO<span class="nu0">-8859</span><span class="nu0">-1</span><br />
Expires: <span class="nu0">-1</span><br />
Client-Date: Sun, <span class="nu0">18</span> Sep <span class="nu0">2011</span> <span class="nu0">13</span>:<span class="nu0">39</span>:<span class="nu0">47</span> GMT<br />
Client-Peer: <span class="nu0">209.85</span><span class="nu0">.148</span><span class="nu0">.105</span>:<span class="nu0">80</span><br />
Client-Response-Num: <span class="nu0">1</span><br />
Set-Cookie: we_have_cookies; <span class="re2">expires=</span>Tue, <span class="nu0">17</span>-Sep<span class="nu0">-2013</span> <span class="nu0">13</span>:<span class="nu0">39</span>:<span class="nu0">47</span> GMT; <span class="re2">path=</span>/; <span class="re2">domain=</span>.google.it<br />
Set-Cookie: we_have_a_lot_of_cookies!; <span class="re2">expires=</span>Mon, <span class="nu0">19</span>-Mar<span class="nu0">-2012</span> <span class="nu0">13</span>:<span class="nu0">39</span>:<span class="nu0">47</span> GMT; <span class="re2">path=</span>/; <span class="re2">domain=</span>.google.it; HttpOnly<br />
Title: Google<br />
X-XSS-Protection: <span class="nu0">1</span>; <span class="re2">mode=</span>block</div>
</div>
<p>Cool. <img src='http://www.simotrone.it/wp-includes/images/smilies/icon_cool.gif' alt='8)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://www.simotrone.it/2011/09/20/httpmessage/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Stream parser e subclassing</title>
		<link>http://www.simotrone.it/2011/09/10/stream-parser-e-subclassing/</link>
		<comments>http://www.simotrone.it/2011/09/10/stream-parser-e-subclassing/#comments</comments>
		<pubDate>Sat, 10 Sep 2011 05:25:28 +0000</pubDate>
		<dc:creator>Simotrone</dc:creator>
				<category><![CDATA[Binary People]]></category>
		<category><![CDATA[Perl]]></category>
		<category><![CDATA[subclassing]]></category>
		<category><![CDATA[XML::Parser]]></category>
		<category><![CDATA[XML::Parser::Expat]]></category>

		<guid isPermaLink="false">http://www.simotrone.it/?p=3500</guid>
		<description><![CDATA[Dovendo fare il parsing di un XML ho deciso di cambiare libreria e provare qualcosa di nuovo. Fino ad ora ho sempre usato XML::LibXML che mette in memoria una mappa dell&#8217;XML e poi permette di navigarci dentro (DOM). XML::Parser è uno stream parser che si basa su Expat: l&#8217;idea di Expat è avere un puntatore [...]]]></description>
			<content:encoded><![CDATA[<p>Dovendo fare il parsing di un XML ho deciso di cambiare libreria e provare qualcosa di nuovo.</p>
<p>Fino ad ora ho sempre usato <a href="http://search.cpan.org/~shlomif/XML-LibXML-1.87/LibXML.pod">XML::LibXML</a> che mette in memoria una mappa dell&#8217;XML e poi permette di navigarci dentro (DOM).</p>
<p><a href="http://search.cpan.org/~toddr/XML-Parser-2.41/Parser.pm">XML::Parser</a> è uno stream parser che si basa su <a href="http://expat.sourceforge.net/">Expat</a>: l&#8217;idea di Expat è avere un puntatore che scorre lungo lo stream xml e rileva eventi specifici (es: la presenza di un tag di apertura) a cui corrispondono delle funzioni che devono elaborare; a queste <em>callback</em> vengono passati determinati parametri (es: un&#8217;istanza del parser expat, l&#8217;elemento, gli attributi).</p>
<p>La mia implementazione in Perl era dentro un oggetto:</p>
<div class="codesnip-container" >
<div class="codesnip" style="font-family: monospace;"><a href="http://perldoc.perl.org/functions/package.html"><span class="kw3">package</span></a> Oggetto;<br />
&#8230;<br />
<span class="kw2">sub</span> <a href="http://perldoc.perl.org/functions/read.html"><span class="kw3">read</span></a> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">my</span> <span class="re0">$self</span> = <a href="http://perldoc.perl.org/functions/shift.html"><span class="kw3">shift</span></a>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">my</span> <span class="re0">$input</span> = <span class="re0">$self</span>-&gt;<span class="me1">filepath</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">my</span> <span class="re0">$sb</span> = <span class="re0">$self</span>-&gt;<span class="me1">scoreboard</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$parser</span> = XML::<span class="me2">Parser</span>-&gt;<span class="me1">new</span><span class="br0">&#40;</span> Handlers =&gt; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Start =&gt; \&amp;handle_start,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; End &nbsp; =&gt; \&amp;handle_end,<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$parser</span>-&gt;<span class="me1">parse</span><span class="br0">&#40;</span><span class="re0">$input</span><span class="br0">&#41;</span>;<br />
<span class="br0">&#125;</span><br />
<span class="kw2">sub</span> handle_start <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">my</span> <span class="br0">&#40;</span> <span class="re0">$parser</span>, <span class="re0">$element</span>, <span class="re0">%attributes</span> <span class="br0">&#41;</span> = <span class="re0">@_</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1"># fai qualcosa&#8230;</span><br />
<span class="br0">&#125;</span><br />
&#8230;</div>
</div>
<p>e il mio problema principale era come passare un&#8217;istanza del mio oggetto alla funzione di callback in modo da avere gli attributi a disposizione della funzione stessa &#8211; nello specifico mi interessava avere $self->scoreboard che doveva essere popolato con gli elementi nell&#8217;xml.</p>
<h3>Soluzione #1</h3>
<p>Nello scope della funzione in cui coesistono sia l&#8217;istanza del parser che del mio oggetto (sub read {}) creare una sub anonima e passare il coderef all&#8217;opzione Handlers del parser.</p>
<div class="codesnip-container" >
<div class="codesnip" style="font-family: monospace;"><span class="kw2">sub</span> <a href="http://perldoc.perl.org/functions/read.html"><span class="kw3">read</span></a> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">my</span> <span class="re0">$self</span> = <a href="http://perldoc.perl.org/functions/shift.html"><span class="kw3">shift</span></a>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">my</span> <span class="re0">$input</span> = <span class="re0">$self</span>-&gt;<span class="me1">filepath</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">my</span> <span class="re0">$sb</span> = <span class="re0">$self</span>-&gt;<span class="me1">scoreboard</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">my</span> <span class="re0">$handle_start</span> = <span class="kw2">sub</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">my</span> <span class="br0">&#40;</span> <span class="re0">$parser</span>, <span class="re0">$element</span>, <span class="re0">%attributes</span> <span class="br0">&#41;</span> = <span class="re0">@_</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1"># fai qualcosa&#8230;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1"># qui dentro $self è vivo quindi $sb è raggiungibile</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$parser</span> = XML::<span class="me2">Parser</span>-&gt;<span class="me1">new</span><span class="br0">&#40;</span> Handlers =&gt; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Start =&gt; <span class="re0">$handle_start</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$parser</span>-&gt;<span class="me1">parse</span><span class="br0">&#40;</span><span class="re0">$input</span><span class="br0">&#41;</span>;<br />
<span class="br0">&#125;</span></div>
</div>
<p>La cosa funziona ed è anche abbastanza chiara per i miei gusti, ma mi piaceva poco l&#8217;idea di avere una sub corposa scritta dentro un metodo&#8230; preferisco quando le sub anonime sono più brevi.</p>
<h3>Soluzione #2 (Subclassing!)</h3>
<p>Un&#8217;altro sistema può essere subclassare il parser e far sì che abbia a disposizione gli oggetti che mi servono ($sb).</p>
<p>Qui il trucco è subclassare non XML::Parser (che passa una istanza di Expat alla callback) ma XML::Parser::Expat stesso; nella copia locale scrivo due metodi per fare set and get di un attributo che il parser si porterà dietro in ogni sua istanza.</p>
<div class="codesnip-container" >
<div class="codesnip" style="font-family: monospace;"><a href="http://perldoc.perl.org/functions/package.html"><span class="kw3">package</span></a> Local::<span class="me2">XML</span>::<span class="me2">Parser</span>::<span class="me2">Expat</span>;<br />
<span class="co1"># subclassing</span><br />
<span class="kw2">use</span> base XML::<span class="me2">Parser</span>::<span class="me2">Expat</span>;<br />
<span class="co1"># set</span><br />
<span class="kw2">sub</span> set_current_object <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">my</span><span class="br0">&#40;</span><span class="re0">$self</span>, obj<span class="br0">&#41;</span> = <span class="re0">@_</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$self</span>-&gt;<span class="br0">&#123;</span>_current_object<span class="br0">&#125;</span> = <span class="re0">$obj</span>;<br />
<span class="br0">&#125;</span><br />
<span class="co1"># get</span><br />
<span class="kw2">sub</span> get_current_object <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">my</span><span class="br0">&#40;</span><span class="re0">$self</span><span class="br0">&#41;</span> = <span class="re0">@_</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <a href="http://perldoc.perl.org/functions/return.html"><span class="kw3">return</span></a> <span class="re0">$self</span>-&gt;<span class="br0">&#123;</span>_current_object<span class="br0">&#125;</span>;<br />
<span class="br0">&#125;</span><br />
<span class="nu0">1</span>;<br />
<span class="co1">#</span><br />
<a href="http://perldoc.perl.org/functions/package.html"><span class="kw3">package</span></a> Oggetto;<br />
<span class="kw2">use</span> Local::<span class="me2">XML</span>::<span class="me2">Parser</span>::<span class="me2">Expat</span>;<br />
&#8230;<br />
<span class="kw2">sub</span> <a href="http://perldoc.perl.org/functions/read.html"><span class="kw3">read</span></a> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">my</span> <span class="re0">$self</span> = <a href="http://perldoc.perl.org/functions/shift.html"><span class="kw3">shift</span></a>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">my</span> <span class="re0">$input</span> = <span class="re0">$self</span>-&gt;<span class="me1">filepath</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">my</span> <span class="re0">$sb</span> = <span class="re0">$self</span>-&gt;<span class="me1">scoreboard</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$parser</span> = Local::<span class="me2">XML</span>::<span class="me2">Parser</span>::<span class="me2">Expat</span>-&gt;<span class="me1">new</span><span class="br0">&#40;</span> Handlers =&gt; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Start =&gt; \&amp;handle_start,<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; End &nbsp; =&gt; \&amp;handle_end,<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$parser</span>-&gt;<span class="me1">set_current_object</span><span class="br0">&#40;</span><span class="re0">$sb</span><span class="br0">&#41;</span>; <span class="co1"># set dell&#8217;attributo</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$parser</span>-&gt;<span class="me1">parse</span><span class="br0">&#40;</span><span class="re0">$input</span><span class="br0">&#41;</span>;<br />
<span class="br0">&#125;</span><br />
<span class="kw2">sub</span> handle_start <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">my</span> <span class="br0">&#40;</span> <span class="re0">$parser</span>, <span class="re0">$element</span>, <span class="re0">%attributes</span> <span class="br0">&#41;</span> = <span class="re0">@_</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1"># fai qualcosa&#8230;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1"># e qui dentro è possibile fare</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1"># $parser-&gt;get_current_object()</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1"># per ottenere $sb </span><br />
<span class="br0">&#125;</span><br />
&#8230;</div>
</div>
<p>Questa è una soluzione che mi piace molto ma richiede di complicare il progetto con un nuovo package che sostanzialmente non fa niente &#8211; inoltre richiede di scavalcare XML::Parser e usare direttamente Expat.</p>
<h3>Soluzione #3</h3>
<p>Un&#8217;altra soluzione è simile alla prima, ma con un passaggio in più nella sub anonima per tenere ordinate le cose.</p>
<div class="codesnip-container" >
<div class="codesnip" style="font-family: monospace;"><span class="kw2">sub</span> <a href="http://perldoc.perl.org/functions/read.html"><span class="kw3">read</span></a> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">my</span> <span class="re0">$self</span> = <a href="http://perldoc.perl.org/functions/shift.html"><span class="kw3">shift</span></a>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">my</span> <span class="re0">$input</span> = <span class="re0">$self</span>-&gt;<span class="me1">filepath</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">my</span> <span class="re0">$sb</span> = <span class="re0">$self</span>-&gt;<span class="me1">scoreboard</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$parser</span> = XML::<span class="me2">Parser</span>-&gt;<span class="me1">new</span><span class="br0">&#40;</span> Handlers =&gt; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Start =&gt; <span class="kw2">sub</span> <span class="br0">&#123;</span> <span class="re0">$self</span>-&gt;_handle_start<span class="br0">&#40;</span><span class="re0">@_</span><span class="br0">&#41;</span> <span class="br0">&#125;</span>,<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$parser</span>-&gt;<span class="me1">parse</span><span class="br0">&#40;</span><span class="re0">$input</span><span class="br0">&#41;</span>;<br />
<span class="br0">&#125;</span><br />
<span class="kw2">sub</span> _handle_start <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">my</span> <span class="br0">&#40;</span> <span class="re0">$self</span>, <span class="re0">$parser</span>, <span class="re0">$element</span>, <span class="re0">%attributes</span> <span class="br0">&#41;</span> = <span class="re0">@_</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1"># fai qualcosa&#8230;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="co1"># qui dentro $self è vivo quindi $sb è raggiungibile</span><br />
<span class="br0">&#125;</span></div>
</div>
<p>Questo sistema mi piace abbastanza: ha il vantaggio che la sub anonima è breve e c&#8217;è un riferimento chiaro ad un metodo interno all&#8217;oggetto.<br />
L&#8217;unica cosa che mi piace pochino è il passaggio degli elementi nella sub anonima che a mio avviso è poco evidente, d&#8217;altra parte se dentro la sub anonima dovessi esplicitare</p>
<div class="codesnip-container" >
<div class="codesnip" style="font-family: monospace;">Handlers =&gt; <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; Start =&gt; <span class="kw2">sub</span> <span class="br0">&#123;</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="kw1">my</span> <span class="br0">&#40;</span><span class="re0">$parser</span>, <span class="re0">$elem</span>, <span class="re0">%attrs</span><span class="br0">&#41;</span> = <span class="re0">@_</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="re0">$self</span>-&gt;_handle_start<span class="br0">&#40;</span> <span class="re0">$parser</span>, <span class="re0">$elem</span>, <span class="re0">%attrs</span><span class="br0">&#41;</span>;<br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1"># oppure la chiamata diretta ad una sub se si preferisce</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span class="co1"># _handle_start( $self, $parser, $elem, %attrs);</span><br />
&nbsp; &nbsp; &nbsp; &nbsp; <span class="br0">&#125;</span>,<br />
<span class="br0">&#125;</span></div>
</div>
<p>perderei la brevità.</p>
<p>Ringraziamenti a larsen, dada, dakkar per il confronto a riguardo. <img src='http://www.simotrone.it/wp-includes/images/smilies/icon_biggrin.gif' alt=':-D' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://www.simotrone.it/2011/09/10/stream-parser-e-subclassing/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

