そんな今日この頃でして、、、

コード書いたり映画みたり。努力は苦手だから「楽しいこと」を探していきたい。

クソコードレビュー会なるものに参加してきた

f:id:blue1st:20160818210740j:plain

転職活動でもお世話になったCodeIQで↓のような問題があったので回答を出したところ、 レビュー会への招待が来ていたので行ってみた!

codeiq.jp


問題

出題はじゃんけんを行うプログラムをリファクタリングするという問題。

「標準入力として与えられた文字列を2人分のじゃんけんの手として解釈して勝敗を標準出力する」というもの。

元はnode.jsだったのだが、僕はjsが不慣れだったりもするのでperlで再現。

sub func02 {
    my ( $a, $b ) = @_;

    if ( $a eq 'g' ) {
        if ( $b eq 'c' ) {
            print "win";
        } elsif ( $b eq 'p' ) {
            print "lose";
        } else {
            print "draw";
        }
    }

    if ( $a eq 'c' ) {
        if ( $b eq 'p' ) {
            print "win";
        } elsif ( $b eq 'g' ) {
            print "lose";
        } else {
            print "draw";
        }
    }

    if ( $a eq 'p' ) {
        if ( $b eq 'g' ) {
            print "win";
        } elsif ( $b eq 'c' ) {
            print "lose";
        } else {
            print "draw";
        }
    }
}

sub func01 {
    my $line = shift;
    my ( $a, $b ) = split / /, $line;
    &func02( $a, $b );
}

my $line = <>;
chomp $line;
&func01($line);

すごーくベタな実装。

コード自体は目的どおり正しく動作するが・・・

続きを読む

超映画批評のスコアをスクレイピングする

昨日だか一昨日だかに超映画批評をスクレイピングしてランキング化するサイトを作った的なホットエントリがあって(リンクはしない)、 「他人様のコンテンツを勝手にぶっこ抜いてウェブサービス化するのはモラル的にあかんやろ・・・」と思ったりしたところ。

movie.maeda-y.com

厳密にアウトの線引きをしようと思うと意外と悩ましいところだけど、 サイトの売りであるところの本文を前文だけとはいえ勝手に持ってきて表示して、 結果的にアクセス機会を奪ってしまうような作りは流石にマズイんじゃないかと僕なりには思う。

じゃあまとめサービスとかで手動でランキング化したリンク記事は良いのかというとそれも微妙だけども。


それはそれとして、超映画批評は僕もちょくちょく覗いていて、 「なるほどなぁ」と思ったり「それは違うよなぁ」と思ったり暇なときに観る映画の参考にしたりする。

で、確かにランキングが欲しいと思うことも少なくない。

スクレイピングの練習問題としては手頃だし実用的で面白い気もするので、 自分で使う用にスクリプトを組んでみた。

(もしかすると人によってはダブスタに見えるのかもしれないけど、 僕なりには個人の利便性の追求の範囲ならOK、というか本質的には止めようがないと思ってる)

続きを読む

最近気になった技術ネタ

ここのとこ忙しくて、興味あることもやりたいこともいっぱいあるんだが全然消化できてない・・・


OSの通知センターにRubyからメッセージを投げる

前回紹介したterminal-notifierには、Rubyから使えるterminal-notifier-guardというのがある。

github.com

そんなわけでRubyの勉強も兼ねて

あたりを使ってはてなブログの当日のアクセス数を取得して通知するツールを書いてみた。

github.com

で、ツール自体は一応予定通り動きはしたんだが一つ誤算。

OSXてデフォではcron動いてないんですな。

定期的にコマンド叩かせようと思ってたんだけど、正攻法でlaunchdを記述するにしろ無理やりcron動かすにしろ面倒くさそう。

そのうち定時実行の仕組みを内部に含む形に書き直そうと思う。


Disque

会社のツールではRedisをジョブキュー的に使ってたりもするんだけど、どうやらそのRedisの作者がまさにジョブキュー用のプロダクトを作成してるっぽい。

github.com

qiita.com

そのうち試してみたい。


Electron

Visual Studio Codeで使われていることでもお馴染みElectron

今のところ紹介記事をなぞって動かしてみた程度だけど、本業のウェブ系のスタイルでデスクトップアプリが開発できるのはそこはかとなくワクワク感ありますな。

electron.atom.io

qiita.com

プラットフォーム・ブラウザ間での差異を気にしないでも済むので、例えば管理画面なんかでも使い勝手良いんじゃないかって気がする。


サブドメインワイルドカード指定

新しいのを立ち上げるたびに/etc/hostsを追記するのは面倒くさいし、かといってプライベートでDNS立ち上げるのもなーと思っていたけど、そういえばこの手がありましたな。

qiita.com

クライアントの数が少ない分にはこれが一番楽かもしれん。


bacon.js

同僚におふざけでIQ145本を貰ったんだけど、関数型プログラミング以前に論理展開が飛躍しすぎてついていけないし文章的にも厳しいものを感じて放置気味・・・

本自体はアレなんだけど「じゃあ実際のところ関数型プログラムてどういうの?」という興味だけは沸いたりはする。

qiita.com

さて、そんな中でキーワードとして目についたのがbacon.js

www.publickey1.jp

iQ145本ではなんでわざわざ配列でインプットする必要があるのかビタイチ分からなかった(「クール」とか言われましても・・・)のだけど、↑のスライドでスッと理解できたw

機会見つけて使ってみたい。


Heroku Docker

Heroku | Introducing 'heroku docker:release': Build & Deploy Heroku Apps with Docker

Herokuの'docker:release'の動き | SOTA

HerokuでDockerが動かせようになるの!?と思ったらそういうことではなくて、どっちかというとHerokuの環境を手元で再現できてそのままデプロイできる(=デプロイしてみたら何故か動かないという事態を避けられる)という感じらしい。


YAPC::Asia 2015

yapcasia.org

出不精マンなんでこれまで勉強会とかイベント事には関わってこなかったけど、今年で最後ということで思い切って個人スポンサーチケット買ってみた。

8月が楽しみ。

Perlの外部コマンド実行についての諸々

Mojoliciousで作ったウェブアプリからバッチを叩きたいという案件があって外部コマンド実行について試行錯誤したのでまとめてみた。

Perlではsystem()exec()``なんかで外部コマンド実行できるが、それぞれで挙動が異なる。

そこまで時間のかからない戻り値も見ない処理なら特に何も考えずに``を使うところだが、処理に時間がかかりウェブアプリ側がそれを待つとタイムアウトしてしまうような要件だったので、特にバックグラウンド実行まわりについて調べてみた。

1. ``による実行

戻り値: 実行結果

実行結果がそのまま返ってくる。

$ perl -e '$r=`echo test`;print"ret:$r\n"'
ret:test

単純にタイプ数が少ないこともあって雑にスクリプト書く時はこれを使う機会が多いのだが・・・

バックグラウンド実行

&つけても何かダメっぽい。戻り値の出力を待ってしまうのだろう。

$ time perl -e '`sleep 5s&`;print"done\n"'
done

real    0m5.099s
user    0m0.051s
sys 0m0.040s

2.system()による実行

戻り値: 実行ステータス

実行ステータスが返ってくるらしい。

成功なら0、失敗ならそれ以外。

$ perl -e '$r=system"echo test";print"ret:$r\n"'
test
ret:0
$ perl -e '$r=system"ero test";print"ret:$r\n"'
ret:-1

バックグラウンド実行

普通に&を後ろにつけることで実現できる。

sleepを待たずにperl自体は終了していることが確認できる。

$ time perl -e 'system"sleep 5s&";print"done\n"'
done

real    0m0.097s
user    0m0.039s
sys 0m0.051s

下の例だと(出力順序は実行時状況に依存しちゃうんで必ずではないけど)コードの記述順序とは逆に出力されていることから、一応バックグラウンドで動いていることが見て取れると思う。

$ perl -e 'system"echo echo&";print"print\n"'
print
echo

3.exec()による実行

戻り値、というか・・・

スクリプト自身のプロセスが指定したコマンドに変化する。

$ perl -e '$r=exec"echo test";print"ret:$r\n"'
test

この例でいうとそのままecho testに変化してしまうので、その後の$retへの挿入やprintが発生しない。

実用上この関数だけで使う機会はあまり無さそう。

fork()を利用して

ちょっと面倒ではあるが、fork関数を利用することにより今回の要件も実現できる。

fork()はプロセスを分岐させ、戻り値として子プロセスIDを返す。(呼ばれた側の子なら0が返る)

したがって戻り値で判定し、子プロセス側をexec()で変身させる等で任意のコマンドのバックグラウンド実行ができる。

$ perl -e '$pid=fork();exec"echo child"unless$pid;print"parent\n"'
parent
child #親プロセス終了後に出力されている

結論

ひとまず今回の「単にバッチを叩きたい」だけならsystem()関数に&を付けて渡すのが楽そう。

バッチの状況やら戻り値やらを使いたいぜってことならfork()関数を絡めた記述を検討するという感じだろうか。

初めてのPerl 第6版

初めてのPerl 第6版

今週気になった技術ネタ

常々このブログはエンジニアっぽさが足りてないと思ったので水増し補充。

ブクマを棚卸しして振り返る意味も込めて毎週末続けていきたいなーと思う。

ソース検索に便利なPlatinum Searcher

monochromegane/the_platinum_searcher · GitHub

ガラケー向けのサービスなんか扱ってるとよくあることなんだけど、文字コードが混在してる環境はソースを検索しづらいのが辛いところ。

速度面に関しては特に検証してないけれど、少なくとも文字コードに左右されずに横断的に検索できるのは相当に有難い。

いつの間にかMacにはhomebrewからも入れられるようになってた。


命名規則について

英語苦手系エンジニアなんでこのへんは勉強していきたいところ。

正しいコーディングが身につくエンジニア英語の手引き 〜文法とクラス/メソッド、命名規則〜 | Find Job ! Startup

特に取得する系のメソッドの動詞を使い分けるのは、後でパフォーマンスを改善していく際に当たりをつけやすくて良いなと思った。

railsとかのどうでもよいメモ: メソッド名の動詞


CSVファイルをSQLで扱う

Run SQL directly on CSV files | Text as Data | q

$ q "SELECT COUNT(*) FROM ./clicks_file.csv WHERE c3 > 32.3"みたいな感じで使える。

内部的には一旦sqlite3にオンメモリで入れてるだけらしいのであまり大きいファイルには使うべきじゃないが、ちょっとした集計になら便利そう。


mysqlコマンドでのテーブル名の補完

mysqlコマンドで、テーブル名とかカラム名の補完(completion)をする方法 - (ひ)メモ

--auto-rehashオプションを付けてmysqlコマンドを打つ、もしくは入った後にrehashコマンドで。


MySQLからコマンドに渡しやすい形で結果を取得する

MySQLのgroup_concatで複数レコードを1行にまとめる - 文系プログラマによるTIPSブログ

集計スクリプトの引数とかコードへベタに記述する用の結果を取得したい場合、普通にターミナルからSELECT文を叩くと加工が必要で面倒くさかったりする。

そんなときこのGROUP_CONCAT使えばコピペで使いやすい形で出力できる。

SELECT GROUP_CONCAT([カラム] SEPARATOR '[区切り文字]') FROM 〜みたいな感じ。


Perlワンライナー備忘録

Perl ワンライナー [ 一行野郎 OneLiner ] 勉強中。

Perlおじさんな割にはあんまり使いこなせてないのよなってことで。

なんだかんだで業務じゃ無理くりシェルやらawkやらでこなしたりちゃう(で、出力結果を手修正する)ことが多いのだけれども、こっちのほうが自由度も高いし書きやすいはずなので。


とりあえず個人的に使用頻度が高そうなutf8エンコードで作ったCSVファイルをWindows機のユーザに渡すために変換するワンライナーを記述してみた。↓

$ perl -MEncode -i -nle 'Encode::from_to($_,"utf8","cp932");print $_¥r¥n' [FILE]
  • -MオプションでEncodeモジュールを指定
  • -iオプションで一時ファイルを作るよう指定
  • -nで引数のファイルを展開して一行ずつ実行
  • -lオプションでchompして要らない改行を取り除く
  • エンコード変換して新たな改行コードを加えて出力する

プロセスをバックグラウンドに移す

時間がかかる集計スクリプトなんかを実行する時には$ nohup [コマンド]&でバックグラウンド実行して接続が切れたりログアウトしても実行し続けられるようにするのが良いのだが、うっかり忘れてしまった時に。

うっかりnohup無しで長時間かかるコマンドを実行したときに後から終了しないようにする - Glide Note - グライドノート

要は

  1. Ctl+Zで休止
  2. jobsでジョブ番号を確認
  3. bg [ジョブ番号]でバックグラウンド実行
  4. disown %[ジョブ番号]でログアウト後も実行されるようにする

という感じらしい。


無料の技術書

無料でダウンロードできるIT技術系電子書籍(EPUB/PDF)一覧 - Build Insider

とりあえずProGitあたりは読んでおこうかなと。


なんか初回だから盛りだくさんになってしまった。。。