上京エンジニアのお話

田舎から上京してエンジニアとして活躍する毎日を綴ります

Perl スクリプトで usage を書いてみた

はろー。こんにちは。
最近暖かくなったり寒くなったりよくわからん毎日ですね
しかし体調を崩すことは全くありません。丈夫なもんです

ところで今回は簡単なスクリプトPerl で書いて、コマンドラインから扱いやすいように usage を出力されるようにしてみました

$ grep --help
usage: grep [-abcDEFGHhIiJLlmnOoqRSsUVvwxZ] [-A num] [-B num] [-C[num]]
    [-e pattern] [-f file] [--binary-files=value] [--color=when]
    [--context[=num]] [--directories=action] [--label] [--line-buffered]
    [--null] [pattern] [file ...]

具体的にこんなやつです
Linux コマンドを使う時確認するやつですよね

そこで実装する実際のスクリプトは、Twitter で該当のツイートをリツイートしているユーザーの情報を標準出力するスクリプトを書きました
実装は以下です

実装

#!/usr/bin/perl
use strict;
use warnings;
use feature qw( say state );

use Net::Twitter;
use Getopt::Long qw(:config posix_default no_ignore_case gnu_compat);
use Data::Validator;
use Encode qw ( encode_utf8 );

my $tweet_id;
my $print_key;
my $help;
GetOptions('i=i' => \$tweet_id, 'p=s' => \$print_key, h => \$help);
if ($help) {
    die show_help();
}
validate( tweet_id => $tweet_id, print_key => $print_key );

my $account = {
    consumer_key        => '%CONSUMER_KEY%',
    consumer_secret     => '%CONSUMER_SECRET%',
    access_token        => '%ACCESS_TOKEN%',
    access_token_secret => '%ACCESS_TOKEN_SECRET%',
};

my $nt = Net::Twitter->new({
    traits   => [qw/API::RESTv1_1/],
    consumer_key        => $account->{consumer_key},
    consumer_secret     => $account->{consumer_secret},
    access_token        => $account->{access_token},
    access_token_secret => $account->{access_token_secret},
});

my $retweet_user_ids = $nt->retweeters_ids({
    id            => $tweet_id,
    stringify_ids => 'true',
});

my $user;
my $retweet_user_list = [];
map { 
    $user = $nt->show_user({ user_id => $_}); 
    push @$retweet_user_list, $user
} @{ $retweet_user_ids->{ids} };

map { say encode_utf8 $_->{$print_key} } @$retweet_user_list;

sub validate {
    eval {
        state $rule = Data::Validator->new(
            tweet_id  => { isa => 'Int' },
            print_key => { isa => 'Str' },
        );
        my $args = $rule->validate(@_);
    };
    if ($@) {
        die show_help();
        exit;
    }
}

sub show_help {
    my $help_doc = <<EOF;
    get retweet info script
    Usage:
        perl $0 [options]
    Options:
        -i : tweet_id (Int)
        -p : print_key (Str)
            ex )
                id, screen_name, location
                https://developer.twitter.com/en/docs/accounts-and-users/follow-search-get-users/api-reference/get-users-show            
        -h : help
    Author
        okkun_sh <okkun.sh\@gmail.com> (\@okkun_sh on Twitter)
EOF
    return $help_doc;
}

使用方法

$ perl get_retweet_info.pl -h

    get retweet info script

    Usage:
        perl get_retweet_info.pl [options]

    Options:
        -i : tweet_id (Int)

        -p : print_key (Str)
            ex )
                id, screen_name, location
                https://developer.twitter.com/en/docs/accounts-and-users/follow-search-get-users/api-reference/get-users-show

        -h : help


    Author
        okkun_sh <okkun.sh@gmail.com> (@okkun_sh on Twitter)


$perl get_retweet_info.pl -i 1111111111 -p screen_name

-h をすることで usage が出力されるようになります
これでoption -i でツイート id の指定、
-p でリツイートしているユーザーの情報の指定をすればよいということがわかりますね

コードのポイントは、この部分です
GetOptions でオプションの引数の指定をしており、引数に対してバリデーションをかけてエラー時は usage が出力されるようにハンドリングしています
また -h を指定時は usage が出力されるようにもしています

use Getopt::Long;
use Data::Validator;

my $tweet_id;
my $print_key;
my $help;
GetOptions('i=i' => \$tweet_id, 'p=s' => \$print_key, h => \$help);
if ($help) {
    die show_help();
}
validate( tweet_id => $tweet_id, print_key => $print_key );

sub validate {
    eval {
        state $rule = Data::Validator->new(
            tweet_id  => { isa => 'Int' },
            print_key => { isa => 'Str' },
        );
        my $args = $rule->validate(@_);
    };
    if ($@) {
        die show_help();
        exit;
    }
}

sub show_help {
    my $help_doc = <<EOF;
    get retweet info script
    Usage:
        perl $0 [options]
    Options:
        -i : tweet_id (Int)
        -p : print_key (Str)
            ex )
                id, screen_name, location
                https://developer.twitter.com/en/docs/accounts-and-users/follow-search-get-users/api-reference/get-users-show            
        -h : help
    Author
        okkun_sh <okkun.sh\@gmail.com> (\@okkun_sh on Twitter)
EOF
    return $help_doc;
}

スクリプト自体はさくっと作ったので動作は怪しいですが、usage の書き方自体は参考になると思います!
完成してから知りましたが、Twitter API ではリツイート情報の取得上限が最大100件らしく全てを取得しきれませんでした。。

もっとシンプルに書ける方法などあれば、コメントください!

Parallel::ForkManager を使って並列処理してみた

ひょんなことから、並列処理が必要とされる場面があったので Parallel::ForkManager とやらを使ってみた

このモジュールを選定した理由は、threads か Parallel::ForkManager で迷ったが、使っている perlbrew では threads が使えなかったため今回は、Parallel::ForkManager を使用しました

ちなみに threads とは、いい感じにマルチスレッドを扱えるクラスです

perldoc.jp

では、Parallel::ForkManager の使い方を書いていきます

導入

cpanm Parallel::ForkManager
いつも通り cpanmコマンドでモジュールを入れちゃいましょう

実装

サンプルコードを載せておきます

#!/usr/bin/perl
use strict;
use warnings;
use feature 'say';

use Parallel::ForkManager;

my $methods = [
    'hoge',
    'foo',
    'bar',
];

my $pm = new Parallel::ForkManager->new(3);
# 子プロセスの最大値を指定し、オブジェクトを生成する

for my $method (@$methods) {
    $pm->start and next;
    # forkする

    if ($method eq 'hoge') {
        &hoge;
    }
    elsif ($method eq 'bar') {
        &bar;
    }
    elsif ($method eq 'foo') {
        &foo;
    }
    $pm->finish;
    # 子プロセスを kill する
}

$pm->wait_all_children;
# 子プロセスの終了を待つ
say "finish";

sub hoge {
    sleep(3);
    say "hoge";
}

sub bar {
    say "bar";
}

sub foo {
    sleep(5);
    say "foo";
}

結果

期待される出力順は、bar → hoge → foo の順ですが・・・

$ perl test.pl
bar
hoge
foo
finish

期待通りの動作でした
こんな感じで簡単にプロセスを fork し並列処理をすることが可能です

metacpan.org

今回は基本的なことしかしていませんが、今後もっと触っていきたいですねー

新しい環境に perlbrew を入れる時によく入れ忘れてエラーになるのでメモ

sudo yum install patch

上京エンジニアの2017年振り返り

今日で仕事納めでした、おっくんです。

今年の振り返りをさらっと書きます。

気がつけば、上京をして約半年が経った。
東京生活はもう慣れてきて標準語も板についてきた気がする。

さて、エンジニアとしてに振り返りをします。

良かったこと

  1. 優秀な会社で優秀なエンジニアの方と働ける環境を得ることができた
  2. Perl を習得してきた

1つ目

今年の3月まで大阪で勤めていた受託会社を退職し、東京の自社サービス中心の会社に勤めることができたことで、社内には優秀なエンジニアの方も多く素晴らしい環境を得ることができてよかったと思った。
もともと技術力に自信があるわけではなかったが、実際業務に携わると自分の技術力に低さをものすごく感じて刺激的な毎日を送っている。
この環境を存分に利用して自分自身成長していきたいと思う。

またこれって受託開発会社あるあると思うんですけど、作っては納品をするというサイクルをひたすら繰り返しており、品質ももちろん重要だがいかに早く納品することに注力し開発していた。
だから運用に携わることが少なかったので、自社サービスは作って終わりではなく我が子のような感覚ですごくやりがいを感じている。

2つ目

今まで PHP のみで開発を行ったことしかなくて、初めて違う言語をメインに業務を行った。
PHPPerl の影響を受けたとはいえど、習得するのにすごく苦戦した。
そしてまだ苦戦している。。

改善すべき点

  • 技術的なことや自分の考えのアウトプットが不足してしまった
  • 自身が運営しているサービスを成長させることができなかった
  • ネイティブアプリへの理解度が著しく低い

1つ目

とにかく技術ブログや Twitter を初めてみたがアウトプットが少ないのでもっとしないとあかんなあって思う。
特に来年は規模問わず登壇して自分の考えを発信したりしようと思う。

2つ目

趣味でもある Web サービスの開発でいくつかサービスを公開しているが悲しいことにほとんどアクセスがない。もちろんアイデア自体にも問題があるのかもしれないが来年こそは使われるサービスにしたい。
今は月々500円程度の超低スペックの VPS で複数サービス運用していてもなんら問題が起きないのが非常に悲しい!

3つ目

業務ではネイティブアプリの運用をメインに行っているが、ネイティブアプリの理解度が低く開発を進める上で困ることが多い。
今は個人のサービスを全て Web 作っているが、ネイティブアプリを作るなどしてみてもいいかもしれへんなーって思う。
理想は、Web サービス利用者増える → ネイティブアプリ版を作るという流れがええかな。

総括

振り返ってみるとなかなか濃い一年でした。
エンジニアとしての環境はすごく整っているので、生かすも殺すも自分次第やなって感じです。

うん、やっぱり文章を書くのが苦手! 来年は更新頻度を上げます。

年末年始は、ひたすら Perl 書きます。

良いお年をー

bash から fish に変えてみた

経緯

会社で使っている Mac が突如お亡くなりになり、bash の設定を一からまたするのがめんどくさかったので、「めんどくさいな〜」とボヤいてたら、先輩に「fish にすればいいじゃん」と言われた。

そもそも情弱な僕は fish なんか知らなくて「fish・・・なんやそれ」ってなってググりながら興味本位で入れてみたところから僕の fish は始まった。

感想

結論から言うと・・・
「すごくいい!!!」

なにがいいかと言うと、コンソールが三流な僕にも使いやすいです。
補完がきいたりして直感で操作できます。

あとは、何よりプラグインマネージャーである fisherman がかなり優秀です。
下記にもコマンドを紹介しようと思いますが、プラグイン管理がすごく簡単で三流な僕でも簡単に扱えちゃいます。

またテーマがかなり豊富にあるので色々選ぶのが楽しい!

では、簡単に導入手順を書いていきます。

導入手順

fish のインストール

brew install fish

シェルを登録

sudo vi /etc/shells

以下を追加
/usr/local/bin/fish

fish にシェルを変更

chsh -s /usr/local/bin/fish

fisherman をインストール

curl -Lo ~/.config/fish/functions/fisher.fish --create-dirs git.io/fisher

ちなみに削除は以下
fisher self-uninstall

以上!!!
導入も簡単です。

プラグイン等々

最後にプラグインを紹介しておきます。

テーマ

以下の URL から適当に選んで入れちゃってください。
github.com
僕は godfather を選びました!

fisher install omf/theme-godfather

エイリアス

エイリアスは、 balias ってのがあるので入れちゃってください。

fisher balias

まだまだ便利なのがたくさんあるのですが、以下の URL に僕のより丁寧に書かれているので、参考にしてください。
ちなみにクラスメソッドさんのブログを参考に導入してみました。
いつも良記事をありがとうございます!感謝しています!

dev.classmethod.jp

futurismo.biz

それでは、皆さん fish 生活を楽しんでください!!!

【書評】「エンジニアとして世界の最前線で働く選択肢」を読んでみた

どうもこんにちは。
最近 Kindle 買いましたおっくんです。

ずーっと通勤中とか出先で技術書読みたいなーと思うことが場面が結構あったんですけど、
技術書って分厚いし重いし、持ち歩きに不便やなーって思ったのでついに買っちゃいました Kindle Paperwhite!(端末割引のために Prime 会員にまでなりました)
なんで今まで買わんかったんやろ?って思うぐらい便利です。

そんな感じで、技術書だけでなく色々な本を良い漁ってます。
ですので、今回こちらの本の書評を書いてみたい思います。

読んだきっかけ

エンジニアの方でシリコンバレーで働くことに憧れを持っている人はたくさんいると思います。 僕もその中の一人で将来シリコンバレーでエンジニアとして活躍してみたいなあと思っていたので読みました。

シリコンバレーのエンジニア事情をググると、
- エンジニアは給料が高い
- サンフランシスコは物価が高い
- 突然のクビを言い渡されることがある

などの情報が多いと思います。
僕もシリコンバレーのイメージってそんな感じだったのですが、今回この本を読んで具体的にイメージすることができました。(僕が無知すぎなだけかもしれません・・・)

良かった点

全体的な章の構成や文章は読みやすく、さくさく読み進めることができました。
また、著者である「竜さん」の実体験を書かれているので読んでいてイメージがしやすかったです。

この本を読むまでは、向こうで働いてみることを考えた時に特に不安に感じるのが以下の 3点でした
- 英語力
- 技術力
- 面接フロー

しかし、もっと大切なことがありました。
そう。「ビザ」です。
恥ずかしながら「ビザ」については全く頭になかったので勉強になりました。

また、特にレイオフやファイアなど現場の経験に基づくリアルな話が貴重でおもしろかったです。

物足りない点

物足りなかった点を強いて挙げるとするのであれば、
以下ことをもう少し掘り下げてほしかったです
- 技術的な内容(困った体験談等)
- 勉強会やカンファレンスはどのように開催されているかなど
- スタートアップ界隈の情報

まとめ

ネット上の情報より細かく書かれており、このような書籍は少ないので、
シリコンバレーに少しでも興味があるエンジニアの方にはぜひオススメした一冊です。
読んでいるとなぜかワクワクしてすごくモチベーションが上がりました。

Perl で Amazon の Product Advertising API を叩いた話

AmazonProduct Advertising APIPerl で叩かないといけないことがあったのでその時のことをまとめておく。

初めに、cpan に何かモジュールがあるだろうと漁ってみたところ・・・
Net::Amazon metacpan.org

あたりが良さそうだったので、とりあえず入れてみた。

cpanm Net::Amazon  

早速叩いてみた。
Product Advertising API 用のアカウントを事前に作成する必要があります

今回は、ISBN を元に商品を取得したのでソースはこんな感じ。

#!/usr/bin/perl

use strict;
use warnings;

use Net::Amazon;
use Data::Dumper;

my $ua = Net::Amazon->new(
    associate_tag => '%ASSOCIATE_TAG%',
    token         => '%TOKEN%',
    secret_key    => '%SECRET_KEY%',
    locale        => 'jp',
);

my $item = $ua->search(
    isbn => '9784873110967'
);

unless ($item->is_success()) {
    print "$item->message() \n";
    exit;
}

warn Dumper $item;

1;

はい、めっちゃ簡単でした。
token はアクセスキーを入れてもらえば問題ないです。