This Week I Learned 2019 - Week 06

Last week post or you can going through some earlier stuff.

Happy new year again or rather, happy Chinese New Year. The weather was blazing hot compare to all the previous year even though there is no fire haze from our neighbouring country.

What else I've learned this week not within this post? Going through the sixth week of ornamental fish culture on fish breeding techniques such as selective breeding and biotechnology. Since this is a short lecture notes, I've decided to continue with week 7 study notes which discuss on seed production on factors affecting larvae rearing and feeding (species and water medium). The review paper of this week is the masculinization of the ornamental Siamese fighting fish with oral hormonal administration. SMS::ClickSend is the Perl module of the week to be reviewed.

Is Nokia 6303c still available these days? The most memorable and funny post I've read so far this year. I'm not sure under what context the poster needs to use a durable normal dump phone, but moving from Nokia 6303c, Nokia 216, Nokia 150, and lastly CAT B30 His perseverance is commendable and definitely should be the coolest post (not coolest use) of Perl usage writeup. I miss the old monochrome dumb or feature phone which is durable, have long lasting battery, and purposeful usages (call, text, and defend). Does affordable dumb phones still exists (as in 2019) these days? Yes, there are quite a lot and the one that caught my attention are from Alcaltel model 10.54, 20.08, 20.51, 10.50. Why dump phone still have a market these days? Four words. Africa and senior citizen.

为何程序员找工作要有个黑名单?这是Github每星期的邮件里推荐的一个流行的Repo。看见这个Repo竟然有十多千个Star,没想到还蛮多大陆的同胞在使用Github。

What are the differences among the subroutines in Carp module? Carp is a Perl module that provides alternative subtitutions to to `warn` and `die` in Perl? The screenshot below summarizes it the best. If you want the similar backtrace feature but don't or can't change your Perl code, there is always a Carp::Always module that will patch the `warn` and `die` subroutine.


What does a long time developer want? "Build more long lasting artifacts." How? Contribute more to FOSS then, is as simple as that.

Is Makefile redundant? In some context, yes. Because if you've a shell available, any shell scripts should be sufficient enough to emulate a Makefile as shown below.
#!/bin/sh
    set -e

    case "$1" in
        up)
            docker-compose up -d
            ;;

        build)
            docker-compose rm -vsf
            docker-compose down -v --remove-orphans
            docker-compose build
            docker-compose up -d
            ;;
        *)
            echo "unknown verb: $1"
            ;;
    esac

Write and publish a book in ten minutes per day? (via HN) Is this doable? Yes, you can just sit there and stare at it for ten minutes. However, the ten minutes is just the appetizer, to get your started. Maybe you can be in the zone or maybe not but you did something, even through you're just sitting there. The thing is you must do it every day, and every day it get easier. Remember the Jogging Baboon?

However, your brain still works on the task subconsciously even after the time frame. If you're not writing a book, what else can you do in ten minutes per day then? Doubt so as you brain still process the task the whole day even after the timed duration. Hence, the ten minutes is just to bootstrap the task and you've spend a few hours later doing it subconsciously.

There is another important lesson here. When to stop. If you don't have any juice left, stop. Or if you doing very well like in the zone, stop so you can look forward to continue tomorrow.

What else can you do during the ten minutes duration? There are plenty of things such as writing a dairy journals (via Lobsters), pick up any new habits, 5BX exercise plan, core wars kata.

Perl Module(s) Of The Week - 2019 Week 06 - SMS::ClickSend

This week Perl module, SMS::ClickSend was chosen because after reviewing the source code, I personally felt that this module embodies what I consider the Perl 5 way of simple coding style. Regardless Perl's notorious TMTOWTDI, as I observed, there exists a standard coding style which includes (1) Use minimum dependencies for speed and simplicity, (2) Prefer plain old Object-Oriented (OO) using blessed instead of Moose or Moo, (3) Snake case subroutine naming convention, (4) lack and little validation, and (5) Brevity without overly verbose. Even through the module was written in 2014 (5 years ago), I've seen new CPAN module that was written in such style even in 2019. There are some CPAN modules which were written in such over-engineered way that spans multiple modules. But that is a discussion for another day.

As usual, Installation is simple.
$ cpanm SMS::ClickSend

Sample usage of the API based on the synopsis.
use SMS::ClickSend;
 
my $sms = SMS::ClickSend->new(
    username => 'username',
    api_key  => 'API_KEY...',
);
 
my $res = $sms->send(
    to => '+61411111111',
    message => 'This is the message',
);
print Dumper(\$res); use Data::Dumper;

Let us look at the constructor. The constructor, `new` accept an array of values that needs to be converted to a hash. Hence, the number of items in the array should be even, hence the modulo by 2 to detect any odd number of items passed. Converting an array to a hash is quite straight forward, just `%hash = @array` should be sufficient;
sub new {
    my $class = shift;
    my %args = @_ % 2 ? %{$_[0]} : @_;

Check whether the required parameters exists without using the `exists`. Just use short-circuit evaluation through logical or operator. Read more on logical disjunction.
    $args{username} or croak 'username is required.';
    $args{api_key}  or croak 'api_key is required.';

Use default user agent if nothing was set or defined through the logical-or assignment.
    $args{ua} ||= LWP::UserAgent->new;

Lastly, just make sure or bless the hash arguments to be part of an object in the `SMS::ClickSend` package.
    return bless \%args, $class;
}

To fully understand how the constructor works, we need to show how the constructor was being called by the calling code.
# We are passing an array of four elements
my $sms = SMS::ClickSend->new(username => $username, api_key => $api_key);

# We are passing a hash and this can be obtained from first element from the argument, `$_[0]`.
my $sms = SMS::ClickSend->new({username => $username, api_key => $api_key});

# This will not work and `$args` will become an empty hash.
my $sms = SMS::ClickSend->new($username);

# This will work partially as `api_key` argument is missing and trigger the `croak`.
my $sms = SMS::ClickSend->new(username => $username);

Instead of catering for all possible inputs, perhaps we can just stick to one way of an array instead of hash to accept arguments to the constructor.
sub new {
    my ($class, %args) = @_;

    $args{username} or croak "username os required";
    $args{api_key} or croak "api_key is required";

    return bless \%args, $class;
}

Another interesting module found within the code. Basically, `var` is "Perl pragma to predeclare global variable names". Basically a global variable within the scope of the package. Superseded by `our` function which is a "lexical alias to a package (i.e. global) variable".
use vars qw/$errstr/;
 
sub errstr { $errstr }