<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Volker Kroll</title>
    <description>The latest articles on DEV Community by Volker Kroll (@vkroll).</description>
    <link>https://dev.to/vkroll</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F198713%2Fc4d30e36-06d1-4b8a-a021-c65496bb8ffe.jpg</url>
      <title>DEV Community: Volker Kroll</title>
      <link>https://dev.to/vkroll</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/vkroll"/>
    <language>en</language>
    <item>
      <title>Date handling modularized</title>
      <dc:creator>Volker Kroll</dc:creator>
      <pubDate>Fri, 28 May 2021 14:34:08 +0000</pubDate>
      <link>https://dev.to/vkroll/date-handling-modularized-10h9</link>
      <guid>https://dev.to/vkroll/date-handling-modularized-10h9</guid>
      <description>&lt;p&gt;Thanks to mentioning my first post on the &lt;a href="https://perlweekly.com/archive/513.html"&gt;perl weekly newsletter&lt;/a&gt; a lot people read the first part of this serie of articles. (Don't know yet, how many parts it will be.) So I decided to write a follow-up. &lt;/p&gt;

&lt;p&gt;What can you expect:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Moving functions to modules&lt;/li&gt;
&lt;li&gt;testing functions automatically&lt;/li&gt;
&lt;li&gt;change a module to a class&lt;/li&gt;
&lt;li&gt;inherit the class from a base class&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To summarize where we left our little skript in part one:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;use strict;

use Getopt::Long;
use DateTime;
use DateTime::Duration;

my $date;   ## the starting date argument
my $dt;     ## DateTime Object of starting date


GetOptions(
        "date=s"         =&amp;gt; \$date,
        );

$dt = get_dt($date);
my $today = DateTime-&amp;gt;today();



if(!$dt) {
    print "submitted value $date is no date\n";
}
if(is_last_week($dt)) {
    print "submitted date was in the last week\n";
}

sub is_last_week {
    my $dt = shift;
    return unless ref $dt eq "DateTime";
    return if($dt &amp;gt; $today) ;

    my $dur = DateTime::Duration-&amp;gt;new(days =&amp;gt; 7);
    $today-&amp;gt;subtract_duration($dur);
    return 1 if $today &amp;lt; $dt;
}


sub get_dt {
    my $date = shift;

    my($y, $m, $d) = $date =~ /^(\d\d\d\d)-(\d\d)-(\d\d)$/;
    my $dt;
    eval {
        $dt = DateTime-&amp;gt;new(year =&amp;gt; $y, month =&amp;gt; $m, day =&amp;gt; $d);
    }; 
    if ($@) {
        print STDERR "Error while generating DateTime: $@\n";
        return 0;
    }
    else {
        return $dt;
    }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The script checks a parameter -d if it is a valid date and that the date is in the last week.&lt;/p&gt;

&lt;p&gt;Calling the script without a paremeter end with a not so nice error:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;perl skript.pl &lt;br&gt;
Error while generating DateTime: Validation failed for type named DayOfMonth declared in package DateTime::Types (/home/kroll/.plenv/versions/5.32.1/lib/perl5/site_perl/5.32.1/x86_64-linux/DateTime/Types.pm) at line 29 in sub named (eval) with value undef&lt;/p&gt;

&lt;p&gt;Trace begun at Specio::Exception-&amp;gt;new line 57&lt;br&gt;
Specio::Exception::throw('Specio::Exception', 'message', 'Validation failed for type named DayOfMonth declared in package DateTime::Types (/home/kroll/.plenv/versions/5.32.1/lib/perl5/site_perl/5.32.1/x86_64-linux/DateTime/Types.pm) at line 29 in sub named (eval) with value undef', 'type', 'Specio::Constraint::Simple=HASH(0x55a2fa53c0a8)', 'value', undef) called at (eval 201) line 91&lt;br&gt;
DateTime::_check_new_params('year', undef, 'month', undef, 'day', undef) called at /home/kroll/.plenv/versions/5.32.1/lib/perl5/site_perl/5.32.1/x86_64-linux/DateTime.pm line 176&lt;br&gt;
DateTime::new('DateTime', 'year', undef, 'month', undef, 'day', undef) called at skript.pl line 45&lt;br&gt;
eval {...} at skript.pl line 44&lt;br&gt;
main::get_dt(undef) called at skript.pl line 15&lt;/p&gt;

&lt;p&gt;submitted value  is no date&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;We will write this on our to-do-list for later.&lt;/p&gt;

&lt;p&gt;But for today we want to put the date handling out of the script in a module, so that the script later can do the heavy lifting but the date handling can be reused in other scripts. &lt;/p&gt;

&lt;h1&gt;
  
  
  Generating a new and empty module
&lt;/h1&gt;

&lt;p&gt;For the perl people it is quite obvious, you generate a directory lib and put the module in and do the normal perl boilerplate:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;package Date;

use strict;

use DateTime;
use DateTime::Duration;


1;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And as the test-driven guy I am usually, I added my first test too. In t/date.t you will find:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;use Test::More;

use_ok("Date");

done_testing();
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And of course this will result green: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;$ prove -lv&lt;br&gt;
t/date.t .. &lt;br&gt;
ok 1 - use Date;&lt;br&gt;
1..1&lt;br&gt;
ok&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So we can commit it:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Author: Volker Kroll &lt;br&gt;
Date:   Thu May 6 11:59:53 2021 +0200&lt;/p&gt;

&lt;p&gt;new Module Date&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Date is empty&lt;/li&gt;
&lt;li&gt;t/date.t has a test, that it loads correctly&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  Move the get_dt in Date.pm
&lt;/h1&gt;

&lt;p&gt;Not much to do then get the code from the script and paste it in our module. But because I prefer modules to be a little more object-oriented I also added a constructor in the - little weird old oo-perl style.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sub new {
    my $class = shift;
    my $datestring = shift|| undef;
    if ($datestring) {
        bless get_dt($datestring), $class;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And a little more testing of course:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;use_ok("Date");

my $d = Date::get_dt('2020-01-02');
isa_ok($d, DateTime);
my $date = Date-&amp;gt;new('2020-01-02');
isa_ok($date, "Date");
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Resulting in:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;$ prove -lv&lt;br&gt;
t/date.t .. &lt;br&gt;
ok 1 - use Date;&lt;br&gt;
ok 2 - An object of class 'DateTime' isa 'DateTime'&lt;br&gt;
ok 3 - An object of class 'Date' isa 'Date'&lt;br&gt;
1..3&lt;br&gt;
ok&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Enough code to commit it:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Author: Volker Kroll &lt;a href="mailto:kroll@strato.de"&gt;kroll@strato.de&lt;/a&gt;&lt;br&gt;
Date:   Thu May 6 12:11:15 2021 +0200&lt;/p&gt;

&lt;p&gt;get_dt now in Date&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;get_dt is called like in skript.pl Date::get_dt(yyyy-mm-dd)&lt;/li&gt;
&lt;li&gt;additionally you can do a Date-&amp;gt;new(yyyy-mm-dd)
 returned is an object of class Date (that is a DateTime)&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  Why not make Date a child of DateTime?
&lt;/h1&gt;

&lt;p&gt;While working on my module I thought it might be a good idea to inherit from DateTime so that if I do a Date-&amp;gt;new(...) I get a DateTime object back. But, that did not work immediatly, because I need to add a lot of code of DateTime then for follow that constructor. (And to be honest, I forgot how to only add a little in my constructor and letting the "real constructor" do the heavy lifting of DateTime, so I decided for this project to rename my constructor to create (that's easy in perl, where you can name your constructor like you want to).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;package Date;

use strict;

use base qw(DateTime);
use DateTime;
use DateTime::Duration;


sub create {
    my $class = shift;
    my $datestring = shift|| undef;
    if ($datestring) {
        return bless get_dt($datestring), $class;
    }
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Also I wanted my function is_last_week in the module too, we had it before in our little script. For making the tests more easy, I added the possibility to "cheat with today" as A. mentioned. When I add a parameter today in the call it uses that not the "real today":&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sub is_last_week {
    my $dt = shift;
    return unless ref $dt;
    my $today = shift ||  DateTime-&amp;gt;today();
    return if($dt &amp;gt; $today) ;

    my $dur = DateTime::Duration-&amp;gt;new(days =&amp;gt; 7);
    $dt-&amp;gt;add_duration($dur);
    return 1 if $today &amp;lt; $dt;
    return 0;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now I was able to add some more testing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;use Test::More;
use Data::Dumper;
use DateTime;

use_ok("Date");
test_new();
test_is_last_week();
done_testing();

sub test_new {
    my $d = Date::get_dt('2020-01-02');
    isa_ok($d, DateTime);
    my $date = Date-&amp;gt;create('2020-01-02');
    isa_ok($date, Date);
    isa_ok($date, DateTime);
}

sub test_is_last_week {
    my $date = Date-&amp;gt;create('2020-01-02');
    my $today = DateTime-&amp;gt;new(year =&amp;gt; 2020, month =&amp;gt; 01, day =&amp;gt; 05);
    can_ok($date, "is_last_week");
    isa_ok($date, "Date");
    isa_ok($today, "DateTime");
    is($date-&amp;gt;is_last_week($today), 1, "2020-01-02 was in the week before 2020-01-05 ");
    is($date-&amp;gt;is_last_week(), 0, "2020-01-02 was not last week from today ");

}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Again resulting in the expected output:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;$ prove -lv&lt;br&gt;
t/date.t .. &lt;br&gt;
ok 1 - use Date;&lt;br&gt;
ok 2 - An object of class 'DateTime' isa 'DateTime'&lt;br&gt;
ok 3 - An object of class 'Date' isa 'Date'&lt;br&gt;
ok 4 - An object of class 'Date' isa 'DateTime'&lt;br&gt;
ok 5 - Date-&amp;gt;can('is_last_week')&lt;br&gt;
ok 6 - An object of class 'Date' isa 'Date'&lt;br&gt;
ok 7 - An object of class 'DateTime' isa 'DateTime'&lt;br&gt;
ok 8 - 2020-01-02 was in the week before 2020-01-05 &lt;br&gt;
ok 9 - 2020-01-02 was not last week from today &lt;br&gt;
1..9&lt;br&gt;
ok&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The next step is of course -- as usual -- the commit&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Author: Volker Kroll &lt;br&gt;
Date:   Fri May 7 11:38:11 2021 +0200&lt;/p&gt;

&lt;p&gt;added Tests for date was in last week&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;changed new to create to not interfere with DateTime new&lt;/li&gt;
&lt;li&gt;add function for is_last_week&lt;/li&gt;
&lt;li&gt;for testing purposes it is possible to call is_last_week with a given
 "today" so tests don't become red&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  Just a few more tests
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sub test_is_last_week {
    my $date = Date-&amp;gt;create('2020-01-02');
    my $today = DateTime-&amp;gt;new(year =&amp;gt; 2020, month =&amp;gt; 01, day =&amp;gt; 05);
    can_ok($date, "is_last_week");
    isa_ok($date, "Date");
    isa_ok($today, "DateTime");
    is($date-&amp;gt;is_last_week($today), 1, "2020-01-02 was in the week before 2020-01-05 ");
    is($date-&amp;gt;is_last_week(), 0, "2020-01-02 was not last week from today ");
    is($date-&amp;gt;is_last_week(), 0, "2020-01-02 was not last week from today ");

}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now the whole module is tested enough to use it. &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;t/date.t .. &lt;br&gt;
ok 1 - use Date;&lt;br&gt;
ok 2 - An object of class 'DateTime' isa 'DateTime'&lt;br&gt;
ok 3 - An object of class 'Date' isa 'Date'&lt;br&gt;
ok 4 - An object of class 'Date' isa 'DateTime'&lt;br&gt;
ok 5 - Date-&amp;gt;can('is_last_week')&lt;br&gt;
ok 6 - An object of class 'Date' isa 'Date'&lt;br&gt;
ok 7 - An object of class 'DateTime' isa 'DateTime'&lt;br&gt;
ok 8 - 2020-01-02 was in the week before 2020-01-05 &lt;br&gt;
ok 9 - 2020-01-02 was not last week from today &lt;br&gt;
ok 10 - 2020-01-02 was not last week from today &lt;br&gt;
1..10&lt;br&gt;
ok&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Only a final commit&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Author: Volker Kroll &lt;br&gt;
Date:   Fri May 7 14:21:09 2021 +0200&lt;/p&gt;

&lt;p&gt;some more testing in date.t&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  Conclusion
&lt;/h1&gt;

&lt;p&gt;Only a few changes changed a lot. Now we are able to easily test the functions we developed. Additionally we can later reuse our (now DateTime) object. But the biggest benefit for the following work is to remove the date handling from the script that will have other work to do. So we separeted the different parts which make them more easy to modify and use.&lt;/p&gt;

&lt;p&gt;What will be the next logical step? That is depended of the requirements and the users of the software. But I would probably fix the "bad error message" when called without a parameter. Usually I call the help function (that still needs to be written), when a mandatory parameter is missing. But that will be done in a third part -- maybe -- stay tuned.&lt;/p&gt;

</description>
      <category>perl</category>
      <category>beginners</category>
      <category>learning</category>
      <category>tdd</category>
    </item>
    <item>
      <title>Developing a script in small steps</title>
      <dc:creator>Volker Kroll</dc:creator>
      <pubDate>Mon, 17 May 2021 17:51:25 +0000</pubDate>
      <link>https://dev.to/vkroll/common-misconception-of-beginners-51jb</link>
      <guid>https://dev.to/vkroll/common-misconception-of-beginners-51jb</guid>
      <description>&lt;p&gt;It all started with a git commit I found: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;commit 340d908fe537d3163e220c84945bbfc5b49fe8dc&lt;br&gt;
Author: A.&lt;br&gt;
Date:   Wed Apr 14 17:28:50 2021 +0200&lt;br&gt;
Deleted redundant INFO messages. Replaced date strings with dt-&amp;gt;ymd() calls. Replaced some if nots with unless. Simplified sub _unpack. Set timezone in DateTime objects. Results are returned as tail calls now. Maybe more minor changes.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;A. is a fresh developer in my department and as many future devs she did not learn so far - neither in university nor in books - how to organize her work. How to avoid commits ending with &lt;strong&gt;Maybe more minor changes.&lt;/strong&gt; Honestly I know a lot senior devs who still use a version control system like any other backup. So what I wanted to show her, was: &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;How to organize my programming in small steps&lt;/li&gt;
&lt;li&gt;How slowly developing &lt;/li&gt;
&lt;li&gt;How to make errors without desaster&lt;/li&gt;
&lt;li&gt;How to use your version control&lt;/li&gt;
&lt;li&gt;How to write a helpful commit-message&lt;/li&gt;
&lt;li&gt;How will I later find something I did&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;So I started a programming-session on my own, and gave her later the repository and we discussed each step. (Honestly: She found immediately an error in my code, that I did not left there intentionally).&lt;/p&gt;

&lt;p&gt;The development was in perl, but I hope other devs find the steps valueable too, so I write it down here. (My first longer article in english)&lt;/p&gt;

&lt;h1&gt;
  
  
  Step one: all started with a README
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;- Script with parameters
    -d Date
        -&amp;gt; has to be in the past
        -&amp;gt; must be no older then 7 days

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Of course that was the first commit: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;commit &lt;br&gt;
Author: Volker Kroll &lt;br&gt;
Date:   Wed May 5 16:49:17 2021 +0200&lt;/p&gt;

&lt;p&gt;README&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;we will have the requirements here&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  Now the fun started, the initial script
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;use strict;

use Getopt::Long;

my $date ; ## the startingdate

GetOptions(
        "date=s"         =&amp;gt; \$date,
        );

print "submitted Date is: $date\n";
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The perl people know, that script does not much more then storing a submitted string as parameter --date or -d in the scalar variable $date.&lt;br&gt;
And of course it uses strict as every good perl script does. &lt;/p&gt;

&lt;p&gt;I committed this change: &lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Author: Volker Kroll&lt;br&gt;
Date:   Wed May 5 16:52:01 2021 +0200&lt;/p&gt;

&lt;p&gt;initial&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Parameter d for the date&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;TODO:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Validation&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h1&gt;
  
  
  As promised a validation
&lt;/h1&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;## starts as before
sub is_date {
    my $date = shift;

    return 1 if $date =~ /^\d\d\d\d-\d\d-\d\d$/;
    return 0;

}
if(is_date($date)) {
    print "submitted Date is: $date\n";
}
else {
    print "submitted value $date is no date\n";
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;I checked if the submitted date matches the regex &lt;code&gt;^\d\d\d\d-\d\d-\d\d$&lt;/code&gt; - you are aware, that we perl-devs solve our problems with regexes right?&lt;/p&gt;

&lt;p&gt;But enough for the next commit&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Author: Volker Kroll &lt;br&gt;
Date:   Wed May 5 16:54:49 2021 +0200&lt;/p&gt;

&lt;p&gt;first check for date&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;date is valid if regex \d\d\d\d-\d\d-\d\d is valid&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;TODO:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;better check&lt;/li&gt;
&lt;li&gt;exclude non valid month and day&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;
&lt;h1&gt;
  
  
  More checks
&lt;/h1&gt;

&lt;p&gt;As announced the next step was to better check for the validity of the date  - and stay tuned these steps will be changed later.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sub is_date {
    my $date = shift;

    my $days = ["", 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];

    my($y, $m, $d) = $date =~ /^(\d\d\d\d)-(\d\d)-(\d\d)$/;
    if ($m &amp;gt; 0 &amp;amp;&amp;amp; $m &amp;lt; 13) {
        print "$m has max $days-&amp;gt;[$m] days\n";
        return 1 if $d &amp;lt;= $days-&amp;gt;[$m];
    }

    return 0;

}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And the next commit even though theses checks are far from perfect&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Author: Volker Kroll &lt;br&gt;
Date:   Wed May 5 17:00:23 2021 +0200&lt;/p&gt;

&lt;p&gt;more checking of date via regex&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;added length per month value&lt;/li&gt;
&lt;li&gt;check if day is possible in the month&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;TODO:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;that is a bad choice for february&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  Let's correct the february
&lt;/h1&gt;

&lt;p&gt;As we saw, my checks did not really work in february - only in leap-years, so I had to handle that with a check wether it is a leap year or not.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sub is_date {
    my $date = shift;

    my $days = ["", 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];

    my($y, $m, $d) = $date =~ /^(\d\d\d\d)-(\d\d)-(\d\d)$/;
    if (is_leap_year($y)) {
        $days-&amp;gt;[2] = 29;
    }

    if ($m &amp;gt; 0 &amp;amp;&amp;amp; $m &amp;lt; 13) {
        print "$m has max $days-&amp;gt;[$m] days\n";
        return 1 if $d &amp;lt;= $days-&amp;gt;[$m];
    }
    return 0;
}

sub is_leap_year {
    my $y = shift;

    if ($y % 4 == 0) {
        return 1 if $y % 400 == 0;
        return 0 if $y % 100 == 0;
        return 1;
    }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now february is handled correctly in every year. So, up the next commit&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Author: Volker Kroll &lt;br&gt;
Date:   Wed May 5 17:07:06 2021 +0200&lt;/p&gt;

&lt;p&gt;check works even for february&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;new function is_leap_year
TODO&lt;/li&gt;
&lt;li&gt;Refactoring - Removing of all own written calendar functions&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  Refactoring - Use of Date Modules
&lt;/h1&gt;

&lt;p&gt;I had to remove my not so elegant and error-prone date-functions. To get you back on track, here is the whole script after removing that and adding a suitable date module&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;use strict;

use Getopt::Long;
use DateTime;

my $date ; ## the startingdate

GetOptions(
        "date=s"         =&amp;gt; \$date,
        );

sub is_date {
    my $date = shift;

    my $days = ["", 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];

    my($y, $m, $d) = $date =~ /^(\d\d\d\d)-(\d\d)-(\d\d)$/;
    my $dt;
    eval {
        $dt = DateTime-&amp;gt;new(year =&amp;gt; $y, month =&amp;gt; $m, day =&amp;gt; $d);
    }; 
    if ($@) {
        print STDERR "Error while generating DateTime: $@\n";
        return 0;
    }
    else {
        return $dt;
    }
}


if(is_date($date)) {
    print "submitted Date is: $date\n";
}
else {
    print "submitted value $date is no date\n";
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I am using now &lt;a href="https://metacpan.org/pod/DateTime"&gt;DateTime&lt;/a&gt; for every date operation. If no DateTime object can be created we assume, that the submitted value is not correct and return 0, else we return a DateTime Object.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Author: Volker Kroll &lt;br&gt;
Date:   Wed May 5 17:24:41 2021 +0200&lt;/p&gt;

&lt;p&gt;removed own calendar functions and added DateTime&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;validation via Exception of DateTime-&amp;gt;new()&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;TODO:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Refactoring: rename function is_date (returns a dt if true)&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;Maybe you saw, that I forgot to remove the arry with the days per month... I saw it now, while I write this article&lt;/p&gt;

&lt;h1&gt;
  
  
  Clean it up 1/2
&lt;/h1&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;use strict;

use Getopt::Long;
use DateTime;

my $date;   ## the starting date argument
my $dt;     ## DateTime Object of starting date


GetOptions(
        "date=s"         =&amp;gt; \$date,
        );

sub get_dt {
    my $date = shift;

    my $days = ["", 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];

    my($y, $m, $d) = $date =~ /^(\d\d\d\d)-(\d\d)-(\d\d)$/;
    my $dt;
    eval {
        $dt = DateTime-&amp;gt;new(year =&amp;gt; $y, month =&amp;gt; $m, day =&amp;gt; $d);
    }; 
    if ($@) {
        print STDERR "Error while generating DateTime: $@\n";
        return 0;
    }
    else {
        return $dt;
    }
}

$dt = get_dt($date);

if($dt) {
    print "submitted Date is: $date\n";
}
else {
    print "submitted value $date is no date\n";
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Everything I did is mentioned in the commit-message (and there is still that array of days...&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Author: Volker Kroll &lt;br&gt;
Date:   Wed May 5 17:28:04 2021 +0200&lt;/p&gt;

&lt;p&gt;moved function is_date to get_dt&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;check is now if return of get_dt is a true value
 a DateTime Object is a true value
 0 is not
 =&amp;gt; so the check still works
 =&amp;gt; so we have already a working DateTime Object to work with later&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  Clean it up 2/2
&lt;/h1&gt;

&lt;p&gt;Now I moved around the code a bit to make it more readable&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;use strict;

use Getopt::Long;
use DateTime;

my $date;   ## the starting date argument
my $dt;     ## DateTime Object of starting date


GetOptions(
        "date=s"         =&amp;gt; \$date,
        );

$dt = get_dt($date);

if($dt) {
    print "submitted Date is: $date\n";
}
else {
    print "submitted value $date is no date\n";
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The sub get_dt remained the same (and there is still that array)&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Author: Volker Kroll&lt;br&gt;
Date:   Wed May 5 17:31:00 2021 +0200&lt;/p&gt;

&lt;p&gt;moved main code up in the file&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  Now for more functionality
&lt;/h1&gt;

&lt;p&gt;As we remember the day has to be in the past. So we need to check that. DateTime Objects can easily be compared and DateTime has a function called today(). So my first step was:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$dt = get_dt($date);
my $today = DateTime-&amp;gt;today();



if(!$dt) {
    print "submitted value $date is no date\n";
}
if($dt &amp;lt; $today) {
    print "submitted date is in the past\n";
}

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That was easy and it worked out of the box.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Author: Volker Kroll &lt;br&gt;
Date:   Wed May 5 17:33:56 2021 +0200&lt;/p&gt;

&lt;p&gt;check if submitted date is in the past&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;added new DateTime Object $today&lt;/li&gt;
&lt;li&gt;compare $today and DateTime Object of submitted date&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;TODO&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;next check: not older then 7 days (see README)&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  But first let's remove this array....
&lt;/h1&gt;

&lt;p&gt;I think you know how a not existing line looks nevertheless that was worth a commit&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Author: Volker Kroll &lt;br&gt;
Date:   Wed May 5 17:37:45 2021 +0200&lt;/p&gt;

&lt;p&gt;removed old arrayref for days in the month&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  Check if it was in the last week
&lt;/h1&gt;

&lt;p&gt;In our requirements was that the date has to be in the last seven days. (Whatever that means in detail)&lt;/p&gt;

&lt;p&gt;Time for another Date Module &lt;a href="https://metacpan.org/pod/DateTime::Duration"&gt;DateTime::Duration&lt;/a&gt; to calculate that difference.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;if(is_last_week($dt)) {
    print "submitted date was in the last week\n";
}

sub is_last_week {
    my $dt = shift;
    return unless ref $dt eq "DateTime";

    my $dur = DateTime::Duration-&amp;gt;new(days =&amp;gt; 7);
    $dt-&amp;gt;add_duration($dur);
    return 1 if $today &amp;lt; $dt;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I think that code is easily to understand even for not perl-devs. I add 7 days to the submitted date and compare it with today. (Here is the error that my colleague found immediatly - but more about the bug later).&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Author: Volker Kroll &lt;br&gt;
Date:   Wed May 5 17:45:57 2021 +0200&lt;/p&gt;

&lt;p&gt;check for is_last_week&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;added DateTime::Duration&lt;/li&gt;
&lt;li&gt;checked if submitted date was in the last 7 days&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;TODO:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Refactoring: Add the check for in the past in is_last_week&lt;/li&gt;
&lt;/ul&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  Cleanup
&lt;/h1&gt;

&lt;p&gt;As mentioned in the TODO we removed the "is in the past" check from the main and added it to the is_last_week&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sub is_last_week {
    my $dt = shift;
    return unless ref $dt eq "DateTime";
    return if($dt &amp;gt; $today) ;

    my $dur = DateTime::Duration-&amp;gt;new(days =&amp;gt; 7);
    $dt-&amp;gt;add_duration($dur);
    return 1 if $today &amp;lt; $dt;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Normally all this would end with the this commit:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Author: Volker Kroll &lt;a href="mailto:kroll@strato.de"&gt;kroll@strato.de&lt;/a&gt;&lt;br&gt;
Date:   Wed May 5 17:48:31 2021 +0200&lt;/p&gt;

&lt;p&gt;is_last_week now a valid check for date concerning to specification&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h1&gt;
  
  
  The bug
&lt;/h1&gt;

&lt;p&gt;As I wrote before, my colleague spotted a bug in my code. I got this question via chat:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;A:     The line $dt-&amp;gt;add_duration($dur); made me wonder. Is the dt object not changed then? Is this call by value or call by reference?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And she was right. So the next commit was from her, modifying my code and correcting it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;diff --git a/skript.pl b/skript.pl
index 2f5594b..426c4af 100644
--- a/skript.pl
+++ b/skript.pl
@@ -30,7 +30,8 @@ sub is_last_week {
     return if($dt &amp;gt; $today) ;

     my $dur = DateTime::Duration-&amp;gt;new(days =&amp;gt; 7);
-    $dt-&amp;gt;add_duration($dur);
+    #$dt-&amp;gt;add_duration($dur);
+    $today-&amp;gt;subtract_duration($dur);
     return 1 if $today &amp;lt; $dt;
 }
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;She changed the direction of the math and modified the no longer used $today&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Author: A.&lt;br&gt;
Date:   Fri May 7 12:38:15 2021 +0200&lt;/p&gt;

&lt;p&gt;is_last_week subtracts from today instead of adding to dt.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now the script was correct concerning the requirements. &lt;/p&gt;

&lt;h1&gt;
  
  
  Conclusions
&lt;/h1&gt;

&lt;p&gt;Of course this is a little bit artificial - and most devs will need to confess that they usually commit much bigger chunks of code. Nevertheless, I think it is valuable to develop in these small chunks.&lt;/p&gt;

&lt;p&gt;Next steps were making it a bit more modular and added automated tests for further development. But for today this shall be enough.&lt;/p&gt;

</description>
      <category>beginners</category>
      <category>perl</category>
      <category>learning</category>
    </item>
  </channel>
</rss>
