大西ブログ

All your blog are belong to us

エンジニアの働きやすい職場を求めていろいろ回ってきました

最近の私は、5ヵ月に渡り、ITスタッフィングさんのITスタッフィング エンジニアスタイルで「エンジニアの働きやすい職場って?」を聞いて回る連載をしていました!先日公開された第5回で一旦連載終了です。

  1. リクルートマーケティングパートナーズさん
  2. クックパッドさん
  3. スマートニュースさん
  4. ヤフーさん
  5. ソニーさん

「エンジニアの働きやすい職場とは」ということで、オフィス環境に留まらず、仕事の進め方、評価とキャリアパスなど、突っ込んだ質問をしていく記事となり、自分の関心分野とも合致していたので非常に興味深い話を毎回聞けて楽しい連載でした。
毎回一緒にオフィス取材に行ってくださった池澤あやかさんとはこの連載が初対面でした。可愛らしいのは記事をご覧の通りですが、エンジニアとしても活躍されているだけあり、質問パートも鋭い質問をしていただき盛り上がりました。実際この連載僕要らなかったんじゃ、と何度も思いました…。

取材を引き受けていただいた皆さんも、エンジニアとして尖った方ばかりでしたし、自分と同じような、開発のマネージャーだったりエンジニアのキャリアパスを考える立場だったり、という方の話を聞くことができて、同じような悩みに共感したり、問題を解決するための仕組みに感心したり、学びのある話ばかりでした。同じような問題意識を持っていらっしゃる方に読んでいただければ幸いです。

各社を回り、「エンジニアの働きやすい職場」のやり方はたくさんあるけれども、成長機会がある、ということが非常に重要だと改めて感じました。エンジニアの成長と事業の成長をきちんとリンクさせられるのが一番だと思います。エンジニアが(それ以外の職種もですが)楽しく働けてかつ成長実感があり、それが事業の成功や会社の成長につながっている、そんな会社に弊社もしていきたいですね。

私は普段は京都に引っ込んでいるので、こういう機会があるのは本当にありがたいです。経営、マネジメント、エンジニアの評価・キャリアパス・採用などについてお話しする機会があれば飛びつきますのでご一報ください。

喰らえ10年鍛えた俺の test.pl !!

こんにちは、2011年くらいにディレクターになってめっきりPerl書かなくなった id:onishi です。

この記事は Perl5 Advent Calendar 2015 18日目です!

書き捨てのコードを test.pl という単一ファイルに __END__ と共に上に追加し続けて10年。3万行超に成長した俺の test.pl から厳選したコード群を喰らえ、という主旨の記事です。

今日のお品書きはこんな感じです。

( [PR]この目次ははてなブログの目次機能で自動生成しています )

ちなみに、書き捨てのコードから良いものは、プロジェクトのリポジトリに入れたり、~/bin/ に置いたりしています。今日は ~/bin/ に移った厳選処理も紹介しますね。
とにかく test.pl にいろんな処理が書かれているので、日付処理したい、とかメール送りたい、とか思ったらそれっぽい単語でファイル内を検索すると適切なコードスニペットが見つかるので業務効率に繋がっています。

list()

ORM使うほどでもないけどさくっとDB引きたい時の簡易DBIラッパーです。

use DBI;

my $host = {
    user => ['host1', 'user', 'pass'],
    blog => ['host2', 'user', 'pass'],
};

sub dbh {
    my $dbname = shift;
    DBI->connect_cached(
        sprintf(
            'dbi:mysql:database=%s;host=%s',
            $dbname,
            $host->{$dbname}->[0],
        ),
	$host->{$dbname}->[1],
        $host->{$dbname}->[2],
    )
}

sub item {
    my $list = list(@_) or return;
    $list->[0];
}

sub list {
    my ($dbname, $sql, @bind) = @_;
    my $dbh = dbh($dbname);
    my $sth = $dbh->prepare_cached($sql);
    $sth->execute(@bind);
    return $sth->fetchall_arrayref({});
}


こんだけ書いておけば list() と item() で以下みたいなコードが書けます。

my $user = item(
    user => 'SELECT * FROM user WHERE name = ?',
    'onishi'
);

my $entries = list(
    blog => 'SELECT * FROM entry WHERE user_id = ?',
    $user->{user_id},
);

print map { $_->{title} . "\n" } @$entries;

数クエリで済みそうな集計を雑にしたい時に使ってます。

fotolife

フォトストレージサービスはてなフォトライフに簡単にファイルをアップロードするコマンドです。Config::Pit で username, apikey, folder を指定しておきましょう。

$ fotolife ファイル
$ fotolife URL

第一引数にファイルパスかURLを受け取り、自分のフォトライフにアップロードし、アップロード結果を出力します。
結果はこのように、はてなブログ用記法、はてなダイアリー用記法、フォトライフpermalink、画像permlinkをまとめて出力する親切設計です。

$ fotolife some-file.jpg
[f:id:onishi:00000000000000p:plain]
[f:id:onishi:00000000000000p:image]
http://f.hatena.ne.jp/onishi/00000000000000
http://cdn-ak.f.st-hatena.com/images/fotolife/o/onishi/000000/00000000000000.png
#!/usr/bin/env perl
use strict;
use warnings;

use Config::Pit;
use FileHandle;
use LWP::Simple 'get';
use XML::Atom::Entry;
use XML::Atom::Client;

my $file = shift;

my $type = $file =~ /(png|gif|bmp)$/i ? lc($1) : 'jpeg';
my $t    = substr($type, 0, 1);
my $ext  = $type eq 'jpeg' ? 'jpg' : $type;
   $type = "image/$type";

my $image;
if ($file =~ m{https?://}) {
    $image = get($file);
} else {
    local $/; # slurp mode
    my $fh = FileHandle->new($file) 
        or die "cannnot open $file: $!";
    $image = $fh->getline;
}

my $config = pit_get("hatena.ne.jp", require => {
    username => 'username',
    apikey   => 'apikey',
    folder   => 'folder',
});
my $username = $config->{username};
my $apikey   = $config->{apikey};
my $folder   = $config->{folder};

my $PostURI = 'http://f.hatena.ne.jp/atom/post';

my $api = XML::Atom::Client->new;
$api->username($username);
$api->password($apikey);

my $entry = XML::Atom::Entry->new;
$entry->content($image);
$entry->content->type($type);
$entry->title('');
my $dc = XML::Atom::Namespace->new(dc => 'http://purl.org/dc/elements/1.1/');
$entry->set($dc, 'subject', $folder) if $folder;
my $EditURI = $api->createEntry($PostURI, $entry) or
  die $api->errstr;

$EditURI =~ /(\d+)/ or die $EditURI;
my $fototime = $1;
my $initial  = substr($username, 0, 1);
my $date     = substr($fototime, 0, 8);
print "[f:id:$username:$fototime$t:plain]\n";
print "[f:id:$username:$fototime$t:image]\n";
print "http://f.hatena.ne.jp/$username/$fototime\n";
print "http://cdn-ak.f.st-hatena.com/images/fotolife/$initial/$username/$date/$fototime.$ext\n";

長い。あと、WSSE認証使ってますけど最近はOAuthでも書けます。
はてなフォトライフAtomAPI

wq

みんな大好き、Web::QueryjQuery ライクに scraping できます。

#!/usr/bin/env perl
use strict;
use warnings;

binmode STDOUT, ':utf8';

use Web::Query;

my $url      = shift or die;
my $selector = shift or die;
my $limit    = shift || 0;

my $i;
wq($url)->find($selector)->each(
    sub {
        printf("%s\n", $_->text);
        $limit && ++$i >= $limit and exit;
    }
);

こんな雑なスクリプトを wq という名前でPATHが通ったところに用意しておくと、URLとセレクタを引数にこんな感じで簡易スクレイピングコマンドとして使えます。

$ wq http://www.hatena.ne.jp 'ul#servicelist li' 5
    ブックマーク ネット上にお気に入りを保存できるサービス。ネット上の旬な話題がすぐわかる
    ブログ 書き残そう、あなたの人生の物語。だれでも使いやすく簡単に書ける、はてなの新しいブログ
    B!KUMA “がんばる私”に、ちょっと一息。恋愛、レシピ、おしゃれ、育児など女性が気になる話題をお届け
    ニュース ネットで旬な話題を分かりやすく紹介。地元発の京都情報、ひとこまマンガも楽しめるニュースサイト
    人力検索 調べたいことを誰かが自分の代わりになって調べてくれる人力検索サービス

(はてなトップページから「はてなのサービス」を5件取得する例)

セレクタ指定して取得した数字を別のサービスに投げたりすると便利なんじゃないでしょうか。

punycode

日本語ドメインでイラッとすることが多いので punycode の自動変換をします。

#!/usr/bin/env perl
use strict;
use warnings;

use IDNA::Punycode;
use Encode;

binmode STDOUT, ':utf8';

idn_prefix('xn-');

my $word = shift;

if ($word =~ /^xn-/) {
    print join('.', map { decode_punycode(Encode::decode('utf-8', $_)) } split(/[.]/, $word)) . "\n";
} else {
    print join('.', map { encode_punycode(Encode::decode('utf-8', $_)) } split(/[.]/, $word)) . "\n";
}

こんな感じ。

$ punycode xn--wgv71a119e.jp
日本語.jp

$ punycode 日本語.jp
xn--wgv71a119e.jp

イラッとしなくなりました。

statuscode

任意のステータスコードを返すサーバーをさっと建てたいこと、ありますよね!(無い)

#!/usr/bin/env perl
use strict;
use warnings;

use HTTP::Daemon;
use HTTP::Status;
use HTTP::Response;

my $d = HTTP::Daemon->new(LocalPort => shift || undef) || die;
print "Please contact me at: ", $d->url, "\n";
while (my $c = $d->accept) {
    while (my $r = $c->get_request) {
        if ($r->method eq 'GET' and $r->url->path =~ m{/(\d+)}) {
            my $code    = $1;
            my $header  = HTTP::Headers->new( 'Content-Type' => 'text/html' );
            my $message = status_message($code) || '';
            my $res     = HTTP::Response->new(
                $code,
                $message,
                $header,
                "<title>$code $message</title><h1>$code $message</h1>"
            );
            $c->send_response($res);
            warn "$code $message\n";
        } else {
            $c->send_error(RC_FORBIDDEN)
        }
    }
    $c->close;
    undef($c);
}
$ statuscode
Please contact me at: http://localhost:53812/

サーバーが立ちます。
http://localhost:port/200 のように任意の数字をパスに指定するとその数字のステータスコードを返します。なんか便利ですね!

結びの言葉

10選くらい挙げたかったのですが、意外と仕事のコードと密なコードが多すぎて紹介できなくて飽きてきたのでここらへんで終わります。
1ファイルを眺めるだけで10年の歴史が眺められて面白かったです。

僕とはてなと開発合宿

はてなスタッフアドベントカレンダー2015 を始めます!

はてなスタッフアドベントカレンダー2015 - はてなスタッフアドベントカレンダー

というわけで初日は私、 id:onishi がつとめます。今日から25日間、スタッフによりなんからの「はてな」に関するエントリーが続く予定ですのでお楽しみに!

初日ということで何を書こうかなと思いましたが、今日は「僕とはてなと開発合宿」について書いてみます。

はてなの開発合宿の歴史

はてなで初めて開発合宿は2005年の事でした。皆さんご存じ「はてなブックマーク」は合宿で産声を上げました(ここらへんに詳しい)。
その後数年は、「少人数で新サービスを作る合宿」というのを行っていました。当時の新サービスは合宿ドリブンで作られたものが多いです。

最近のはてなは開発者の人数も増えたため、たくさんの人数で出かけるイベント型の合宿を行っています。チームを組んで2泊3日で、各チームの成果を発表するという流れです。
去年行われた合宿をもとに、合宿の企画・運営について記事を書きましたので、そちらに詳しいです。

また、合宿の参加者の記事も書かれたのでぜひご覧ください。

僕と開発合宿

最初の、はてなブックマークの開発合宿にも参加し、その後もほとんどの開発合宿に大なり小なり関わってきました。

最近でこそマネジメントっぽいことをしていますが、僕はもともとは長い間エンジニアをやってきました。長くやっていたため、どちらかというとレガシーなサービスを任されることが多く、開発合宿は普段できないような開発をする絶好の機会となっていました。

そのため開発合宿では異常にテンションが上がり、夜中までコードを書きまくるという体験を心から楽しんできました(夜中まで書かなきゃいけないってことは全然無く、寝る人は寝てます)。

その後、ディレクター、プロデューサー、今の開発本部長、とやれることは増えていったのですが、「合宿好き」の血は体に刻まれてしまい、今はもっぱら合宿を企画する、という形で合宿に参加しています。

今は業務でコードを書く事はほとんど無いのでそういう意味でも合宿は自分にとって貴重な機会になってきました。

今年の合宿も(なんと)明日から始まります。去年は約40人参加でしたが、今年は約50人の参加を予定しています。無事合宿が成功し、来年も実施できるようにがんばります!参加者の人も楽しんで、目的意識をしっかりもって取り組んでください!!

というわけで、なんか真面目な感じになってしまいましたが、次は新入社員の id:stefafafan です!楽しいエントリ期待!

お菓子工場の夢

久しぶりに夢日記を書く。


お菓子を作る工場を見学している。巨大な機械の中を縫うようにベルトコンベアが走り、その上を低い円柱状のお菓子が流れていく。
行程が進み、成形され、ミントブルーにコーティングされたお菓子たちは、あるものはさざ波のような、またあるものはお城のような、不思議に動きをもっている。
やがてパッケージにつめられたその箱には「12のうごき、12のあじ」と書かれていた。
色は一色なのに動きと味にバリエーションがあるのが新しい!と思って目が覚めた。

ブログを始めたきっかけ

今週のお題「私がブログを始めたきっかけ」に参加します。
もともとはgeocitiesでウェブ日記を書いていた。HTML手書きで友達だけが見てるような。という話は以前「僕のオープンインターネット - 大西ブログ」で書いた。

その後、はてなに入って人力検索サイトを運営していたわけだけど、そのサイトの中に「スタッフ日記」というコーナーを作った。簡単な日記を書ける仕組み。入社して独力でやった初めての新規の機能だった気がする。diary.cgi。.cgi かよって感じだけど当時は社内にフレームワークもなく、Apache + CGI で動かしていた。その後 mod_perl (もちろん1) 導入して、cgiApache::Registry で動かすようにして(use strictを学んだ)、その後フレームワークが作られた。

話が逸れた。

2001年8月から開始したスタッフ日記コーナーは当時のスタッフ3人で更新していた。その後2003年にはてなダイアリーというサービスを作って、スタッフ日記はそれぞれの日記にインポートした。
これが最初のエントリ。今読むと緊張感がある。はてなの使い方提案 - 大西日記 - はてなダイアリー
はてなに入社して最初の仕事が日記の仕組みを作ることで、その後何年にもわたって日記(ブログ)システムをエンジニアとして運用して、その後はてなブログというサービスをディレクターという立場で作ることになるのであった。
ブログサービスを始めたきっかけでした。こちらからは以上です。