<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <title>Wolfgang Kinkeldei</title>
    <link rel="alternate" type="text/html" href="http://blogs.perl.org/users/wolfgang_kinkeldei/" />
    <link rel="self" type="application/atom+xml" href="http://blogs.perl.org/users/wolfgang_kinkeldei/atom.xml" />
    <id>tag:blogs.perl.org,2009-11-03:/users/wolfgang_kinkeldei//473</id>
    <updated>2013-04-23T09:44:04Z</updated>
    <subtitle>A blog about the Perl programming language</subtitle>
    <generator uri="http://www.sixapart.com/movabletype/">Movable Type Pro 4.38</generator>

<entry>
    <title>Pinto::Remote and Pinto::Server</title>
    <link rel="alternate" type="text/html" href="http://blogs.perl.org/users/wolfgang_kinkeldei/2013/04/pintoremote-and-pintoserver.html" />
    <id>tag:blogs.perl.org,2013:/users/wolfgang_kinkeldei//473.4598</id>

    <published>2013-04-22T18:07:49Z</published>
    <updated>2013-04-23T09:44:04Z</updated>

    <summary>Today I was glad to read that the successful merge of Pinto::Remote and Pinto::Server into its main Pinto repository made Pinto::Remote work again. I wanted to know how difficult a setup of a Pinto server could become. The requirement behind...</summary>
    <author>
        <name>Wolfgang Kinkeldei</name>
        
    </author>
    
    <category term="cpan" label="cpan" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="perl" label="perl" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="pinto" label="pinto" scheme="http://www.sixapart.com/ns/types#tag" />
    <category term="repository" label="repository" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://blogs.perl.org/users/wolfgang_kinkeldei/">
        <![CDATA[<p>Today I was glad to read that the successful merge of Pinto::Remote and Pinto::Server into its main <a href="https://metacpan.org/module/THALJEF/Pinto-0.079_01/lib/Pinto.pm">Pinto</a> repository made Pinto::Remote work again.</p>

<p>I wanted to know how difficult a setup of a Pinto server could become. The requirement behind was to access a single cpan-like repository for deploying server machines. The repository should contain company-provided distributions optionally combined with a collection of cpan-available distributions.</p>
]]>
        <![CDATA[<p>Installing perl-modules on a server should be as simple as</p>

<pre><code>cpanm --mirror http://myrepo-server.de:port --installdeps .
</code></pre>

<p>If we had a cpan-like repository (possibly created using Pinto) somewhere we could run a simple PSGI application on the repo server</p>

<pre><code>plackup -M Plack::App::File \
    -e 'Plack::App::File-&gt;new(root =&gt; "/path/to/repo")-&gt;to_app'
</code></pre>

<p>and we are ready to go, if we had the repository filled.</p>

<p>Filling a repository sitting in a given directory on a certain machine using remote shell commands is not very comfortable but this is where <a href="https://metacpan.org/module/THALJEF/Pinto-0.079_01/bin/pintod">pintod</a> comes into play. Accessing our repository for reading without authentication is OK, but adding distributions to the repository should be password-protected. Not really a problem.</p>

<p>First, a repository has to get created on the remote machine.</p>

<pre><code>pinto -r /path/to/repo init
</code></pre>

<p>Then, we need a way to authenticate. I chose the option to use <a href="https://metacpan.org/module/Authen::Simple::Passwd">simple password authentication</a>. The preparation of passwords could look like this:</p>

<pre><code>htpasswd -c /path/to/htpasswd user
</code></pre>

<p>Now we are ready to launch the pinto daemon (for demonstration purpose not deamonized)</p>

<pre><code>pintod --root=/path/to/repo --port 5555 --auth backend=Passwd --auth path=/path/to/htpasswd
</code></pre>

<p>Back on the developer's machine, we can now query or fill the remote repository. Setting the PINTO<em>REPOSITORY</em>ROOT environment makes things easier, otherwise the "-r" option is required at every pinto command.</p>

<pre><code>export PINTO_REPOSITORY_ROOT=http://user:secret@myrepo-server.de:5555
pinto list
pinto add --author SOMEBODY /path/to/dist-0.01.tar.gz
</code></pre>

<p>Dear admin at $work, I would like to get a VM for our pinto-server tomorrow :-)</p>
]]>
    </content>
</entry>

<entry>
    <title>Simple Singleton in a few lines</title>
    <link rel="alternate" type="text/html" href="http://blogs.perl.org/users/wolfgang_kinkeldei/2012/09/simple-singleton-in-a-few-lines.html" />
    <id>tag:blogs.perl.org,2012:/users/wolfgang_kinkeldei//473.3782</id>

    <published>2012-09-03T21:30:46Z</published>
    <updated>2012-09-03T21:41:53Z</updated>

    <summary>The other day I was working on a library which needed to have a small list of dependencies and guaranteed to run on Perl versions 5.10 and above. In order to keep the dependencies minimal I decided to code a...</summary>
    <author>
        <name>Wolfgang Kinkeldei</name>
        
    </author>
    
    <category term="moomoosesingleton" label="Moo Moose Singleton" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://blogs.perl.org/users/wolfgang_kinkeldei/">
        <![CDATA[<p>The other day I was working on a library which needed to have a small list of dependencies and guaranteed to run on Perl versions 5.10 and above. In order to keep the dependencies minimal I decided to code a <code>singleton()</code> method like this:</p>

<pre><code>sub instance {
    my $class = shift;
    state $self = $class-&gt;new(@_);

    return $self;
}
</code></pre>

<p>Just to get me right. This is not a complain to Moo*X::Singleton modules. The snippet above is very primitive, does not provide a separate initialization and has no way of clearing an instance. But sometimes this simplicity might do its job.</p>
]]>
        

    </content>
</entry>

<entry>
    <title>Create PDF from many POD files</title>
    <link rel="alternate" type="text/html" href="http://blogs.perl.org/users/wolfgang_kinkeldei/2012/04/create-pdf-from-many-pod-files.html" />
    <id>tag:blogs.perl.org,2012:/users/wolfgang_kinkeldei//473.3025</id>

    <published>2012-04-02T18:38:33Z</published>
    <updated>2012-04-02T18:49:50Z</updated>

    <summary>Using POD as the basis of documentation for Perl projects is the usual way to do. There are many modules available to convert POD into several formats. However, I was not able to find a module that creates a single...</summary>
    <author>
        <name>Wolfgang Kinkeldei</name>
        
    </author>
    
    <category term="pdf" label="pdf" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://blogs.perl.org/users/wolfgang_kinkeldei/">
        <![CDATA[<p>Using POD as the basis of documentation for Perl projects is the usual way to do. There are many modules available to convert POD into several formats. However, I was not able to find a module that creates a single PDF file from all the documentation available for e.g. a single project. Typically a series of PDF files are the result of a conversion. Combining these files and creating a hierarchical outline can be hard work.</p>

<p>As a simple aid, we peeked into <a href="https://metacpan.org/release/pod2pdf">pod2pdf</a> and wrote a little wrapper around it in order to handle many files and create the outline. Well, this solution is not rock solid, as we rely on its internals but at least it is short and usually creating PDFs is not mission-critical.</p>

<p>Maybe some parts can still be improved, but for people interested, here is my first try: <a href="https://gist.github.com/2277444">https://gist.github.com/2277444</a>. Feedback welcome!</p>
]]>
        

    </content>
</entry>

<entry>
    <title>Be nice to your speakers</title>
    <link rel="alternate" type="text/html" href="http://blogs.perl.org/users/wolfgang_kinkeldei/2012/03/be-nice-to-your-speakers.html" />
    <id>tag:blogs.perl.org,2012:/users/wolfgang_kinkeldei//473.2908</id>

    <published>2012-03-07T08:06:54Z</published>
    <updated>2012-03-07T08:20:26Z</updated>

    <summary>This year we decided not to disturb our speakers on the german perl workshop during their talks to tell them the time remaining. Instead, we printed simple tags in different colors with a short meaningful text on it. As far...</summary>
    <author>
        <name>Wolfgang Kinkeldei</name>
        
    </author>
    
    <category term="perlworkshop" label="Perl Workshop" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://blogs.perl.org/users/wolfgang_kinkeldei/">
        <![CDATA[<p>This year we decided not to disturb our speakers on the german perl workshop during their talks to tell them the time remaining. Instead, we printed simple tags in different colors with a short meaningful text on it. As far as we got feedback from our speakers, they liked it.</p>

<p><a href="http://blogs.perl.org/users/wolfgang_kinkeldei/assets_c/2012/03/Foto-747.html" onclick="window.open('http://blogs.perl.org/users/wolfgang_kinkeldei/assets_c/2012/03/Foto-747.html','popup','width=956,height=1412,scrollbars=no,resizable=no,toolbar=no,directories=no,location=no,menubar=no,status=no,left=0,top=0'); return false"><img src="http://blogs.perl.org/users/wolfgang_kinkeldei/assets_c/2012/03/Foto-thumb-300x443-747.jpg" width="300" height="443" alt="Smilies.jpg" class="mt-image-left" style="float: left; margin: 0 20px 20px 0;" /></a></p>
]]>
        

    </content>
</entry>

<entry>
    <title>Date arithmetic can be dangerous</title>
    <link rel="alternate" type="text/html" href="http://blogs.perl.org/users/wolfgang_kinkeldei/2012/02/date-arithmetic-can-be-dangerous.html" />
    <id>tag:blogs.perl.org,2012:/users/wolfgang_kinkeldei//473.2848</id>

    <published>2012-02-20T21:05:16Z</published>
    <updated>2012-02-20T21:51:05Z</updated>

    <summary>Every time I review code others have written, I blame people for doing date arithmetic of their own. However, some time ago, I received a pull request for a module that had some date arithmetic inside. As all tests passed,...</summary>
    <author>
        <name>Wolfgang Kinkeldei</name>
        
    </author>
    
    <category term="perldatetime" label="perl datetime" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://blogs.perl.org/users/wolfgang_kinkeldei/">
        <![CDATA[<p>Every time I review code others have written, I blame people for doing date arithmetic of their own. However, some time ago, I received a pull request for a module that had some date arithmetic inside. As all tests passed, I could not see something dangerous in it and followed the pull request. Today, I found the date tests failing. Why? Why today? Well, this is worth some investigation.</p>

<p>The main part of the module generates an HTTP-Header using this construct ($c is the mocked catalyst context, expire_in is a method containing the nr of seconds to expire in):</p>

<pre>
$c->response->headers->expires(time() + $self->expire_in)
    if ....some_condition...
</pre>

<p>Well, adding a number of seconds to an epoch value cannot hurt. Can it? The test looked like this:</p>

<pre>
my $expected_date =
    (DateTime->now 
     + DateTime::Duration->new(seconds => $controller->{expire_in}
    )->strftime('%a, %d %b %Y %H:%M:%S GMT');
is $c->response->header('expires'), $expected_date,
   'expired header date is OK';
</pre>

<p>For the test case having an expiry of 3 years, the test failed with a difference of exactly one second:</p>

<pre>
#   Failed test 'expired header date is OK'
#   at t/5-expire.t line 55.
#          got: 'Thu, 19 Feb 2015 18:27:59 GMT'
#     expected: 'Thu, 19 Feb 2015 18:27:58 GMT'
not ok 4 - expired header date is OK
</pre> 

<p>One second? Do we have a rounding problem? No. After a while, I remembered that <a href="https://metacpan.org/module/DateTime">DateTime</a> mentioned a leap-second in its <a href="https://metacpan.org/source/DROLSKY/DateTime-0.72/Changes">Change-Log</a> some time ago. This could explain our difference.</p>

<p>Doing time-calculations by ourselves is wrong. Replacing the header generation with a more complicated but correct construct worked. Using DateTime before 0.71 kept the old date arithmetic-tests working, but actually the tests should have failed, because the leap-second was ignored.</p>

<pre>
$c->response->headers->expires(
    DateTime->now
            ->add(seconds => $self->expire_in)
            ->epoch
)
</pre>

<p>My personal conclusion: Date arithmetic is dangerous. Be more strict to any kind of date arithmetic. Never ever do date-math again. Never. Instead: keep all date manipulating modules at a current version and trust in them. Their authors known what they are doing, I don't. I didn't :-(</p>
]]>
        

    </content>
</entry>

<entry>
    <title>Perl is faster than C -- can benchmarks get compared?</title>
    <link rel="alternate" type="text/html" href="http://blogs.perl.org/users/wolfgang_kinkeldei/2012/01/perl-is-faster-than-c----can-benchmarks-get-compared.html" />
    <id>tag:blogs.perl.org,2012:/users/wolfgang_kinkeldei//473.2749</id>

    <published>2012-01-30T18:17:22Z</published>
    <updated>2012-01-30T18:52:35Z</updated>

    <summary>Interpreting byte code can never be faster than native code. We all know. But two benchmarks generated in different programs might tell a different story. So I thought I should share my wisdom. Some days ago, I was experimenting with...</summary>
    <author>
        <name>Wolfgang Kinkeldei</name>
        
    </author>
    
    <category term="perldatabase" label="perl database" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://blogs.perl.org/users/wolfgang_kinkeldei/">
        <![CDATA[<p>Interpreting byte code can never be faster than native code. We all know. But two benchmarks generated in different programs might tell a different story. So I thought I should share my wisdom.</p>

<p>Some days ago, I was experimenting with the <a href="http://redis.io">Redis</a> noSQL Database in order to find an alternative to file based session storage for Catalyst web applications. Redis comes bundled with a benchmark tool <code>redis-benchmark</code> which reveals the speed of this database. On my Macbook I get these counts when benchmarking the database with single concurrency:</p>

<pre>
$ redis-benchmark -c 1 -n 10000
[...]
====== SET ======
  10000 requests completed in 0.50 seconds
  1 parallel clients
  3 bytes payload
  keep alive: 1

100.00% <= 0 milliseconds
20202.02 requests per second

====== GET ======
  10000 requests completed in 0.49 seconds
  1 parallel clients
  3 bytes payload
  keep alive: 1

100.00% <= 1 milliseconds
20408.16 requests per second
[...]
</pre>

<p>I wondered what the speed would be using Redis from Perl. I first checked the speed of <a href="https://metacpan.org/module/Redis">Redis.pm</a>, a very cool Perl binding. It offers lots of features, fully implements the protocol and is fast while still being a pure-perl library.</p>

<p>How fast could I go when sacrificing everything, Redis.pm does by simply doing network writes and reads on my own? Can I reach the C benchmark's speed? Well, Perl is even faster -- and I also use JSON::XS to encode a hash :-) At least my benchmark is telling me...</p>

<pre>
Benchmark: timing 10000 iterations of get_native, get_redis, set_native, set_redis...
get_native:  0 wallclock secs ( 0.23 usr +  0.13 sys =  0.36 CPU) @ 27777.78/s (n=10000)
            (warning: too few iterations for a reliable count)
 get_redis:  2 wallclock secs ( 0.95 usr +  0.20 sys =  1.15 CPU) @ 8695.65/s (n=10000)
set_native:  1 wallclock secs ( 0.20 usr +  0.14 sys =  0.34 CPU) @ 29411.76/s (n=10000)
            (warning: too few iterations for a reliable count)
 set_redis:  1 wallclock secs ( 0.82 usr +  0.21 sys =  1.03 CPU) @ 9708.74/s (n=10000)
              Rate  get_redis  set_redis get_native set_native
get_redis   8696/s         --       -10%       -69%       -70%
set_redis   9709/s        12%         --       -65%       -67%
get_native 27778/s       219%       186%         --        -6%
set_native 29412/s       238%       203%         6%         --
</pre>

<p>The full benchmark, also comparing JSON::XS versus YAML::XS and pure writes without any serialization can be found here: <a href="https://gist.github.com/1697936">https://gist.github.com/1697936</a></p>
]]>
        

    </content>
</entry>

<entry>
    <title>MetaCPAN Logo</title>
    <link rel="alternate" type="text/html" href="http://blogs.perl.org/users/wolfgang_kinkeldei/2012/01/metacpan-logo.html" />
    <id>tag:blogs.perl.org,2012:/users/wolfgang_kinkeldei//473.2668</id>

    <published>2012-01-11T19:55:56Z</published>
    <updated>2012-01-12T17:45:20Z</updated>

    <summary>very often, when I see a logo drawn by somebody else, I highly appreciate his or her work. Many logos are simple but very easy to remember and recognize. Graphics is not my business. Maybe I just made more than...</summary>
    <author>
        <name>Wolfgang Kinkeldei</name>
        
    </author>
    
    <category term="perlmetacpan" label="perl metacpan" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://blogs.perl.org/users/wolfgang_kinkeldei/">
        <![CDATA[<p>very often, when I see a logo drawn by somebody else, I highly appreciate his or her work. Many logos are simple but very easy to remember and recognize. Graphics is not my business. Maybe I just made more than 1000 graphical mistakes. However, my father-in-law when he was some 80 years old always used to say 'I am young and still can learn'. Here is my first graphical try (click to enlarge):</p>

<p><a href="http://blogs.perl.org/users/wolfgang_kinkeldei/wolfgang_kinkeldei_de-metacpan-16-120111.png"><img alt="wolfgang_kinkeldei_de-metacpan-16-120111.png" src="http://blogs.perl.org/users/wolfgang_kinkeldei/assets_c/2012/01/wolfgang_kinkeldei_de-metacpan-16-120111-thumb-100x42-715.png" width="100" height="42" class="mt-image-none" style="" /></a></p>

<p>Improved version:</p>

<p><a href="http://blogs.perl.org/users/wolfgang_kinkeldei/meta_cpan_kerned.png"><img alt="meta_cpan_kerned.png" src="http://blogs.perl.org/users/wolfgang_kinkeldei/assets_c/2012/01/meta_cpan_kerned-thumb-100x43-721.png" width="100" height="43" class="mt-image-none" style="" /></a></p>

<p>I hope it is not too bad. Otherwise I will have to wait until I reach a reasonable age :-)</p>
]]>
        

    </content>
</entry>

<entry>
    <title>Trying Marpa to parse CSS</title>
    <link rel="alternate" type="text/html" href="http://blogs.perl.org/users/wolfgang_kinkeldei/2011/12/trying-marpa-to-parse-css.html" />
    <id>tag:blogs.perl.org,2011:/users/wolfgang_kinkeldei//473.2603</id>

    <published>2011-12-22T19:45:03Z</published>
    <updated>2011-12-22T20:11:37Z</updated>

    <summary>Some days ago, Marpa::XS reached version 1.0. Jeffrey Kegler, Marpa&apos;s godfather already wrote a some blogs about the algorithm operating behind. In order to get a feeling on how to use Marpa, I decided to try it for parsing CSS....</summary>
    <author>
        <name>Wolfgang Kinkeldei</name>
        
    </author>
    
    <category term="perl" label="perl" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://blogs.perl.org/users/wolfgang_kinkeldei/">
        <![CDATA[<p>Some days ago, <a href="https://metacpan.org/module/Marpa::XS">Marpa::XS</a> reached version 1.0. Jeffrey Kegler, Marpa's godfather already wrote a some blogs about the algorithm operating behind.</p>

<p>In order to get a feeling on how to use Marpa, I decided to try it for parsing CSS. Thankfully, the official grammar for CSS is <a href="http://www.w3.org/TR/CSS2/grammar.html">available</a>. So I tried to become a friend of Marpa::XS. I was used to work with <a href="https://metacpan.org/module/Parse::RecDescent">Parse::RecDescent</a> in the past, so I could not imagine to get into trouble. However, using both modules is different. Parse::RecDescent handles the scanning process by itself and allows various shortcuts for repeating elements inside a grammar. Marpa on the other hand needs a separate scanner to feed it with tokens and only allows very simple grammar rules. Parse::RecDescent combines parser code and grammar rules in one string. Marpa keeps the grammar clean and calls action methods based on rules defined inside the grammar.</p>

<p>After figuring out how to write grammars and having coded a simple tokenizer I finally got a parser working. Maybe, some rules might need expansion because of erroneous white-space handling or other flaws, but the result impressed me. Defining the grammar as a data structure makes it very good readable. Getting action methods called for processing the parse results keeps code separate from the grammar which keeps the entire code readable.</p>

<p>What are the next steps? Maybe a compressor or a sass-like processor? Maybe.</p>

<p>My quick and dirty try can be seen <a href="https://gist.github.com/1511584">here</a>.</p>
]]>
        

    </content>
</entry>

<entry>
    <title>German talk about some perl tricks</title>
    <link rel="alternate" type="text/html" href="http://blogs.perl.org/users/wolfgang_kinkeldei/2011/11/german-talk-about-some-perl-tricks.html" />
    <id>tag:blogs.perl.org,2011:/users/wolfgang_kinkeldei//473.2480</id>

    <published>2011-11-22T19:50:04Z</published>
    <updated>2011-11-22T19:56:49Z</updated>

    <summary>Last weekend, a local group around Nuremberg had their annual convention, called the KNF Kongress. I talked about some collected tricks around using perl. The key points were perlbrew, cpanm, minicpan and Dist::Zilla. All slides (in german language) collected from...</summary>
    <author>
        <name>Wolfgang Kinkeldei</name>
        
    </author>
    
    <category term="perltricks" label="perl tricks" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://blogs.perl.org/users/wolfgang_kinkeldei/">
        <![CDATA[<p>Last weekend, a local group around Nuremberg had their annual convention, called the KNF Kongress. I talked about some collected tricks around using perl. The key points were perlbrew, cpanm, minicpan and Dist::Zilla. All slides (in german language) collected from the speakers are online now:</p>

<p><a href="http://www.franken.de/veranstaltungen/knf-kongress/2011">KNF Kongress 2011</a></p>
]]>
        

    </content>
</entry>

<entry>
    <title>German Perl Workshop day 3</title>
    <link rel="alternate" type="text/html" href="http://blogs.perl.org/users/wolfgang_kinkeldei/2011/10/german-perl-workshop-day-3.html" />
    <id>tag:blogs.perl.org,2011:/users/wolfgang_kinkeldei//473.2335</id>

    <published>2011-10-22T14:15:38Z</published>
    <updated>2011-10-22T14:25:36Z</updated>

    <summary>Yesterday was the last day of the german perl workshop. Denis Banovic started with a live demo demonstrating development and deployment of a dancer app in the &quot;Cloud&quot;. It looked very easy to do. Karl Gaissmaier was the next speaker...</summary>
    <author>
        <name>Wolfgang Kinkeldei</name>
        
    </author>
    
    <category term="perlworkshop" label="perl workshop" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://blogs.perl.org/users/wolfgang_kinkeldei/">
        <![CDATA[<p>Yesterday was the last day of the german perl workshop.</p>

<p>Denis Banovic started with a live demo demonstrating development and deployment of a dancer app in the "Cloud". It looked very easy to do.</p>

<p>Karl Gaissmaier was the next speaker explaining a lot of details about Captive::Portal, a hostspot software his university developed.</p>

<p>Stefan Hornburg talked about various advanced features of and his experiences with Dancer.</p>

<p>After lunch, Rolf Langsdorf held a very interesting talk comparing Perl and JavaScript. After that, Herbert Breunung had two talks: Thoughts about better documentation and a comparison of Hg and git.</p>

<p>And the last two speakers were Richard Lippmann discussing the usage of the right language for programming projects and Renée Bäcker with tips and tricks for doing talks.</p>

<p>All to gether, this was a great workshop. I will definitely attend next year's workshop which is in Erlangen from March 5 to March 7, 2012.</p>
]]>
        

    </content>
</entry>

<entry>
    <title>German Perl Workshop day 2</title>
    <link rel="alternate" type="text/html" href="http://blogs.perl.org/users/wolfgang_kinkeldei/2011/10/german-perl-workshop-day-2.html" />
    <id>tag:blogs.perl.org,2011:/users/wolfgang_kinkeldei//473.2320</id>

    <published>2011-10-20T19:37:19Z</published>
    <updated>2011-10-21T06:40:42Z</updated>

    <summary>Today, we had more talks than yesterday. Marc Chantreux talked about his module, &apos;Perlude&apos;, an interesting CPAN module porting some of Haskel&apos;s ideas to perl. Gerhard Schwanz presenting Mapweaver was the next speaker, directly followed by Denis Banovic presenting the...</summary>
    <author>
        <name>Wolfgang Kinkeldei</name>
        
    </author>
    
    <category term="perlworkshop" label="perl workshop" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://blogs.perl.org/users/wolfgang_kinkeldei/">
        <![CDATA[<p>Today, we had more talks than yesterday. Marc Chantreux talked about his module, 'Perlude', an interesting CPAN module porting some of Haskel's ideas to perl.</p>

<p>Gerhard Schwanz presenting Mapweaver was the next speaker, directly followed by Denis Banovic presenting the simplicity of Dancer. For me, this talk was the best of today.</p>

<p>Steffen Ulrich gave an excellent introduction into TLS and explained some recently happening issues and how they could occur.</p>

<p>As a replacement for an omitted talk, Heiner Kuhlmann presented a tool to display some software quality metric values graphically. Nice to see Perl-Critic in colored boxes :-)</p>

<p>Herbert Breunung talked about some features of Perl 6. Whenever I hear him talking, I wish Perl 6 was already production-ready. All the new features are really awesome!</p>

<p>The last two speakers before the lightning talk session were Rolf Langsdorf showing a way of using macros to expand Perl 5 and Lars Dieckow who gave another SSL talk. The Macro-Talk was very impressive but I have to take a look into the sources in order to fully understand what happens under the hood.</p>

<p>As usual, the lightning talks went over too fast. The things I remember most were a new search engine operating under Perl: http://duckduckgo.com and the reminders to next year's German Perl Workshop in March and the YAPC Europen in August.</p>
]]>
        

    </content>
</entry>

<entry>
    <title>German Perl Workshop day 1</title>
    <link rel="alternate" type="text/html" href="http://blogs.perl.org/users/wolfgang_kinkeldei/2011/10/german-perl-workshop-day-1.html" />
    <id>tag:blogs.perl.org,2011:/users/wolfgang_kinkeldei//473.2315</id>

    <published>2011-10-19T20:21:57Z</published>
    <updated>2011-10-19T20:33:28Z</updated>

    <summary>Today, the german perl workshop 2011 started. Today&apos;s keynote was done by Heiner Kuhlmann, who talked about software architectures and refactoring. The interesting point was the parallelism between data structures and software structure. All the time I was comparing his...</summary>
    <author>
        <name>Wolfgang Kinkeldei</name>
        
    </author>
    
    <category term="perlworkshop" label="perl workshop" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://blogs.perl.org/users/wolfgang_kinkeldei/">
        <![CDATA[<p>Today, the german perl workshop 2011 started. Today's keynote was done by Heiner Kuhlmann, who talked about software architectures and refactoring. The interesting point was the parallelism between data structures and software structure. All the time I was comparing his talk with Robert C. Martin's book "Clean Code" which mentioned refactoring a couple of times. The common denominator is that refactoring without intensive testing cannot be successful.</p>

<p>Renée Bäcker demonstrated the use of <code>Role::Basic</code> for non-Moose environments. Looks very useful.</p>

<p>Rolf Langsdorf talked about possibilities to extend Perl's syntax using syntactic sugar and function prototypes. He tries to avoid source-filters and parsers in order to avoid breakage of external tools.</p>

<p>Uwe Voelker talked about <code>HTML5::Sanitizer</code>, a module he wrote to clean uploaded HTML code.</p>

<p>Max Maischein demonstrated Web Scraping techniques using FireFox to allow scraping websites that depend on JavaScript.</p>

<p>Looking forward to tomorrow's talks :-)</p>
]]>
        

    </content>
</entry>

<entry>
    <title>Test::DBIx::Class</title>
    <link rel="alternate" type="text/html" href="http://blogs.perl.org/users/wolfgang_kinkeldei/2011/10/testdbixclass.html" />
    <id>tag:blogs.perl.org,2011:/users/wolfgang_kinkeldei//473.2262</id>

    <published>2011-10-06T19:20:53Z</published>
    <updated>2011-10-06T19:35:38Z</updated>

    <summary>Today, I tried to test a freshly created DB schema using Test::DBIx::Class. Scanning through the documentation was impossible -- it knows far too many options to get captured within a few minutes. But carefully reading the brilliant manual is worth...</summary>
    <author>
        <name>Wolfgang Kinkeldei</name>
        
    </author>
    
    <category term="dbixclass" label="DBIx::Class" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://blogs.perl.org/users/wolfgang_kinkeldei/">
        <![CDATA[<p>Today, I tried to test a freshly created DB schema using <code>Test::DBIx::Class</code>. Scanning through the documentation was impossible -- it knows far too many options to get captured within a few minutes. But carefully reading the brilliant manual is worth the time spent. <code>Test::DBIx::Class</code> has a lot of options and test-functions tailored especially to the needs of DB-testing.</p>

<p>My primitive schema knows 3 tables: Sensors, Measures and AlarmConditions. Inside my <code>t/</code> directory, I needed to create only one supplementary file to allow the tests to get coded: a config file <code>t/etc/schema.pl</code></p>

<pre><code>{
    schema_class =&gt; 'Statistics::EasySchema',
    force_drop_table =&gt; 1,
    resultsets =&gt; [ qw(AlarmCondition Measure Sensor) ],
    connect_info =&gt; ['DBI:Pg:dbname=statistics_test', 'user', 'secret'],
}
</code></pre>

<p>My tests started using a blank database which was OK for me in this particular situation with a primitive database like this.</p>

<p>My test-script partially looked like that:</p>

<pre><code>use strict;
use warnings;
use Test::More;
use Test::DBIx::Class;


# ensure DB is empty
is Sensor-&gt;count, 0, 'no records in sensor table';


# add a sensor
ok my $sensor = Sensor-&gt;find_or_create({name =&gt; 'erlangen/keller/temperatur'}),
    'find or create sensor';
is_result $sensor;
is_fields [qw(sensor_id name)], $sensor, [1, 'erlangen/keller/temperatur'],
    'sensor fields look good';
is Sensor-&gt;count, 1, '1 record in sensor table';

# more test...

done_testing;
</code></pre>

<p>How easy things can be by simply using the right module :-)</p>
]]>
        

    </content>
</entry>

<entry>
    <title>DBIx::Class populate Gotcha</title>
    <link rel="alternate" type="text/html" href="http://blogs.perl.org/users/wolfgang_kinkeldei/2011/09/dbixclass-populate-gocha.html" />
    <id>tag:blogs.perl.org,2011:/users/wolfgang_kinkeldei//473.2214</id>

    <published>2011-09-21T12:37:15Z</published>
    <updated>2011-09-21T13:40:44Z</updated>

    <summary>Today, we watched a series of test cases failing. Our tests started with a blank database and a series of populate method-calls to create their own test records. Everything looked obviously right, but after a while of debugging, we found...</summary>
    <author>
        <name>Wolfgang Kinkeldei</name>
        
    </author>
    
    <category term="dbixclass" label="DBIx::Class" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://blogs.perl.org/users/wolfgang_kinkeldei/">
        <![CDATA[<p>Today, we watched a series of test cases failing. Our tests started with a blank database and a series of populate method-calls to create their own test records.</p>

<p>Everything looked obviously right, but after a while of debugging, we found out that the populate method of DBIx::Class::ResultSet behaves differently depending on the context used. In Scalar or List context, the records are inserted using the INSERT statement, while in void context, a bulk insert method is used.</p>

<p>From a performance standpoint, this absolutely makes sense. The documentation does explain this very well.</p>

<p>However, some optimizations have been made under the hood that are not obvious unless you know about -- I did not know that before.</p>

<p>My code looked like this:</p>

<pre>
    MyApp->model('DB::Element')->populate([
        {element_id => 113, name => 'f4'},
        {element_id => 114, name => 'f5', usage_starts => '2000-04-01'},
    ]);
</pre>

<p>And the statement sent to the database was:</p>

<pre>
INSERT INTO element( element_id, name ) 
  VALUES( ?, ? ) : '__BULK_INSERT__'
</pre>

<p>Every column which was not mentioned in the first record got lost and simply was ignored.</p>

<p>Conclusion? A bulk insert can only operate on a well known set of columns. The logic behind DBIx::Class retrieves the set of rows from the keys of the first hashref. This is important to keep in mind when using this syntax.</p>

<p>Solutions? TIMTOWTDI :-) If speed is not important, a populate method call could easily put into list context forcing the usage of single insert statements that do what you expect.</p>

<pre>
    # force list context, ugly but usable :-)
    () = MyApp->model('DB::Element')->populate([
        # ...
    ]);
</pre>
]]>
        
    </content>
</entry>

<entry>
    <title>Wishlist: filter CPAN modules</title>
    <link rel="alternate" type="text/html" href="http://blogs.perl.org/users/wolfgang_kinkeldei/2011/09/wishlist-filter-cpan-modules.html" />
    <id>tag:blogs.perl.org,2011:/users/wolfgang_kinkeldei//473.2175</id>

    <published>2011-09-09T11:38:16Z</published>
    <updated>2011-09-09T11:44:25Z</updated>

    <summary>Sometimes I wish I could apply a filter named &quot;only list serious modules&quot; when browsing through CPAN. More and more people are mis-using CPAN as a personal storage for modules that are not usable for other people. Other useless modules...</summary>
    <author>
        <name>Wolfgang Kinkeldei</name>
        
    </author>
    
    <category term="cpanperl" label="cpan perl" scheme="http://www.sixapart.com/ns/types#tag" />
    
    <content type="html" xml:lang="en" xml:base="http://blogs.perl.org/users/wolfgang_kinkeldei/">
        <![CDATA[<p>Sometimes I wish I could apply a filter named "only list serious modules" when browsing through CPAN. More and more people are mis-using CPAN as a personal storage for modules that are not usable for other people. Other useless modules (aside from those in the 'ACME' namespace) act as a pun on common modules like 'Moose'.</p>

<p>Especially when teaching newcomers how to use the CPAN this leaves a bad impression.</p>

<p>Experienced people quickly learn to skip those things but taking the archive more serious would be nice.</p>]]>
        
    </content>
</entry>

</feed>
