Blog::kfly8

prove t/foo/bar/baz.t

Hello Android

いまさら、、あんどろいどにはろーわーるどしました(え

備忘録です。 MyFirstAppを作成するところまでは手順通りだった。それだけなのにつかれる事態になってしまった><

ant debugでまずはまった

まず、ant がないと怒られる。次で解決

brew update
brew install ant

build.xmlがなくて、buildできない

android update project --name MyFirstApp --target android-19 --path ~/android/workspace/MyFirstApp

apkを端末にインストールできなくてはまった

error: device offline

  • adb devicesしてもでてこない。端末外して、次をしてから、接続し直して解決。
adb kill-server
adb start-server

error: more than one device and emulator

  • 端末を指定して解決
% adb devices
List of devices attached
emulator-5554   offline
XXX      device
% adb -s XXX  install bin/MyFirstApp-debug.apk

とりあえず、はろーあんどろいど

isucon に負けて悔しいので、問題を速く解決するためのパターンを考えてみた

isucon決勝からもうだいぶ日が経ってしまいました、、その間、負けて、id:karupanerura先生に、げきおこされる夢も見ました。

振り返ります。

isuconでスコアを残しているチームは技術力もさることながら、 問題解決能力が高いと思うのです。もの凄く。

近づくにはどうすればいいんだろうと、頭の整理のために、 自分が普段感じている問題解決のパターンを書いてみました。 特にisuconの反省なので、与えられた問題を良い感じに速くするための解決方法寄りだと思います。

パターン


  • 処理*1しない
  • 処理したらメモしておく
  • 処理の下準備をする
  • 処理をまとめる
  • 処理を少なくする

  • 処理を外にお願いする
  • 必要な分だけ、処理する
  • 処理を得意な人にお願いする
  • 処理関係者を減らす

  • 処理するヒトを増やす
  • 処理できるヒトを良くする

  • 仕様を仕様を削る

「isucon知識足りなくて、負けたわー、じゃー、ほげほげ勉強しよう!」っていうんじゃ、 思考停止だと思っています。

また知らない技術領域が出て来ても、 どうにかこうにか対応できるようになりたいなーと思った感じです (知識不足は、ちゃんと補完しなきゃですが、、)

箇条書きで終わりもアレなので、 良い例かは分からないですが、パッと思いつく例を書いてみます。

処理しない

一番、大事なことだと思います。処理しないで、済むなら、処理しない。 やらないですむなら、やらない。

1 + 1

たたきこみ

処理したらメモしておく

今回のisucon決勝なら、画像投稿時、ないし、初回呼び出し時などで、キャッシュをするなど。

どこでキャッシュするか、いつキャッシュするか、メモしたものをどう更新するかは色々ですが、やったことは、またやりたくないというのは(領域が許せば)良い。

処理の下準備をする

indexや、辞書作りなどの学習

処理をまとめる

都度の処理呼び出しコストを減らす。 描画処理を減らすために、DOMに書き出さないなど。

処理を少なくする

処理を無くせはしないけど、少なくすることはできるっていうのはある。 処理内容が減れば、大小あれど、一応嬉しい。

# あるある
$dbh->query() for 1..100

ここから、ちょっと、トレードオフが大きくなりそうな、パターン。

処理を外にお願いする

処理が完了するまで、次の処理が出来ないのはもったいない なので、他の人にお願いしたくなったりすることもある

必要な分だけ処理する

重い処理の割には、意外と使われなくて、事前準備してなくて構わないというのはあるなと。 そしたら、必要になったときに、処理すればよい。

処理を得意な人にお願いする

言語レベルか、機械レベルか、ソフトウェアか、、など。 これで良さそうな判断ができるかどうかは知識量に凄い左右されると思っている。

それでも得意な人にお願いしたいというのは変わらないはず。 使いこなせる武器が多いのは、視点が高くなる。

処理関係者を減らす

全てを一番ベストな人にお願いしても、1000箇所で処理が行われるとしたら、 その処理の受け渡しのコストが目につくかもしれない。

処理するヒトを増やす

  • 1人でやるより、2人で処理出来る方が捗ることもある。
  • スケールアウト

処理できるヒトを良くする

  • スケールアップ

仕様を削る

  • その仕様、、、、その仕様、、い、、るかも、、いや、いら、らないかも、、 っていうのは、バッサバッサ切れればいいね。
  • 難しい処理の方がお金になったりすることもあるから、難しいね。でも無駄なのもあるよね。
  • エンジニアから、一歩踏み出すのも、問題解決する為の一つの手段。

最後に

id:karupanerura先生、id:masasuz先生、牡蠣鍋打ち上げしましょう> <

KAYACさん、LINEさん、isuconありがとうございました!!!!!

*1:仕事に置き換えても面白いかも?

TypeScriptさわるぞー #TODO

jsを大きな規模でもちゃんと動くようにしたいと、のたまったので、 偉い人たちが作ったaltjsを勉強させてもらいます ref http://kfly8.hatenablog.com/entry/2013/11/16/005340

#発火村 中、id:gfx 先生におすすめしてもらったTypeScriptを見てみます><

ぱっと見: # TODO

  • jsのsuperset
  • 見た目はほとんど一緒
  • I/Fに型を添えて分かりやすくしている

導入

% npm install -g typescript
% cat > hello.ts
function hello(s: string) {
  return 'hello ' + s;
}
console.log(hello('typescript'));
^D
% tsc hello.ts
% node hello.ts

grunt-typescrpt

npm install grunt-typescript
https://github.com/kfly8/ts-sample

TypeScriptのドキュメントのメモ

Types

// primitive type. ( number, boolean, string, void, null and undefined and user defined enum types)
function hello(str: string) {
    return 'hello' + str;
}

// function type
function hoge(callback: (result: string) => any ) {
    ...
}

hoge(function(result: string) {
    ...
});

// object type

// * object type literal ( ObjectType,ArrayType,FunctionType and ConstructorType  )
var aaa: () => {
    x: number; y: number;
};

// * object type interface // PerlのMouseTypeみたい
interface Friend {
    name: string;
    birthday?: string; # optional field
}

function add(friend: Friend) {
    var name = friend.name;
}

add({ name: 'taro' });
add({ birthday: '20130101' }); # error, name required
add({ name: 'hanako', birthday: '20130201' });


// Structial Subtypes

interface Point {
    x: number;
    y: nubmer;
}

function getX(p: Point) {
}

Class CPoint {
    x: number;
    y: number;
    constructor(x: number, y: number) {
        this.x = x;
        this.y = y;
    }
}

getX(new CPoint(0,0)); // ok!!
getX({ x: 1, y: 2: z: 3); // ok!! Extra fields ok
getX({ x: 1 ); // ng!! supplied parameter's not Point

Class && Module

class Animal { 
    constructor(public age: number) {
    }
    addAge(amount: number) { 
        this.age += amount; 
        return this.age; 
    } 
}
var Animal = (function () { 
    function Animal() { 
        this.age = 0; 
    } 
    Animal.prototype.addAge = function(amount) { 
        this.age += amount; 
        return this.age; 
    }; 
    return Animal; 
})(); 
module Hoge { 
    var s = "hello"; 
    export function f() { 
        return s; 
    } 
} 

Hoge.f(); 
Hoge.s; // Error, s is not exported // variable 's' is private
var Hoge; 
(function(exports) { 
    var s = "hello"; 
    function f() { 
        return s; 
    } 
    exports.f = f; 
})(Hoge||(Hoge={})); 

declare

declare var document; 
document.title = "Hello"; 

外部モジュール

# File main.ts: 
import log = require("log"); 
log.message("hello"); 

# File log.ts: 
export function message(s: string) { 
    console.log(s); 
} 
# point.ts
export = Point; 
class Point { 
    constructor(public x: number, public y: number) { } 
    static origin = new Point(0, 0); 
} 

# use
import Pt = require("point"); 
var p1 = new Pt(10, 20); 
var p2 = Pt.origin; 

温泉発火村なう

#発火村 !!!!!!!!!!!

大規模なjsってどうして書きにくい?

大規模なjsってどうして書きにくい?

フロントサイドでの話です。

そんな話を、id:karupanerura#isucon反省会帰り、東海道線で話した

2人で話した答え:

  • 「パッケージの責任範囲を小さくするベストプラクティスが分からない」
  • つまりは「コードを読む範囲を小さくしたい」

所感:

  • "よしなに"やってくれるって、"なんかこわい"
    • jsのフロントサイドのライブラリって何となくそういうの多い気がする
    • 作るのも大変
  • CPANのように客観的によくテストする仕組みがあれば、使う人も作る人も幸せになれる?
  • 一つのことを上手くやる小さなモジュールを組み合わせたい

どうやって解決するか?

  • モジュールを決められた仕様で書いて、requireして使うcommonjsライクがいいんでは?と話した
    • モジュール毎にHTTP Requestするのはいやなので、concatとかもしやすくしたい
    • 【追記】せっかく非同期に読み込むこともできるのだから、依存関係解決しながらいい感じに読み込むめばいいのか、、と思うと、require.jsでいいのか 、、このサポートのことは一旦忘れよう、

例えば、以下のようにfoo,bar.jsというモジュールを作り、、

# lib/foo.js
exports.foo = function() {...};
# lib/bar.js
exports.bar = function() {...};

package.jsonやcpanfileのようなpackagefileを書くと、、

require lib/foo.js;
require lib/bar.js;

gruntのようなビルドツールでビルドして、、

# generate file
SHELL% BUILD aaa # generate aaa.js

requireして、各モジュールが使える

# some.html
<script src="aaa.js"></script>
<script>
(function() {
    var foo = aaa.require('foo'); # source.mapも利用しやすいはず
    var bar = aaa.require('bar');
})();
</script>

テストは、npm test とか

最後

上のようなことなら、個人でやる分には素直に書けるけど、、最初の命題に対するアプローチどうなんだろうか、、?jsの何が一番いけてない?

すばらしいライブラリやaltjsがあるというのに、jsを書くというアプローチ、、 悪い言い方ですが、臭いモノの蓋を開けても、そんなに臭わないようにしたいなーというそんな願望の現れです。かっこつければ、js書くのが楽しくなれば、それはそれで意義深いかも?!という感じでございます。

以上!

#techhills #7にいってきたー

CROOZさん主催のtechhillsに初めて参加させてもらった。 いろんなゲームエンジンの話で興味深く聞かせてもらいました! ありがとうございました!

かんたんなメモ!!資料はあげてもらえたら随時更新で。

Unity2D/New Unity GUI(uGUI)

  • 物理エンジンにBox2Dを使っている
  • Spriteが主にゲーム用に用意されている

https://twitter.com/kyusyukeigo/status/400264293565755392

Aiming/Unity

http://www.slideshare.net/KatsutoshiMakino/aiming

  • MMORPGげんとうせんきグリフォンを作ったときの話
  • メモリ使用量
    • gcでうわーってなるのは、リソースを大量に切り替えた時やアンロードしたとき
    • addClipしたのを使い回しして、節約
  • UI
    • NGUIを使用
    • 日本語の為に、ビットマップフォントを使用
    • ダイナミックフォントにしたいそう
  • リソースのダウンロード
    • asset bundle
    • LoadFromCacheOrDownload

cocos2d-x

  • C++,Lua,jsなどをサポートするOSSゲームフレームワーク
  • CocosBuilder/SpriteBuilderなどのUIエディタを使うといいんじゃないか

enchant.js

  • コードたのしいよ

Playground KLab

Playground : 描画周りの内部の仕組み

http://www.slideshare.net/RomainPiquois/playground-28101668

  • いろいろ難しいところをいい感じにやってくれている?そう。
  • カメラに映ってないものは、描画しない(カリング)
  • ピクセルの書き換えを減らす
    • 透明でない要素の並びを、近くから遠くに並び替える(重なっている部分の書き換えは最前面だけということだろう)
    • 透明な要素の並びを、遠くから近くに並び替える
    • シェダー?でソート
    • モバイル2D環境だと、シェダーは変わらないゲームが多く、透明でない要素は少ないのが特徴
  • 描画コールを減らす
    • 処理をまとめる/状態が同じものでバッチ処理
    • 状態に関するツリー構造のようなのを管理し?、変わった所だけ変更を行うようにする

Playground : 音ゲーAndroid対応の話

ゲームエンジンの比較の話

XXX ベンチ公開されるといいなー


わーきれいだなー(棒 ゲームエンジン勉強会たのしかった!

#isucon 予選、暫定で生き残れたよう。

初めてisuconに参加させてもらいました。 すごい楽しませてもらっています! 坂パスタチーム( code )は1日目6位で、幸い本戦にも参加出来そうです。 またよろしくお願いします!!

運営の方々、ほんとにありがとうございます><

予選が終わってみて思うこと

偏見に満ちていますが、isuconは、 インフラ周りをやっている人が強い印象です。

普段自分がやっていることはアプリケーションが中心です。 もっと言えば、ゲームのイベントや機能を作ったり、 フロント寄りなアニメを作ったりしています。

きっと俺は無惨に殺されるんだろうと思っていました。

やはりダメージを受けましたが、予選をどうにか、、生き延びれたようで、

  • チームメンバーに感謝!
    • id:karupaneruraid:masasuz がいい感じにしてくれるという安心感があったので開発に集中できた!
  • devだけだって、、、できることはある!
    • (もっと頑張らなきゃだけど...)

そんなことを思いました。

予選でやったこと

下準備(2hours)

  • karupaneruraがdeployツールなど足回りを作ってくれる
  • masasuzさんがパフォーマンス計測用のツールやconfなどを把握
  • 自分は、アプリの仕様を把握する
    • コードをいじれる範囲を大きくしたかったので、丁寧に読む
    • コードを読むだけじゃなく、benchmarkによるアクセス傾向とレギュレーションを見て、 硬くいえば、どこまで成果物ができていれば良いかの線引きを把握。
    • 冗長だけど、こんなの書いた。 https://github.com/karupanerura/isucon2013-yosen/blob/master/memo.md

アプリでなんかあれだなーと思った点

下準備を経て、手を入れたいと思ったところ。結構数が挙ってしまった。

  • トップページ( / )や最近追加されたメモページ( /recent/:page ) で、共通して使われていた「メモ抜粋」の項目をまとめる

    • 参照される回数が多かったので、メモ抜粋のデータを取り出すやすくするのは、まずカジュアルだなーと思う
    • usernameをmemosに突っ込もう
      • 実際にアプリとして、運用するならcacheに入れる方が管理しやすいけど、コード書く量多くなるし、キャッシュ層挟んでベンチマークこけるとかはまるのを恐れ、避ける
      • 100件のIN句でRelation作るっていうのもあるけど、usernameの更新機能は無かったので、そこ頑張る必要ないと却下。
    • memos.contentの1行目をmemosにsummaryとして突っ込もう
      • TEXT型だったので、でっかいテキスト持ってくるのやだなーと思った
  • 公開されているメモの件数を表示している

    • 素直な全件COUNT文. やめよう
    • cacheしても良かったけど、まずは、考えることは少ない方がいいので、counter table.
  • メモの詳細ページで、登録されたメモの前後のメモのidを取り出す処理が大げさだった

    • memosを全部取り出していた。おそろしい
  • 最近追加されたメモページのページング処理で、でっかい OFFSET へのアクセスあって、やだなー

  • markdownの処理が、やだなー

  • no index no life

    • memos にINDEXがない。かなしい
    • いい感じの張ってもらいたいなーとmasasuzさんをちらちらする
    • アクセス元を把握するために、テンプレを眺め回ってたら発見。わらた。
    • 他にもないかと、chrome dev toolsのネットワーク見て、変なリクエストないか、見る
  • /signinへのアクセスはない。

    • benchmarkツールのアクセスを見てて発見。わらた。
    • このページのコードをいじる必要はない
    • user,passwdが20文字制限だったので、アプリがリリースした時点から長さが変わっていなければ、VARCHAR(255)は小さくできるなーと思う
  • usernameが存在するかどうかのチェックにusername VARCHAR(255)で検索している。かなしい

    • とりあえず、usernameにhashをかけたカラムを用意しよう
  • 全ページで、user情報がstashされていた。ぬーん。

    • (過去分のメモの詳細をキャッシュに突っ込もうという話があったけど、userデータの扱いを失念していたので、無駄にはまる所だった。あぶない。テンプレ分割すればいいんだけどさ)

飯を食いつつ方針周り話す( 1hour )

  • まずは予選を突破できればいいねと話す
  • アプリではcache層挟んだりせず、素直に駄目なところを改善させてと話す。
  • 15:30過ぎくらいに後半周りのスコアを見て、考えようと後回し
  • つまり消極作戦。
  • frontの置き換えだったり、confのいいかんじの設定をお任せせ><

もくもく( 最後まで )

ほとんど午前中に気づいたことを書くことで終わる 途中色々詰まって、邪魔をする.. orz

  • アプリ側の問題点は結構挙っていたので、実装が間に合わないと嫌だったので、火を見るより明らかな所を直す。

    • どの変更でパフォーマンスが上がったか下がったか分からないと困るので、大人しくbranch切って書き書き。
    • 都度ベンチをお願いする。
    • 完了したら、ローカルのブランチを削除して、branchをtodoリストっぽく扱うw
  • benchmark時に走らせるスクリプトが、うまく動かない、、他の2人にも聞き、結局俺は実装を優先させてもらい、karupaneruraにパス>< すいません

    • 結局、~での指定が悪く、rootユーザでの実行を想定してなかったせいだった、すいませんすいません
  • また自分の変更で、benchmarkこける..焦る、今度は、masasuzさんにいろいろ見てもらう、、すいません

    • refererを教えてもらって、原因を特定、、すいませんすいません。

書いてて、凹んできたw もっとoptsの力があれば、チームの方々の時間を奪わずに済んだろう...

5割くらいは実装できたから、、いいんだ、、本戦頑張る!!

多分本戦であかんかったら、karupaneruraに埋められる。

たられば、よもやま

  • ユーザが登録したメモの前後関係を取るなら、どんなデータを残すのがいいかなーと考える
    • ユーザ毎にメモの登録順序を持つような実装進める

疑似コードはっつけ。

まとめ

もっと点数を伸ばす為には、ドラスティックな変更できる筋力欲しいと思うも、 単純なことを単純にやれる力があることが確かめられて、少し自信になった。 チームでいいお酒飲めるように本戦もがんばろー。

蛇足

早速、坂のパスタ屋に行って来た。うまし!!

#yapcasia と #pyconapac 2013のボランティア参加してきた

[追記]運営からのお願い

--8<--

YAPC::Asia Tokyo 2013に参加していただいた皆様 本当にありがとうございました。 おかげ様で今年も楽しいイベントにすることができたと思います。

そこでYAPCの熱気が冷めない間に皆様に2点お願いがあります:

1) 是非感想ブログを書いてください! 書いたブログは「YAPC::Asia Tokyo 2013 ブログ書いたよ!フォーム」 に入力していただければ、yapcasia.orgサイト上からリンクさせていただきます フォーム: https://docs.google.com/a/perlassociation.org/spreadsheet/viewform?formkey=dEcwX3FvQUpQN1R5ZDRpUXBZQW1ycWc6MA#gid=0 まとめページ: http://yapcasia.org/2013/09/yapcasia-2013.html

2) 是非アンケートにお答えください! アンケートは非公開で、運営のみが目を通します。 https://docs.google.com/spreadsheet/viewform?formkey=dEVNUGo2WGlYbUt0bWh2cnFlZjhNVHc6MA

上記は参加できなかった人達や一部トークを見逃した人達およびYAPC::Asia Tokyo運営チーム一同が楽しみにしていますので、是非是非書いていただけるとありがたいです。

以上よろしくお願いいたします。

-->8--

YAPC::AsiaPyCon APACの当日ボランティアとして参加させてもらいました。 どちらのイベントも楽しませてもらいました。楽しかったー!

特にYAPCは、東京で就職した一昨年の2011、翌年の2012を聞く側として楽しませてもらっていたので、 何か主体的に関われることはないかと、今回ボランティアに応募。

当日のお仕事

  • ノベルティ準備
    • パンフレットとスポンサーの方々のノベルティを、ノベルティのトートバッグに詰める。
    • yapcは1000人以上の方が参加予定で、スポンサーをしてくださる企業も10社以上。なので、1000 * 10 もあって、、、筋肉痛になりました。参加してただけの今までは考えてなかった!
  • 発表する会場の準備
    • スピーカーの人の背面に置く、スポンサーのアイコンを彩ったバッグボードや企業広告を貼る、電源確保、ビデオカメラの設置など
  • 発表会場の案内、進行
    • タイムキーパーをしたり、マイクの電源を気にしつつビデオ撮影。あと「ブログ書くまでが、YAPCですよ!」など言う(書いた!)
    • 担当していた部屋に人が入り切らない状態になってしまい、、申し訳ない気持ち、、
    • 個人的にも、 担当していた部屋なのに、Yappoさん、karupanerura、hirataraさん、naoya_itoさん、soh335さん、y_uuk1くんのセッションが連続して全然聞けなかった。かなしい。
  • 撤収
    • ゴミ、会場に準備したもの、ノベルティなど全てけつかっちんで撤収

PyConに行ってみて

普段から仕事でPerlを書いたり、 Kyoto.pm #1#4 に参加したりと 自分の軸足は、Perl。(好きで嫌いなのはjs)

PyConに初参加でいきなりボランティアさせてもらうだなんて、アホのすることだけど、 それでも、2つの大きなカンファレンスに参加させてもらって、違う視点から見れて良かった。

  • 当日ボランティアの仕事は、似てた。
    • PyConの方が、English Speakerが多くて、スタッフも英語喋れるかどうか問われた。
  • PyCon sessionsはあまり聞けなかったけど、いくつか思う。
    • sphinxやpuppet, Ansible などtool系の話が多かった印象。
    • 学術的な話もPyConの方が多かった印象。
    • 基調講演は、同時通訳がついたりしていた。
      • 技術に長けた通訳の人だったのだろうか、、聞いておくんだった、、、

カンファレンスを教えてもらった。あとやりたい。

ボランティアをしての感想、まとめ

941さんや牧さんらコアなスタッフの方、スピーカーな方、参加した方、おつかれさまでしたー。 ボランティアとして参加させてもらえて楽しかったです。ありがとうございます! 「いいからコード書け」とも思うけど、フレッシュレモンみたいなお仕事も、これからもさせてもらいたいなーと思いました。

「コミットできるとより楽しめる」ってことを声を中くらいにして言いたい。 もっとコミットできるようになったら、大になるはず。

リンク

#kyotopm にいってもくもくしてきた

そうだ、京都に行って来ましたー

2013-03-30 @はてな http://www.zusaar.com/event/582004

http://instagram.com/p/Xefv11oDDR/ はてなのTシャツもらた。あざます!

今回のKyoto.pm は、 もくもくするハッカソンイベントでした。 自分は、数式のエディタ作ってみました。(ほとんどドキュメント読んでる時間でしたが...)

発表していた人の(わずかな)めも...

Cinnamonの並列処理

  • id:shiba_yu36
  • 並列処理のテストを書くのに、サーバ環境を2つ用意しないといけないことに気づいて、、
  • vagrant

黒い画面でキャラを。

http://xpathfeed.com/

Net-Signalet

以下、その日、発表で使った資料(にちょっと手を加えたもの)

-------------->8-----------------------------------------------------

自己紹介

  • kfly8
  • 朝まで飲んで、品川発の新幹線に乗り込む。
  • もしかして: ねむい
  • 普段は、MFで、ソーシャルアプリ作ってます。
  • よろしくお願いします。

つくったもの

txtをMathMLに変換してくれるwebあぷぷ

仕組みの概要

Text::ASCIIMathML

$parser     = new Text::ASCIIMathML();
$mathMLTree = $parser->TextToMathMLTree('int_0^1 e^x dx');
$mathMLTree->text();

動機を...

weighted shuffle

@weighed_list = [ { value => 'hoge', weight => 10 }, { value => 'fuga', weight => 100 } ];

@weighted_shuffle_list = map { $_->{value} }
    sort { $b->{rand} <=> $a->{rand} }
    map {
        {
            rand  => rand($_->{weight}),
            value => $_->{value},
        }
    } @weighted_list;

ロジック

weightの価値が知りたい

  • この確率は、積分で表せるのだが...
  • なんか数式で表したいなー
  • これが、動機!!!!

MathMLって?

数式を表す他の手段は?

画像を使う

  • Google Chart Tool
  • 画像で数式を表現

  • CodeCogs

  • 画像で数式を表現. 解像度を指定できる.

画像で数式を表した場合の問題点

  • 機械に優しくない
  • Liquidレイアウトしずらい

非対応ブラウザ対応

今後どうしたいか

  • 変換精度を上げる
  • エディタとしての使い勝手を上げる
  • 例えば、オフラインで動かしたいので、JSで変換できるようにしたい
  • 画像にしてダウンロード、シェアできるようにしたい。

  • 数式をカジュアルに使いたい!

参考URL

MathML

MathML ver2 @2003 -> ver3 @2010に移行しているので、どう違うのか調べる。 #TODO

変換ツール

最後に

もくもくコードが書けて楽しかったです。 畳でコード書けるっていいですね! 楽しかったです!

ありがとうございました!!

----------------8<---------------------------------

桜きれいだったー。

http://instagram.com/p/XgnafPIDFU/

TODO: 教えてもらったラーメン屋に行く。

新しい年度が始まる!がんばろうー。

suppressしたrow objの存在しないkeyにアクセスして、Data::WeightedRoundRobin の初期値が使われて...orz

たった今、かなしい!となったので勢いに任せて書きます.


普段、Data::WeightedRoundRobin のSugarを次のような感じで
exportして使っています.

    use Data::WeightedRoundRobin;
 
    sub list2dwr (&@) {## no critic
        my $code = shift;
        return Data::WeightedRoundRobin->new([ map { $code->($_) } @_ ])
    }
 
    my $dwr = list2dwr {
        +{
           key    => $_,
           value  => $_ * $_,
           weight => $_,
        }
    } qw/1 2 3 4/;
 



普段、Teng のsuppress_object_creation も、データが多くなるってとき、
使っています.

 
    my @rows = do {
        my $iter = model('DB::Hoge')->search(+{ user_id => $args->{user_id} });
        $iter->suppress_object_creation(1);
        $iter->all;
    };
 



で、はまったコードはこれ.

 
    my @rows = do {
        my $iter = model('DB::Hoge')->search(+{ user_id => $args->{user_id} });
        $iter->suppress_object_creation(1);
        $iter->all;
    };
 
    my $dwr = list2dwr {
        +{
           key    => $_->{id},
           value  => $_,
           weight => $_->{weihgt},
        }
    } @rows;
 

分かりにくいと思うので、拡大!!
コレ!!!!!

           weight => $_->{weihgt}, # not weight!!!



順としては

  1. $_->{weihgt} が undefined
  2. Data::WeightedRoundRobin の、DEFAULT_WEIGHT 100が適用される
  3. orz


テストコードで気づくと思いつつ、意地悪なテストじゃなかったら、すり抜けるなーと


普段、次のような恩恵を自然と預かっているんだなと改め思う

  • $_->weight に対するアクセスが普段メソッド通しているので、typoに気づく
  • hashへのアクセスもバリデータを通しているので、気づく
  • readonly にしていればとか、、、



だから、どうしよう...
と思ったが少し閃いた

どうせ、ラップして使っているなら、default値は使わないぜ作戦

 
    sub list2dwr (&@) {## no critic
        my $code = shift;
        return Data::WeightedRoundRobin->new([ map { $code->($_) } @_ ], { default_weight => sub { die } } )
    }
 


Data::WeightedRoundRobin で、default_weight がコードリファレンスだったら実行してもらう必要があるけど、、

あとは、suppress_object_creation でreadonlyにする作戦?!

2012年の振り返りと2013年。

あけましておめでとうございます。

2012年は自分にとって、成長の年でした。
(ということにする!)


最初から私事で恐縮ですが、
鬼畜id:karupaneruraにバツイチと言われてしまいましたが、、
2012年は、一生過ごして行きたいと思っていた人との別れを経験しました。

今まで、チープだと思っていた邦楽の恋愛の歌が
「こんなツラい経験を歌にしてて、すげー」と尊敬の念を抱いたり、
小田和正、中島みゆきらは「くぐっている修羅場が、違う」
と思ったりしてました。階段から人を突き飛ばす人を、自分は見た事がないです。

冗談のようですが、こんな風に思えたことは、
人間って面白いなー感じさせてくれました。
言い方を変えれば、
「人の気持ちになって考える」のは難しく、
経験したら「すんなりわかる。わかった気になる」
都合がいいもんだなと。

つるっつるの脳みそに(もう二度とはごめんだけど)
ありがたいシワもらったなーと。

数十年生きていれば、誰かに悩みを相談したり、されたりあると思うのです。
そんなときなど、相手の気持ちをもっと思いやれればと思ったのです。

元気出たなーということ

そんなこんなで、絶賛へこんだりしてたわけですが、
ありがたいことに元気出たなーということ。

  • エンジニアの上司曰く「何年か先、胸を張ってられるように過ごすといいんじゃないかな」
  • 女の先輩曰く「恋愛体質ね」
  • 美味い飯
  • コードいっぱい書いた。

まとめるなら、

  • 人と話せてよかった。
  • 頑張りを向ける先があったことが幸せだった。

かなーと。

2012年エンジニアとして

2012年は、ほとんどソーシャルゲームのRPG作りをやっていました。

コミット数を見てみると、
去年の8月ころまでにやっていたRPGが、こんな感じ。

git shortlog --no-merges -sn --since=1year
2106  ****
1806  k-kobayashi
544  ***
152  ***
...

今開発中のものが、こんな感じ。

876  k-sato
781  k-kobayashi
267  ***
155  ***
116  ***

これが是か非かは謎ですが、
ぼちぼち手が動くようになってきたのかなとは
思っています。

コードを書くときに意識したいこと3つだなんてこと書けたのも
手を動かせたからかなーと思ってます。


時系列は遡りますが、
2012年の始めに、温泉はっかそんができたこと、
3月にはKyoto.pmでそれに関するLTをさせてもらい、
Perl Mongerと交流できたことも、2012年よかったぜ!って事です。
コミュニティに何らか貢献したい!と思うようになった年になりました。

ちゃっかりadvent calender を書かせてもらったりもしました。

2013年は

2012年、悪い言い方をすれば、がむしゃらな年でした。
コードを書いていて、根拠が乏しいと手が止まってしまっていました。
また人に説明する機会も必要に迫られるようになりました。

そういう具合なので、
今年は、自分に「テコ入れ」をしたいと思います。

具体的には、次のようなことができればいいのかなと。

  • XSモジュール書く
  • webサービスを一個作る
  • 勉強会などスタッフをする

あとは、

  • 温泉ハッカソンをやるー。
  • JSを書きまくるー。

という欲にまみれたこともしたいしたい!


まとまりませんが、ここら辺で。

今年もどうぞよろしくお願いします。

lenny に、node 0.8.15 を入れるのに嵌ったログ。chai を入れるのが目的だったはずが力尽きるの巻

はじめに

JSのテスト環境を作りたい。作りたい><
なので、LordOfNights をUnity からHTML5 に移植した@mizchiさんが、
npm のshould は嫌だなー。chaiがいいよ。って言ってたので、便乗してみる。
詳しいことはTODO

結果的に、このバージョンのnode.jsをいれる必要があったのか、まだ調べてすらいないが、
node.js の最新安定版のv0.8.15 を入れてみる。

やること

node.js の最新安定版(v0.8.15)をdebian lenny に入れてみる
ついでに、chai を入れる。
(chai を入れることが目的のはずが、ほとんど、node.js を入れることに時間を費やす。。。。)

node.js version manager 選び

結論、シンプルで使いやすそうなnodebrew に。

node.js のvergion マネージャーは結構あるそうなので、再検討してみてもいい。
とりあえずnode.js が入れたいだけだったので、GOGO

install nodebrew

# 落として
curl https://raw.github.com/hokaccha/nodebrew/master/nodebrew | perl - setup
# パス通す
echo 'export PATH=$HOME/.nodebrew/current/bin:$PATH' >> ~/.zprofile
source ~/.zshrc

だけ簡単!

install node.js

nodebrew に従うだけ、、?

nodebrew install stable

ビルド待つ

ln -fs out/Release/node node
python tools/install.py install
Traceback (most recent call last):
  File "tools/install.py", line 4, in <module>
    import json
ImportError: No module named json
make: *** [install] エラー 1

???
tools/install.py のモジュールの読み込みのところでエラーってる。
んー、ぐぐると、python のバージョンが、2.5 より上げれば解決しそうなので、上げてみる
python は、product で使ってるわけじゃないから、いいだろう <-

python の2.7.3 を入れてみる

http://www.python.org/download/


python もversion 管理してくれるツールあるだろう。
ぐぐる。あった。

これでいいのかな??前のコミット相当古い、、

開発者忙しくて、あんまり開発できなさそう、

紹介されている pythonz がいいのかなと思って試す。

curl -kL https://raw.github.com/saghul/pythonz/master/pythonz-install | bash


  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100  2596  100  2596    0     0   3319      0 --:--:-- --:--:-- --:--:-- 2535k
pythonz requires Python 2.6, 2.7 or higher

げー。2.5 だから、入れたいのに、2.6 以上じゃないとだめだと、、、
致し方なく、pythonbrew にする

# これも落として、
curl -kL http://xrl.us/pythonbrewinstall | bash
# パス通すだけ
echo '[[ -s $HOME/.pythonbrew/etc/bashrc ]] && source $HOME/.pythonbrew/etc/bashrc' >> ~/.zprofile
source ~/.zshrc

簡単!

よし、python の最新安定版をいれてみよう。

pythonbrew install 2.7.3

待つ。

Use the previously fetched /home/k-kobayashi/.pythonbrew/dists/Python-2.7.3.tgz
Extracting Python-2.7.3.tgz into /home/k-kobayashi/.pythonbrew/build/Python-2.7.3

This could take a while. You can run the following command on another shell to track the status:
  tail -f "/home/k-kobayashi/.pythonbrew/log/build.log"

Installing Python-2.7.3 into /home/k-kobayashi/.pythonbrew/pythons/Python-2.7.3
Downloading distribute_setup.py as /home/k-kobayashi/.pythonbrew/dists/distribute_setup.py
######################################################################## 100.0%
Installing distribute into /home/k-kobayashi/.pythonbrew/pythons/Python-2.7.3
Installing pip into /home/k-kobayashi/.pythonbrew/pythons/Python-2.7.3

Installed Python-2.7.3 successfully. Run the following command to switch to Python-2.7.3.
  pythonbrew switch 2.7.3


yappie!!

pythonbrew switch 2.7.3 
python -V # 2.7.3

今度こそ、node.js の最新版を入れてやる!!!!

nodebrew install stable

待つ。

ImportError: No module named bz2:


今度は何だ、、
(ログ不完全orz

  • version は全然違うけど同じことはまっている人がいた。
# bz2 をインストール
aptitude search bz2
sudo aptitude install libbz2-dev

# python をインストールしなおす
pythonbrew uninstall 2.7.3
pythonbrew install 2.7.3

三度目の正直。今度こそ!!

nodebrew install stable

ビルド待つ

nodebrew ls
v0.8.15

きたー!!

おまけ

npm install chai

蛇足

自分のmac book air だとすんなり入ってたので、
結構はまってショック!!

俺はテストするぞー!!

コード書くときに意識するよになった3つ

社会人として、コードを書くようになって、もう一年半くらい経ってしまった、、
HHKを買って盛り上がっているうちに、偉そうなこと書いてみます。

f:id:kfly8:20120722211416j:plain
http://instagram.com/p/K1hB2fIDGe/


ソーシャルゲームを作っていると、
仕様が変わったり、追加されることがよくあります。

そういう時でも対応しやすいコードを書くために、
最近、大きく3つのことを意識するようになりました。


1個目!

そのコード、直感的?


責任範囲を超えた"なんでもバスケット"みたいなコードは、
どんな使い方ができるか想像しがたいと思っています。

  • 何するコード?
  • お前がやるべきこと?
  • どう使えれば気持ちいい?

とブツブツ唱えてから作ると嬉しいなと思います。

もっぱら方法として効果があると思うのは、

使い方を書いてから、中身を実装すること!


2個目!

コードを書かない

エンジニアとして働いていて、幸い、自分はコードを書くのが好きです。
(ハッカソンしたいーーー。)

なんですが、

  • ゲームとしてすべきことの把握
  • 企画の目的の把握
  • アプリのコードの把握

ができていると、コードを書かないって選択肢がまま取れます。

「もうその機能はあるから5分でできるよ!」

好き嫌いが分かれるかもですが、
意味のあるコードを書くのに時間を使えた方が自分は幸せだと思うので、
「コードを書かない」って選択肢を手札に入れています。


あのモジュールがあるから
「コードを書かない」という選択は取りきれていないので、
精進精進、、



3個目!

コードを書くのに本気にならない

本気で書いたコードは、もしものときに殺される可能性大だからです。

ソーシャルゲームを作っていると、

  • 問い合わせの対応
  • 不具合
  • 仕様変更
  • 新機能!

など、大概作るより強力な弾丸が飛んできます。
作るのに本気だと、あとあと打ち返せないと思っています。

どんだけ怠慢なんだよと思われるかもしれませんが、
自分は全知全能な人でなく、凡人なんだという思想からです。

  • 仕様の先読みした抽象化

は難しい選択肢だと思っています。
ゲームの理解、アプリのコード理解、技術理解など、把握すべきところが多いと思います。
迷うくらいなら、様子を見るべきだと思っています。


以上、自分への戒め!でした。

Perl で配列回すときにデリファレンスしといた方がいいと勘違いしてました、、

避暑地でハッカソンがしたい。

前置きー。

JavaScript で、配列の長さを評価する必要がないとき、
以下のよう配列長をキャッシュすると思います。

配列の長さが変わらないなら、、

for ( var i = 0 ; i < arr.length; i++ ) { //do something}

配列長の変数に入れておく。

for ( var i = 0, l = arr.length; i < l; i++ ) { //do something}


それで、Perlでもおんなじ風味で、
キャッシュしておいた方がいいと思うと、やっぱり予想通りでした。

use strict;
use warnings;
use Benchmark qw/cmpthese/;
 
my @arr = 0..100;

# Benchmark js style
cmpthese(100000, {
    'js' => sub {
        my $total = 0;
        for (my $i = 0; $i < scalar @arr ; $i++) {
            $total += $arr[$i];
        }
    },
    'js cache' => sub {
        my $total = 0;
        for (my $i = 0, my $l = scalar @arr; $i < $l ; $i++) {
            $total += $arr[$i];
        }
    },
});

ベンチ。

            Rate       js js cache
js       51020/s       --     -19%
js cache 63291/s      24%       --

この後の本題のために、この例のfor文を簡素化してみてベンチ。

use strict;
use warnings;
use Benchmark qw/cmpthese/;
 
my @arr = 0..100;

# Benchmark coding style
cmpthese(100000, {
    'array' => sub {
        my $total = 0;
        $total += $_ for @arr;
    },
    'js cache' => sub {
        my $total = 0;
        for (my $i = 0, my $l = scalar @arr; $i < $l ; $i++) {
            $total += $arr[$i];
        }
    },
});

変数の代入が無い分速いのかな?と疑問は残りつつ、前置き終了。

             Rate js cache    array
js cache  66667/s       --     -39%
array    108696/s      63%       --

本題ー。

ここで予想したのが、

「配列長をキャッシュしておいた方がいいなら、
配列のデリファレンスしたものもキャッシュしておいた方がいいのかな?」

でした。

ですが、違いました以下のように配列のキャッシュを十分活かせない形だと、デリファレンスするコストの方が高くなるようです(2013-11-19修正)

具体的には、以下のベンチ。

use strict;
use warnings;
use Benchmark qw/cmpthese/;
 
my @arr = 0..100;
my $arr = \@arr;
sub get_arr { return @arr; }
sub get_arr_ref { return $arr; }

# Benchmark dereference
cmpthese(100000, {
    'array' => sub {
        my $total = 0;
        $total += $_ for @arr;
    },
    'get_array' => sub {
        my $total = 0;
        $total += $_ for get_arr();
    },
    'get_array cache?' => sub {
        my $total = 0;
        my @a = get_arr(); #キャッシュ?
        $total += $_ for @a;
    },
});


# Benchmark dereference
cmpthese(100000, {
    'array_ref' => sub {
        my $total = 0;
        $total += $_ for @$arr;
    },
    'get_array_ref' => sub {
        my $total = 0;
        $total += $_ for @{ get_arr_ref() };
    },
    'get_array_ref cache?' => sub {
        my $total = 0;
        my @a = @{ get_arr_ref() }; #キャッシュ?
        $total += $_ for @a;
    },
});

ベンチ結果。

                     Rate get_array cache?        get_array            array
get_array cache?  40161/s               --             -43%             -64%
get_array         69930/s              74%               --             -38%
array            112360/s             180%              61%               --

リファレンスとして扱った方

                         Rate get_array_ref cache?  get_array_ref      array_ref
get_array_ref cache?  49261/s                   --           -55%           -56%
get_array_ref        108696/s                 121%             --            -3%
array_ref            112360/s                 128%             3%             --
       2%    --


デリファレンスしておいたものを変数代入(キャッシュ?)しておいた方が遅かったです。

どうしてこういう結果になったのか、腹落ちしてないので、たぶん、、調べる、、、、

  • 代入のコストが意外と大きい?
  • あと意外なのが、ger_array より、get_array_ref の方が速かったこと。

蛇足。

Sledge のコードを読んでいて、登録されているトリガーをぶん回しているところを読んでいて沸いた疑問でした。
miyagawaさんが、書くなら、それがいいんだろうと思ってベンチを取ってみて、やっぱりそうでした。

追記

sort についても、、、
ループのたびに評価されるって思ってた、、、完全な勘違い、、残念すぎる、、orz


use List::Util qw/shuffle/;

my @num = shuffle 0..9;

# Benchmark dereference
cmpthese(1000000, {
    'simple' => sub {
        my $s = '';
        $s .= $_ for sort @num;
    },
    'cache?' => sub {
        my $s = '';
        my @sorted_num = sort @num;
        $s .= $_ for @sorted_num;
    },
});

ベンチ

           Rate cache? simple
cache? 128041/s     --   -58%
simple 305810/s   139%     --

追記2 2013-11-19

ベンチが十分、arrayのキャッシュを活かせる形じゃなかった。
コメントのnyaさんの指摘で気づきました。ありがとうございます><

雑日記。


休日に会社のPCでYouTubeを見てるのは誰ですか?俺です。すみません。
引っ越したばかりでネット繋がってなくて、、←

4月に自分携わっているアプリがリリース、
あとプライベートで、いろいろいろ、、で、
多忙させてもらってました。


人生にいくつか転機があると思いますが、
自分は今と思ってがんばらせてもらってます。


ふわっとし過ぎ。


以上、近況報告!!

Kyoto.pmに参加。温泉発火村のLTもやらせてもらった。

こんばんは。
初開催のKyoto.pm Tech Talks #01に参加させてもらいました。
そして、温泉ハッカソンを企画した話で初LTもさせてもらいました。

会場を貸してくださった、はてなさん。
運営の方々。楽しい時間をありがとうございました!
参加されている方とも交流できてよかったですー

f:id:kfly8:20120317210008j:plain

発表資料


夜遅くまで懇親会に参加させてもらって、
Perlのコミュニティっていいなーと思ったのでした。
YAPCやハッカソンなどでも何度も感じさせてもらってて、
使っている技術で繋がれるのっていいですね。

例えば、id:xaicronさんが懇親会から参加したりするのって、
Perlのコミュニティの魅力がとってもあるか、@xaicronさんが変なのか
どっちかだと思うんですよね。


仕事を始めて、約1年。
エンジニアって仕事を選んで良かったなと思ったのでした。



めもめも

id:nekokak さん

  • Teng開発者募集
    • コミュニティで開発できたらいい
  • ORM
    • データとオブジェクトの溝を埋める

id:karupanerura

  • XOClock
    • 指定時刻にジョブを実行する
    • 冗長性を持たせられたら、うまー。

id:hakobe932 さん

  • ruby-git
  • Git.pm
  • Git::Class / Git::Wrapper
  • Git::Repositry
  • Guita::Mapper::Git
  • libgit2

LT

  • Text::Hatena:oEmbed
  • SQL::Object
  • Test::Successful
  • Test::Flatten
  • DBIx::QueryLog

余談

観光地のpmは、翌日も楽しめていいですねんw