アルパカ三銃士

〜アルパカに酔いしれる獣たちへ捧げる〜

IPアドレスとサブネットマスクの考え方

久しぶりに考える機会を得たのでメモ。
@aokabin_ さんに教えてもらいました。

ネットワークアドレス 133.13.50.110 を与えられていて、サブネットマスク 255.255.255.0 を与えられている時、で降るとゲートウェイはどれくらいの範囲を割り当てられているかという考え方ですが、

255.255.255.0 を 32 bit の 2 進数へ修正すると 11111111 11111111 11111111 00000000 となる。この時下位 8 bit は 0 なので 255 - 0 = 255 なので 133.13.50.0 ~ 133.13.50.255 まで得ることが可能。

サブネットマスク 255.255.192.0 を与えられている時、同様に 2 進数へ変換すると
11111111 11111111 11000000 00000000 となる。この時 9 bit ~ 16 bit は 192 なので 255 - 192 = 63 そしてこの時下位 8 bit は 0 なので 255 - 0 = 255。つまり 133.13.0.0 ~ 133.13.63.255 まで得ることができる。

goveralls で カレントディレクトリのみ coverage を出したい

goveralls ってこれ。 github.com

よく travis-ci で goveralls を使って coverage を出すようにしてますが、今回プロジェクトディレクトリ内に example ディレクトリを入れてて、いつも通り goveralls を実行すると example ディレクトリ内まで見てしまい coverage を出すことができない問題がありました。
そのプロジェクトがこれ。 github.com

このプロジェクトの詳細は後日書きますが、goveralls の問題は以下に実行するようにすれば解決できました。
goveralls -package "."

最終的な .travis.yml はこんな感じになりました。

language: go
sudo: false
go:
  - 1.7
  - 1.7.5
  - 1.8
  - tip
script:
  - make test
after_script:
  - go get github.com/mattn/goveralls
  - goveralls -package "." -service=travis-ci

Okinawa.pm #4 に参加した

運営側でもありますが、最近やってた XS の知見を共有するために参加しました!

XS 始めは結構苦労したなぁ...

List::Flatten::XS をリリースしました

先日 Okinawa.pm の Slack で複雑なリストのフラット化を行う話で盛り上がりました。(Okinawa.pm の Slack へはこちらから参加できます!)
その中で @yasuXS さんが考案したフラット化のコードがシンプルの上に、フラット化が高速でした。以下がそのコードになります。

use strict;
use warnings;
sub flatten {
    my @args = @_ > 1 ? @_ : @{$_[0]};
    my @result;
    while (@args) {
        my $a = shift @args;
        if (ref $a eq 'ARRAY') {
                unshift @args, @{$a};
        } else {
                push @result, $a;
        }
    }
    return @result;
}

my $arr = [[1,2,3],[4,5,[6,7,[8,9,[1,2,3]]]]];

print flatten($arr);

リストを shift を使って取り出し、もし配列リファレンスなら、デリファレンスして元のリストへ unshift をして、それ以外なら返り値ように用意した変数へ push するといったシンプルなコードです。
これを XS で書き直そうと思い、List::Flatten::XS を作成し始めたんですが、メモリリークで悩んでいたところ、@tompng さんにRuby の flatten のコードを参考にしてはという助言をいただいて、「引数に渡されたレベルに合わせてフラット化する」機能も取り入れました。
以下は Pure Perl と List::Flatten::XS のベンチマークに使ったコードとその結果です。

use strict;
use warnings;
use v5.10;
use Data::Dumper;
use List::Flatten::XS 'flatten';

use Benchmark qw/cmpthese/;


my $arr = [[[[[[[[[[[[1], 2], 3], 4], 5], 6], 7], 8], 9], 1], 2], 3];

cmpthese 0, {
    nonrecursive => sub { flat($arr) },
    xs => sub { flatten($arr) }
};

sub flat {
    my $list = shift;
    my @args = @{$list};
    my @result;
    while (@args) {
        my $a = shift @args;
        if (ref $a eq 'ARRAY') {
            unshift @args, @{$a};
        } else {
            push @result, $a;
        }
    }
    return @result;
}

結果

                 Rate nonrecursive           xs
nonrecursive 117657/s           --         -70%
xs           394824/s         236%           --

約 2 倍の速さは出てるっぽいです。
以下が SYNOPSIS を少し弄ったコードです。ぜひ試してみてください。

#!/usr/bin/env perl

use strict;
use warnings;
use v5.10;
use Data::Dumper;
use List::Flatten::XS 'flatten';
 
my $ref_1 = +{a => 10, b => 20, c => 'Hello'};
my $ref_2 = bless +{a => 10, b => 20, c => 'Hello'}, 'Nyan';
my $ref_3 = bless $ref_2, 'Waon';
 
my $complex_list = [[["foo", "bar", 3], "baz", 5], $ref_1, "hoge", [$ref_2, ["huga", [1], "K"], $ref_3]];
 
# got: ["foo", "bar", 3, "baz", 5, $ref_1, "hoge", $ref_2, "huga", 1, "K", $ref_3];
my $flatted = flatten($complex_list);
say Dumper $flatted;
say "-"x20;

# got: ("foo", "bar", 3, "baz", 5, $ref_1, "hoge", $ref_2, "huga", 1, "K", $ref_3);
my @flatted_with_array = flatten($complex_list);
say Dumper @flatted_with_array;
say "-"x20;

# got: [["foo", "bar", 3], "baz", 5, $ref_1, "hoge", $ref_2, ["huga", [1], "K"], $ref_3]
my $flatted_level = flatten($complex_list, 1);
say Dumper $flatted_level;
say "-"x20;


# got: (["foo", "bar", 3], "baz", 5, $ref_1, "hoge", $ref_2, ["huga", [1], "K"], $ref_3)
my @flatted_level_with_array = flatten($complex_list, 1);
say Dumper @flatted_level_with_array;

最後に

明日は Okinawa.pm #4 です。
そこで XS で得た苦労して知見を共有しようと思います。

github.com

MDR-1000X っていうヘッドホン買ったぞォォォォ!!

3 月入るまでクソ忙しい環境をよくぞ耐え抜いたということで自分へのご褒美としてヘッドホンを買うことにしました。
Premium reseller でアルバイトしていた頃によく SHUREAKG を買った方が良いよ!とアドバイスもらっていたのですが、それらの意見を無視して、SONY の MDR-1000X というノイズキャンセリング搭載のヘッドホンを購入しました。
amzn.asia

ノイズキャンセリング機能が搭載されたヘッドホンを買った理由として、家や大学など騒音が激しい環境で作業に集中したかったからです。

f:id:codehex:20170315160353j:plain
バーン!!
f:id:codehex:20170315160358j:plain
ケースがオシャレ!!しかも航空機内で使えるプラグまで入れることができる!!
f:id:codehex:20170315160346j:plain

しかし、このヘッドホンが凄いのはノイズキャンセリングで終わらないところです。
ノイズキャンセリング機能を使うと周囲の音をある程度抑えることができ、音楽に集中することができますが、その分重要なアナウンスを聞き逃してしまったり、会話をするためにノイズキャンセルの機能をオフにしなければならないということが起きてしまいますね!

MDR-1000X ならそれらの問題を解決してくれます。 例えば音楽を聴きながら、周囲の音を取り込む新機能「アンビエントサウンドモード」。
ボタン一つで簡単に「ゴー」というような低域のノイズをカットしつつ、人の声などの中域から高域くらいの音を拾ってくれます。

もっと凄いのが「クイックアテンション」機能。
とっさに外の音を聞きたい場合右側のハウジングを全面を触れると、音楽の音量を絞り、まるでヘッドホンをつけてない状態のように外の音を聞き取ることができます!!

詳しくは【本日よりご予約開始】SONY新製品MDR-1000XやXBA新シリーズも! -eイヤホンのブログでも読むと、どういう機能があるのかというのが分かりやすいと思います。

付けた感じ、重さは全く感じません。しかし若干圧迫感があるのかなという感じがします。
それ以外は本当に満足しているので最高です!!

これであと 10 年頑張れるぞ!!!

YAPC::Kansai 行ってきた感想

全体的に良かった。トークもしました。

特に

  • Webアプリケーションのキャッシュ戦略とそのパターン
  • Perl ウェブ開発の中世 〜CGIPlack の間〜
  • はてなシステムの考古学

の3つが良かった。 moznion さんの「Webアプリケーションのキャッシュ戦略とそのパターン」のスライドで一番印象的だったのが引用。

この辺時間があった時読んでいきたい。 パターンに名前をつける話の時に、設計段階でその部分部分に何かしら名前をつけておくことで、コミュニケーションがしやすいというのがあったのですが、これは真似していきたいと思いました。(キャッシュの話ももちろん良かった!!)

残りの二つの話が特に温故知新のテーマにぴったりな良い話でした。凄く面白かった!!!

xtetsuji さんの「Perl ウェブ開発の中世 〜CGIPlack の間〜」、CGI については聞いたことがあるという程度だったので、リクエストが来た時にスクリプトが実行されてその結果を返していたという点は驚きました。まじかよ CGI となった瞬間です。あと、Common Gateway Interface という名前の割に全然 Common じゃねえ!という点、Plack の方が共通化できてたんですね!流石 PSGI

motemen さんの「はてなシステムの考古学」。はてなの歴史(時代毎の開発体制、サービス)についての話でした。独自のWAFを持っていて、時代毎に求められているものをちゃんと見極めた上で、何回か作り直していたらしいです。メンテナンス性ってやっぱり大事なんだなとつくづく思いました。

今回のYAPCも前夜祭、懇親会を含めとても楽しい思い出になりました。Perlに対するモチベーションも上がってきたので何かやろうと思います。 運営スタッフの皆様本当にお疲れさまでした。そしてありがとうございました。

YAPC::Kansai で Perl と Go のトークをしてきました!!

20分喋ってきました。いやー緊張しますねやっぱり。

20分ということもあって内容を少し省いて喋ったので、伝えたい部分が伝えられなかったような気もします。 まとめられてる記事も発見したのでよろしければどうぞ

qiita.com

言い足りなかった部分として

  • Go では Perl でいう push は append に値する
  • capacity を指定してスライスや map を作成すると realloc が走らないため高速
  • 生成したプロセスを管理する時はスライスに type Process を追加する
  • Process.Wait でプロセスが死んだか確認する
  • 死んでいた場合, スライス内のそのプロセスの位置に nil を代入してあげる
  • 新たに生成した type Processnil の位置に置く
  • 全ての要素が nil ではない場合 append する
  • 参考

この辺。
初めてのトークYAPC だったということが凄い光栄だと思ってます。
見に来てくださった皆さんありがとうございました。

そしてこれはルートビアです。
全体の感想は後ほど👍