2012年12月23日日曜日

macでemacs生活



環境はusキーボード,iterm2

目指すところ


emacs(というかiterm2)上ではcommand をmetaキーにしつつ、
iterm2も含めたグローバルでは
command+space で言語切り替え
command+tab でアプリ切り替え

あと、ctlとcapsの入れ替え。

設定


metaキーまわり

iTerm > Preferences -> keysで
1、optionとcommandを入れ替え。
2、左の表をクリックして、command+space をDo Not Remap Modifiersに。
f:id:toku_bass:20121222152155p:image
追記
iTerm2でAltキーをMetaキーとして使う

capsとctl

macのシステム環境設定→キーボード→修飾キーボタンと遷移した先で設定

参考にならないマイナー設定


f:id:toku_bass:20121222152157p:image
KeyRemap4MacBookでセミコロンとリターン入れ替え。
同じくKeyRemap4MacBookでキーリピートの速度を速くしておく。

追記
KeyRemap4MacBookで、
Command_R to Command_R (+ When you type Command_R only, send KANA/EISUU (toggle))
にチェックを入れて、右コマンドだけでかな、アルファベット切り替えできるようにした。




2012年11月4日日曜日

2軍(仮 でisucon2に参加しました



結果は来年リベンジ!って感じでした。
まず反省点はセットアップに結構時間がかかってしまって、懇親会で聞いた話を参考にする限り、ローカルで編集してdeployすればよかったなと思いました。
(bashrcをscpで送ったら、サーバーでコマンドが動かなくなった。)

やったことはクエリの書き替えとvarnishでのキャッシュだけです。
まず邪道なのですが、stockとrequest_order ? 以外は更新がないテーブルだったので、perlのコードにハードコードしました。
これでほとんどのクエリからjoinが無くなるどころか、クエリをDBに投げなくなりました。
今回のjoinは素直に2回クエリを投げれば解決するものばかりだったので、実サービスではhoge_idによるselectの結果をキャッシュをする形になると思います。

これで、チケットは1000から1500くらいは捌けるようになりました。(フロントはnginx)
ここでフロントをnginxからvernishに切り替えて、キャッシュを導入すると、4000以上は出たのですが、最近購入したチケットがうまく反映されなくて失敗し、それが最後まで解決できませんでした。

以上です。
恐らく平均するとwebエンジニア歴2年未満な3人でしたが、まぁ健闘したと思いますし、来年は上位に入れるように頑張りたいです!





2012年10月22日月曜日

mongoのレプリカセットをperlとnginx-gridfsから使う



レプリカセットを作る記事はあるけど、利用する記事って意外にないねーってことで書く。


構成


mongod2つと、arbiter1つでレプリカセットを組む。gridfsも同居。
今回は全部localhostでテスト。

gridfsはnginx-gridfsを使用してフロントのサーバーからアクセス。
perlはMongoDBを使用。


レプリカセットを組む


まずデーモンを3つ立ち上げる。
configはこんな感じで。portとdbpathはそれぞれのデーモンで別のに設定に。
dbpathのディレクトリは勝手に作ってはくれないみたい。
(arbiterにjournalは要らない)



dbpath = /usr/local/mongodb/rs1/db1/
journal = true
bind_ip = 127.0.0.1
port = 27017
replSet = rs1



mongoシェルでレプリカセットの設定。
以下はjsで設定ファイルを作っておいて、流し込む方法。(設定しなおす場合はrs.reconfig())



// replica_set_config.js
db = db.getSisterDB("admin");
rs.initiate({
_id: 'rs1', // replSetのセット名。nginx-gridfsでも使う。
members: [
{_id: 0, host: 'localhost:27017'},
{_id: 1, host: 'localhost:27018'},
{_id: 2, host: 'localhost:27019',arbiterOnly : true}
]
});



3つとも起動しておいて、



/usr/local/mongodb/bin/mongo localhost:27017/project < replica_set_config.js



で完了。


perlからレプリカセットにアクセス


複数指定するとMongoDBが勝手に探してくれる。
どのmongodにも、どのmongodがマスターなのかという情報があるので、最大2回でマスターに接続できる仕組み。



use MongoDB;
my $db = MongoDB::Connection->new(host => 'mongodb://localhost:27017,localhost:27018', find_master => 1);



nginxからgridfs(のレプリカセット)にアクセス



location /gridfs/ {
gridfs tracenote field=filename type=string;
mongo "rs1" localhost:27017 localhost:27018;
}



で、うまくいかない。
ipアドレスなら上手くいくが、hostnameだとダメ。
これは運用上よろしくない。

issuesにあった。
mongo-c-driverが対応してないらしい。(追記あり。本家mongo-c-driverで大丈夫でした)
@kiwanami さんのパッチが本家に反映されてない気がする(上手くいかなかった)ので、
kiwanamiさんのブランチをclone.



git clone git://github.com/kiwanami/nginx-gridfs.git && \
cd nginx-gridfs && \
git submodule init && \
git submodule update
cd mongo-c-driver && \
git checkout master


nginxをmake



./configure --prefix=/usr/local/nginx/ --add-module=/path/to/nginx-gridfs --with-cc-opt=-Wno-error
make && make install



追記


nginx-gridfsが最新のmongo-c-driverに対応してないので、修正が必要。
nginx-gridfsのsubmoduleに指定しているmong-c-driverは古いので、git checkout masterして最新にする。
これで、kiwanamiさんのパッチが取り込まれてる状態になる。

次にnginx-gridfsのconfigがsrc以下全部を対象にしていて、windows用のをコンパイルしようとするので、
issues に書いてあるように
mongo-c-driver を単体でmake して、
nginx-gridfs/configを編集する。



ngx_addon_name=ngx_http_gridfs_module
HTTP_MODULES="$HTTP_MODULES ngx_http_gridfs_module"
NGX_ADDON_SRCS="$NGX_ADDON_SRCS $ngx_addon_dir/ngx_http_gridfs_module.c"
NGX_ADDON_DEPS="$NGX_ADDON_DEPS $ngx_addon_dir/mongo-c-driver/src/*.h"
CFLAGS="$CFLAGS --std=c99 -I src -I /usr/local/include -L /usr/local/lib -lmongoc"


libmongoc.aと、libmongoc.soは -L で指定した/usr/local/libに置いておく。
(/sbin/ldconfig忘れない. redhat系なら/usr/local/libを /etc/ld.so.confに追加)
これで、ngninxをconfigureすると、libmongoc.so.0.6が見つからないと言われたのでリネーム。
正常に動作した。





2012年9月15日土曜日

mongoDBのログ可視化。



ここの一番上のEddaってのを使ってみた。
https://github.com/10gen-labs/edda

pip導入


git clone https://github.com/pypa/pip.git
cd pip
sudo python setup.py install (python3は未サポート)

モジュールがないって言われたら、easy_install

pipでeddaをインストール


pip install edda

eddaをrun


python edda/run_edda.py ログファイル名を列挙。

ここで、python2.6だとformatどうたらエラーがでる。
エラーのところで{}を{0}に書き換えて実行。

URLが出てくるので、ブラウザでアクセス。




2012年9月2日日曜日

sshでssh_exchange_identification: Connection closed by remote host



いつも通りsshでサーバーに接続しようとすると、
ssh_exchange_identification: Connection closed by remote host

ググってみると、hosts.denyやhosts.allowの設定話がでてきますが、関係なし。

sshdを再起動してみると、以下のメッセージが。
Starting sshd:/var/empty/sshd must be owned by root and not group or world-writable.

/var/empty/sshd になぜか書き込み権限があったので、パーミッションを変更して、再起動。でokでした。





2012年8月26日日曜日

Perl Beginners #4 レポート



#3に引き続き発表してきました。資料
今回自分の発表のあとに出てきた質問について補足したいと思います。
(質問について補足できる場があるといいですね)


mixin(export)って具体的にどうやってるの


まずuseの話から。
useはrequireしたあとに、importメソッドを呼び出す。
use終わり。

useされる側のメソッドをuseした側のパッケージに移植する、という処理は自分でuseされる側のimportメソッドに書けってことです。
でも面倒なので大抵はExporterなどのモジュールで用意されてるimportメソッドを拝借します。

では動作を確認するために、Exporterのimportメソッドを見てみましょう。
Exporterのソース

はい、折れた!今君の心折れたネ!

以下に異なるパッケージにサブルーチンを移植するだけのコード置いときますのでお好きにどうぞ。
ここ

実行すると、mainって表示されますね。
mainにはexport_methodなんて定義してないのにmainのメソッドとして呼べているのがわかります。

MyExport.pmもimport文は2行。
callerで自分を呼び出した側の名前を取得して、
グロブを使って相手のパッケージにサブルーチンを登録しています。(エイリアス)

さて、グロブって何だよ死ねって思われたかもしれないですが、そこはperldocに譲りたいと思います。
http://perldoc.jp/docs/perl/5.8.8/perlmod.pod


使わなくなったモジュールを消したい


本当に使わなくなったかどうかを確認したいってことだと思うのですが、
無理☆という結論に。
使用されるモジュールというのは動的に決定されるので、すべてのケースを網羅したテストがあると可能ですが、じゃぁそのテストが完璧だっていうのはどうやって検証するのっていう、、、、。

動的な言語では全部無理じゃないかなぁ。

また根本的な話だと、使わなくなったモジュールを完璧に排除する必要は無いな、と思います。
動的なんで、ホントに使ってないならロードもされないですから。
(使ってない=useしてない、 排除=ライブラリソース自体置かない)





2012年8月7日火曜日

mysqld_multi

my.cnfを設定して、mysqld_multiを起動
sudo mysqld_multi start
sudo mysqld_multi report


mysqld_multi stop でshutdownしないので、両方のmysqlでやっておく。(passは設定してない状態)
mysql > grant shutdown on *.* to mysql@localhost identified by '';

レプリケーションの設定
マスターでユーザ作成
mysql> GRANT REPLICATION SLAVE ON *.* TO repl@localhost IDENTIFIED BY 'repl';

マスターのデータコピー。このときマスターに変更がないようにテーブルロックか、インスタンス落とすかしておく。
sudo mysqld_multi stop
sudo cp -aR /var/lib/mysql/* /var/lib/mysql_repl1/

show master statusで確認、
file: mysql-bin.000003
position:106

CHANGE MASTER TO MASTER_HOST= 'localhost', MASTER_USER='repl', MASTER_PASSWORD='repl', MASTER_LOG_FILE='mysql-bin.000003', MASTER_LOG_POS=106

2012年7月1日日曜日

Perl Beginners #3 レポート



大まかな内容は他の人のレポートにまかせますw

初心者セッション?で発表されていたのは、以下のようなコードでした。
https://github.com/studio3104/out-exec-mysql-slowquery/blob/master/explain2.pl

その場でいろいろ突っ込みは入ったものの、
納得できてもいきなり書けるもんじゃないと思うので、次の日にちょろっと書いてみた。
15分くらいだったから当日その場で書けばよかった気もしますが、無線持ってないもんで、、、、。

https://github.com/tokubass/out-exec-mysql-slowquery/blob/master/explain2.pl

動作確認してないので、参考程度にお願いします。
んで、要点としては


if文のネストは避ける & 長いifのあとにelseがくるのを避ける

方法は、elseの処理がreturnやnextであれば、



if(hoge){
# 20行くらいの処理
}else{
return;
}


は、



unless (hoge){
return;
}
#以下、ifが真のときの処理


のように書けます。
if文頭に、「受け取ったJSONをそのままMessagePackにして放出」と、elseの処理をコメントで書いてありますが、これが必要だったのはelse文がすごく下のほうに書いてあるためだと思われます。


正規表現はマッチすれば真を返す

ので、以下は冗長で、



my ($db) = ($decode->{sql} =~ /^use ([^\;]+)/i) if ($decode->{sql} =~ /^use [^\;]+/i);


は、



if ( $decode->{sql} =~ /^use \s+ ([^\;]+)/xi ) {
$db = $1;
}


でOK.


後置ifとmy宣言の組み合わせはダメ絶対

上記の正規表現で出てきましたが、
perldocによると、



注意: (my $x if ... のような) 条件構造やループ構造で修飾された my 文の振る舞いは 未定義 です。 my 変数の値は undef かも知れませんし、以前に代入された値かも 知れませんし、その他の如何なる値の可能性もあります。 この値に依存してはいけません。 perl の将来のバージョンでは現在のバージョンとは何か違うかも知れません。 ここには厄介なものがいます。



なので、気をつけましょう。
また、PBP(perlベストプラクティス)に従うならば、後置ifはnextやreturnなど、制御の流れを変えてしまうようなものを目立たせるためにのみ使うと書いてあります。


その他



  • hashの使い方がおかしかったので修正

  • @でデリファレンスするとき、リファレンスが配列を指してないと落ちる。元コードはdefinedで空かどうかだけチェックしてたのを、refで配列かどうかのチェックに変えてみた。



ちなみに、
'ARRAY'や'HASH'のかわりに、[],{}もよく使われます。


お疲れ様でした


お題がDBということもあって、「perlは専門じゃないインフラエンジニア」が集まってた感もあって良かったんじゃないでしょうか。





2012年6月17日日曜日

openssl-develを入れたらssh接続できなくなった



openssl-develを入れたら、/var/empty/sshdに書き込み権限が付与されていて、ssh接続できなかった。えぇ、、、、





2012年6月10日日曜日

Perl Beginners の下見にいってきた



2012/06/29 にPerl Beginners #3 が開催されるとのことで、参加登録をしようと思ったのですが、すでにいっぱいで補欠でした。これは残念。
ところが、LT枠が余ってるではありませんか、ここに滑り込ませていただきました。

しかし、いかんせん埼玉から遠く、初めての土地なので道に迷いそうです。
LT枠まで取っておいて当日遅刻などできないので、会場である京橋区民館に下見に行くことにしました。

近くに駅はあるようですが、よくわからないので、とりあえず東京駅から歩くことに。

まずは八重洲中央口を出てまっすぐ大きい道を行きます。

大きな地図で見る

この道の左側を歩いているなら、途中に交番とセブンイレブンがあります。

大きな地図で見る
突き当たりの交差点の対角線に移動して、右に進みます。
スギ薬局がよい目印です。スギ薬局の一つ向こうで左に曲がってまっすぐいくと右手に目的地が見えます。
ストリートビューではまだスギ薬局ではなく昭和ビルのようです。隣のサンマルクカフェはありました。

大きな地図で見る

自分は建物の入り口の方角を間違えてよくわからないところに行ってしまったので気をつけてください。
細い道に入ったら右手に見えますので。(ちょうど周りにハッピを着た京橋二丁目会の方々が集まっていたので、道を教えてもらいました。)


会場の中に入ってみると、当日開催される3階には「6/9 京橋二丁目会会場」と書かれていました。
20日後にはここにPerlの文字が並ぶのですね、胸熱です。

これで目的は達成できたのですが、この残った胸熱感、どうしてくれましょう。
いきおいATNDまで立ててしまいました。

とりあえず誰も集まらなくても一人酒でコード書きます、、、

ああ、楽しい下見だったなぁ、、、
とりあえず電車の中で即興で書いたLT資料を書き直すかぁ、、、

※あまりに気づいてもらえないので、書くけど、日程間違えたんだよ!!





2012年5月31日木曜日

JSX触ってみた



インストール


環境

CentOS6


node.jsとnpm

node.jsは公式サイトからソースDL
普通に、./configure, make, sudo make installで入ります。

次にnpm
curl http://npmjs.org/install.sh | sudo sh


jsx本体

git clone https://github.com/jsx/JSX.git
make setupで、nodeモジュールとperlモジュールが入る。


サンプルを動かす


make web
make server
とすると、サーバーが起動してブラウザ上でサンプルが動かせる。


CUIで動かす


jsx --run hoge.jsx


ドキュメント


ここを一通り読んだ
あわせてtoggetter



  • CUIで最初に実行されるのはmain関数(最初に実行される関数のことをなんて表現するんだっけ、、、)



jsx --test foo.jsx って書くと foo.jsx の(プライベートクラスである) _Test クラスの test で始まる関数が実行されて TAP 形式で集計する



とのことなので、指定しないときのデフォルトが_Mainクラスのmain関数ってことですね。





    • 基本的に文字や数値などの組み込み型は、変更不可だし、undefinedも許されない

    • 文字列の配列string[]やDate、functionは変更可。

    • MayBeUndefined型が追加されている。




  • 関数

    • 引数が異なる同じ名前の関数が存在できる。引数でどの関数が実行されるか変わる。





感想


思った以上にjava likeだった。
ところで、型を表示するのってどうすればいいのかな。


追記


string(nullにならない)とString(nullになり得る)の違いがあって元々JSの仕様だとか。





2012年5月30日水曜日

daemontools



以下Ubuntuの場合。
CentOSの場合は、こちら


インストール



$ sudo apt-get install daemontools daemontools-run svtools
$ sudo reboot # svscanを起動するため再起動



設定


/service以下にプロジェクトと同じ名前のディレクトリを作成。
(logをとる場合、一旦 .pj名のようにドットを入れておいて、daemontoolsに認識されないようにしておいてlog/runも準備してから、renameする。このタイミングでしかsuperviseを作ってくれないみたい。)

しかしubuntuは/etc/service/だった。
/etc/service/サービス名/runを作成。このrunはプロジェクトの中に書いておいて、それのシンボリックリンクにする。


log設定


以下を作成。
/etc/service/サービス名/log/run
/etc/service/サービス名/log/main/

runの中身は、



#!/bin/sh
exec setuidgid logadmin multilog t s1000000 n100 ./main


ユーザも作成しておく。
sudo /usr/sbin/useradd -s /sbin/nologin -d /dev/null logadmin
あとは各ディレクトリの権限をlogadminが書き込めるようにしておく。

以下でログ監視。
tail -f /etc/service/PJ_name/log/main/current | tai64nlocal


動作確認


ps auxf で見てみる。
readproctitle service errors: ...ile does not exist?supervise: fatal
エラーでてるけど、正常に動く、、、はて。
killしてみて、異なるPIDで復活してたので、OK。

追記
http://tech.dclog.jp/2010/12/daemontools.htmlによると、
readproctitleは一度エラーメッセージを出すと、ずっと残るようだ。
メッセージクリア用のコマンドを用意して、消したいときに消せるようにする。

/service/clearmsg/run



#! /bin/bash
yes '' | head -4000 | tr '\n' .


touch /service/clearmsg/down #普段は実行させない
svc -o /service/clearmsg #一度だけ実行





ファイル監視で再起動



今さら感満載。


コマンド


plackup -r でlib以下を監視。それ以外なら-Rオプション。


CPU使用率を下げる


監視は有名所の、Filesys::Notify::Simpleを使用。これは以下を入れておかないと、ディレクトリ以下をフルスキャンするので、以下のxsモジュールを入れておくとCPU使用率が下がる。



  • linux

    • Linux::Inotify2



  • mac

    • Mac::FSEvents





そもそもリクエスト時だけ再起動する


再起動のモジュールをLオプションで指定できるので、shotgunを入れておくと、ファイル変更時ではなく、リクエスト時に再起動がかかる。
plackup -L Shotgun

http://d.hatena.ne.jp/sugyan/20100404/1270320069


関係ないけど、以下で、psgiの仕様にそってるかチェックできるらしい。
enable 'Lint';





2012年4月7日土曜日

第2回 Ruby On Rails 勉強会 渋谷



第2回 Ruby On Rails 勉強会 渋谷にお邪魔してきました。
ハッシュタグは#rorshibuya
不完全なので、思い出したら書き足す。


Rubyの基本


コロン2つで始まるメソッド名

::hogeで始まるメソッド名は、クラス名を省略している。相対パス。


例外処理

レスキューを使う。endまでがスコープなので、defの最後に書く。


文字コード

1.8系はKCODEで文字コード指定。これはruby全体の文字コードを指定している。
(ruby起動するときに引数で指定も出来た。)
1.9系はKCODE廃止
1.9系では各オブジェクトごとに文字コードを指定できる。これはPerlと違い内部エンコーディングの指定
magic_commentで文字コード指定。
コード内で非アスキーを使う場合は必須。


rails


ソースコードリーディング

中は魔窟だが、activesupportは読みやすい。
core_extはarrayのメソッドなどを拡張している。


scaffoldは使わない?

RESTで作成されるけど、現実のお仕事ではRESTでないことが多いので臨機応変に。


Rubyの求人って無いよね


基本的に人づてらしい。
(でもベンチャーだと、人材がいるかどうかで決まるから、Rubyの会社じゃなくてもルビリストが集まればRubyの仕事はできると思うけどって、話を後でした。)


便利なCSSフレームワークは?


fbootstrapp ( twitter boostrap1とは互換性があるが、2だと少し書き換えが要るらしい)


pjax使って簡単に実装できる?


backboon.jsが使える?


twitterのブックストリームをリアルタイムに取得


twitter API stremingならpush型で取得。接続維持してるので、commetっぽい。


Rubyコミュニティ


地域Rubyの会


作られてたサービス


シェア住
備忘録りくわいや


モジュール検索


ruby toolbox


oauth


twitter oauth
定番はomniauth


twitterなどでデータマイニングしたい


形態素解析はmecabが定番。
統計はお手軽にベイズはいかが。
ベイズのサンプルとしてはスパムフィルターであるbsfilterがRubyで書かれている(モジュールもあるだろうけど)


heroku以外でサーバーとかどう準備したらいい?


商用サービスなど、もう少し真面目に作るけど、人材リソースはないって場合。
よく覚えてない、、、結局amazonとかそういう話になったかも。
とりあえずデータベースのバックアップもあるから1台で全部やるのは厳しくないかって話はでた。
railsは結構メモリを食うので、データベースとの共存は厳しい?MySQLなら最低メモリ16GB必要。





2012年3月21日水曜日

渋谷 HTML5+CSS3+JS de ゲーム勉強会 x コロプラ事例発表



ちょっと畑違いだけど勉強会に行ってきました。
覚えてることだけ。

メディアクエリー


メディアクエリー
デバイスごとにCSSを適用したりする。
書いたことあるけど、メディアクエリーって名前だったんだ。仕様読まないとなー。

画像系の高速化


起動時のHTTP経由の画像取得が遅い

アプリに埋め込んで解決。
ただしキャッシュはブラウザキャッシュが最速なので、アプリから画像を引っ張ってくるほうが遅い。

ネットワークが不安定でも動くように、LocalStrageを使う。



  • WebStrage

    • LocalStrage

    • SessionStrage



SessionStrageはウインドウを閉じると消える。
Strageを使う際は他のユーザの影響で変化するパラメータ(オフラインの間にサーバー側で値が変わってる値)などは保存しない。

懇親会で、上書きされたりしないの?って聞かれたけど、以下のような仕様だった。


ユーザーエージェントは、localStorage 属性によって返された Storage オブジェクトのメンバーのうち一つでも、有効なスクリプトの origin と、localStorage 属性がアクセスされた Window オブジェクトの Document の origin と同じでないときは常に、SECURITY_ERR 例外を投げなければいけません。

これは、document.domain 属性が使われるときには Storage オブジェクトは中性化されることを意味します。


うん、それぞれのwindowオブジェクト配下だもんね。

その他


コロプラでゲーム作るのに、エンジニアとかデザイナとか各1名ずつで6名くらい?で大体4ヶ月。
感覚としてなんとなく覚えておこう。
戦闘バランスの調整が大変とか。RPGツクールを思い出すなぁ、、、、。




2012年3月18日日曜日

ubuntuでDBD::mysqlのインストールに失敗



cpanm DBD::mysql でこけた。
cpanmで失敗したDBD::mysqlを(半)手動でインストールする
--mysql_configオプションに、mysql_configのパスを与えればいいようです。

ubuntuだと、mysql_configが入ってないようなので、
sudo apt-get install libmysqlclient15-dev

mysql_configが/usr/bin/に入っちゃったせいか、
もう一度cpanmで入れるとすんなり入った。





2012年3月14日水曜日

モーダルウインドウ内のHTMLのscriptタグが消える



結論


jQuery.html(data)としたとき、data内に存在するscript要素が切り取られた状態でappendChildされる。
切り取られたscriptはappendChildの前に、evalScript関数で評価されている。

jQuery.prettyPoppin.jsがモーダルウインドウ用の領域を作成して、そこにjQuery.htmlでhtmlを貼り付けていたので、貼り付けたhtml内のスクリプトは実行されるが、DOMには追加されていなかった。


jQuery.htmlの実装


引数の中に、<scriptか<style があると、innerHTMLではなく、jQuery.appendが呼ばれる。
appendではDomManip関数とclean関数が呼ばれ、ここで、スクリプトを切り出して、実行。
append関数は最後に、appendChildを呼ぶ。


素のJSの場合


innerHTMLでは[object HTMLScriptElement]が表示され、
appendChildだと、スクリプトが実行されて、かつスクリプト自体も残っている。(ブラウザ依存)

確認用



<html>
<head>
<script src="http://www.google.com/jsapi"></script>
<script>google.load("jquery", "1.7.1");</script>
</head>
<body>
<div id="target">aaaaaaaaaaa</div>

<script>
var script = document.createElement('script');
script.type = 'text/javascript';
script.innerHTML = 'alert(1)';
//どれかコメント外して動作確認
//$('#target').html(script);
//document.getElementById('target').appendChild(script);
//document.getElementById('target').innerHTML=script;
</script>
</body>
</html>





2012年3月11日日曜日

chmod 1775でSticy設定



所有者と、root権限以外は、ファイル内容の変更は出来ても、削除とリネームができない。




jQuery BBQメモ




  • ハッシュフラグメントをみるイベント

    • $(window).hashchange(function(){});

  • クエリを配列に格納

    • $.deparam.querystring();

  • ハッシュフラグメント取得

    • $.param.fragment()




2012年3月3日土曜日

初めてのrails



【第2回】yoyogi.rb Ruby初心者向け で、HatchUp!に行ってきました。


教材


commitsログが教材
nysalor/twit


railsインストール



sudo gem install rails
Building native extensions. This could take a while...
ERROR: Error installing rails:
ERROR: Failed to build gem native extension.

/usr/bin/ruby1.9.1 extconf.rb
<internal:lib/rubygems/custom_require>:29:in `require': no such file to load -- mkmf (LoadError)
from <internal:lib/rubygems/custom_require>:29:in `require'
from extconf.rb:1:in `<main>'


Gem files will remain installed in /var/lib/gems/1.9.1/gems/json-1.6.5 for inspection.
Results logged to /var/lib/gems/1.9.1/gems/json-1.6.5/ext/json/ext/parser/gem_make.out


失敗。mkmfがない。



apt-cache search mkmf
apt-get install ruby1.9.1-dev
sudo gem install rails



プロジェクト作成



rails new twit -T #TはTest::Unitを入れない



複数バージョンのruby,rails管理


rvm(Ruby Version Manager )
http://www.machu.jp/diary/20110521.html#p01
perlbrewみたいなもの?今回はスルー。


サーバー起動



rails server


エラー。

javascriptの新しいエンジンがいるようだ。
node.jsをいれてもいいけど、
projectディレクトリ内のGemfileを編集。



# 追記
gem 'execjs'
gem 'therubyracer'



bundle install


これでサーバーが起動できる。


ひな型作成


userモデルとuserコントローラ作成

viewもあるけど、scaffoldだから?雛形をいじるのはどこ?



rails g scaffold User name:string


Tweetモデル作成


rails g model Tweet body:string user_id:integer


以下が作成される。timestampsは勝手に作成されるのね。



# twit/db/migrate/....._create_tweets.rb
class CreateTweets < ActiveRecord::Migration
def change
create_table :tweets do |t|
t.string :body
t.integer :user_id

t.timestamps
end
end
end

# app/models/tweet.rb
class Tweet < ActiveRecord::Base
end



作成したモデルから、テーブル作成。(db/schema.rbが設定される)



rake db:migrate



テーブル間のリレーションを定義


belongs_to

tweetがuserに属していることを記述。一方通行の関係性ですね。
これ、tweetテーブルにuser_idってカラムを自分で作成しないでいいんですね。



# app/models/tweet.rb
class Tweet < ActiveRecord::Base
belongs_to :user
end




# app/models/user.rb
class User < ActiveRecord::Base
has_many :tweets
end



users#showにtweetを表示




<p>
<b><%= @user.name %>さんのつぶやき</b>
<ul>
<% @tweets.each do |tweet| -%>
<li><%= tweet.body %></li>
<% end -%>
</ul>
</p>


tweetを表示させる。
コントローラに書いてある@hogeはインスタンス変数なので、viewで使用できると言われてよくわからなかったけど、
<% %>はruby文法をそのまま記述しているからっぽい。


userコントローラにtweetメソッド追加



# POST /users/1/tweet
def tweet
@user = User.find(params[:id])
@tweet = @user.tweets.create(:body => params[:body])

redirect_to @user, notice: 'Tweet was successfully updated.'
end


tweetメソッドに与えるパラメータをurlから取得


# config/routes.rb
match '/user/:id/tweet' => 'users#tweet', :as => :user_tweet


/user/1/tweet にアクセスすると、usersコントローラのtweetメソッドの :idに1が入る。
:asでメソッドへのalias設定。'_path'を末尾に追加した名前が使える。



# views/users/show.html.erb
<%= form_tag user_tweet_path do %>
今何してる?:<%= text_field_tag :body %>
<%= submit_tag %>
<% end -%>



ロジックをコントローラからモデルに移動


@user.tweets.create(:body => params[:body]);をUserモデルのメソッドに。
メソッド名はtweet!のようにビックリをつけるのが好みだそう。


orderメソッド


@user.tweets.order('created_at DESC')
で日付順を逆に。
orderって記述はActiveRecordeのメソッド?


scopeでsqlの遅延評価


直接sqlを書かないようにするだけならメソッド化でいいが、遅延評価できるようにscopeを使用。
モデルクラスに、



scope :newer, order('created_at DESC')


と書いてnewerメソッドとして使用。
@user.tweets.newer.limit(10) としても、全件とってきてから10件取得しないで済む。


partial(部分テンプレート)


TTでいうところの、INCLUDE,PROCESSみたい。外部ファイル読み込み。



<%= render :partial => "tweets" %>


_tweets.html.erbって名前のファイル内容を挿入してくれるっぽい。
命名規則があるのかな?だとするとちょっと分かりにくいかなぁ。
TTみたいにパスを直接書くほうが管理しやすいかも。

メモ



:collection で渡しているインスタンス名がパーシャルの名前とそろっていること。規約により、hogehoge.html.erbをコレクションのサイズだけループしてくれるらしい。そしてさらに引数が渡したければ、localsを使う。




ajax


まず、ajaxだからredirect_toは削除。
form_for、link_to:remote => trueを加えると非同期処理になる。
サンプルではajaxでテンプレートを貼り付けてたけど、テンプレートが評価された後にJSの引数として評価されてるのかな。





2012年2月29日水曜日

パッケージの依存関係を調べる。



参考



apt-cache depends rails #railsが依存しているパッケージ一覧
apt-cache showpkg rails #railsに依存しているパッケージ一覧





2012年2月16日木曜日

cronのログ



cron自体が実行されたかどうかのログ



/etc/syslog.confに下記を設定
cron.* /var/log/cron




cronに登録したコマンドのログ



コマンド >> log.log 2>> err-log.log



>>は1>>の省略系
1とか2はプロセスが持つファイルディスクリプタ(ファイル記述子)の番号。
0(標準入力),1(標準出力),2(標準エラー出力)は固定番号。





gitのconfig3種類



参考


pro Git

gitは



  • /etc/gitconfig

  • ~/.gitconfig

  • git管理下のプロジェクト/.git/config


の順に設定を読む込む。
優先順位は後から読み込んだほう。

config --global は~/.gitconfigに書き込んでいる





サブシェル



参考


UNIXの部屋


サブシェル



  • シェルから起動した別プロセスのシェル


起動


  • ()でくくる



利用例

(cd ~/ ; make)
別プロセスでcdとmakeが行われているので、このコマンド実行後のディレクトリは
cdする前のディレクトリのまま


export


親シェルを継承したサブシェル(別プロセス)に変数をコピー(孫以下にも適用)
コピーなので、他シェルに影響しない。





プロトタイプ



最初に&があると、特別扱いされて、無名サブルーチンの sub を省略して「間接オブジェクト」スロットにブロックだけを置くことができる(この場合、ブロックの後ろにはコンマは置かない)。
func(@ary, sub { $_*2 } ) が func { $_*2 } @ary になる。



sub hoge ($&) {}
hoge 'foo', sub {}; #ok

sub hoge2 (&$) {}
hoge2 {} 'foo'; #ok


sub aaa (&) {}
aaa sub{} #ok
sub mymap (&@) {}
mymap {} qw( a b c d ); #ok
mymap sub{}, qw( a b c d ); #ok
mymap sub{} qw( a b c d ); #NG subが付くと、コンマが必要



Plack::Builderの例



package Plack::Builder;
sub builder (&) {

}


app.psgiの中で、



builder {
...
$app;
}


で実行できる。





暗号系、Cipherとか



Plain Text(平文)=> Encrypt(暗号化)=> Cipher Text(暗号文)

Salt(塩) 暗号化する前の対象文字列に、いくつか文字列を追加しておくこと。




コードのインデント揃える



指定範囲のインデントをそろえる。
C-x h ・・・ mark-whole-buffer
C-M-¥ ・・・ indent-region





2012年2月8日水曜日

Dropboxをubuntuに入れる



wget https://www.dropbox.com/download?dl=packages/dropbox.py
で取得したスクリプトを実行。
dropbox.py start -i
表示されたパスにブラウザでアクセスして、ログインパスワード入力。
これでDropboxディレクトリが出来ている。

lsof -i:17500
とすると、UDPが動いている。これを切るのは、

wget http://dl.dropbox.com/u/340607/pyDropboxValues.py
wget http://dl.dropbox.com/u/340607/dropbox_set_lansync.py

なんだけど、
An error occured: Unhandled DB schema version 2
と怒られる。

んー、なんだろ。とりあえず、dropboxデーモン切っておこう、、、





2012年2月6日月曜日

Amon2 make testが通るまで



追記


だいぶ情報が古いです。
今(2014.02.16)はcpanm --install-deps . でとくにエラーもならず入った。
あとJSLintではなくJSHintに変わってる。


チュートリアル


チュートリアル


いろいろインストール


cpanm Amon2 Amon2::DBI
cpanm Plack::Middleware::ReverseProcy
cpanm DBD::SQLite
cpanm HTML::FillInForm::Lite
cpanm Test::WWW::Mechanize::PSGI


バグ


とりあえずハマるのは、SQL-Interp-1.20がテストでコケルこと。古いバージョンにする。



cpanm http://search.cpan.org/CPAN/authors/id/M/MA/MARKSTOS/SQL-Interp-1.10.tar.gz



セットアップ


skinnyというオプションはないみたい?



amon2-setup.pl --skinny Hello




ここまでで、plackup app.psgiが動いた。しかしmake testが全然通らない。
ぉ、パスの部分を見るとperl5.10と書いてある。これはシステムperl。
今はperlbrewで5.14になってるはずなんだけど。
makefileにも5.10と書いてある。
とりあえずmake cleanして、もう一度perl Makefile.PL && make && make test
今度はOK.makefileにも5.14と書いてある。はて、何だったんだろ。


JSLint


JSLintが入ってないので、skipされているtestがある。
でもJSLintの入れ方がわかんね!
散々時間を食ったけど最終的にまたしてもtokuhiromさんのブログで解決。



sudo aptitude install libnspr4
wget http://www.javascriptlint.com/download/jsl-0.3.0-src.tar.gz
tar xzvf jsl-0.3.0-src.tar.gz
cd jsl-0.3.0/src/
make -f Makefile.ref
cp -a Linux_All_DBG.OBJ/jsl /usr/local/bin/



やっとmake testが通った、、、





is_deeplyの代わり



これはすごい。超見やすかった。
is_deeplyだと失敗したときに、どこが違うのかわからないけど、テキストに落としてから差分をとればいい、とのこと。

http://d.hatena.ne.jp/tokuhirom/20080308/1204999977

use YAML;
use Test::More;
use Text::Diff;

$got_dump = YAML::Dump($got);
$expected_dump = YAML::Dump($expected);

ok $got_dump eq $expected_dump, Text::Diff::diff(\$got_dump, \$expected_dump);





apacheからnginxに切り替える際に、リトライを書き換えるのが大変なとき



フロントをapacheからnginxに切り替える際に、リライトの設定をするのが面倒なら、
not foundだったものはすべてバックエンドに流すのもアリ。




2012年1月14日土曜日

歴史修正git



ブランチの削除


git push origin :ブランチ名
githubのfork自体がなくなるわけではない。

commitの修正


以下が、わかりやすい。
Git初心者が絶対に覚えておくべきコマンド30

また上記の記事を読む前に、addとcommitで管理してる場所が違うことをわかっておかないと混乱する。
図解git

git commit --amend

新しいコミットを、ひとつ前のcommitと入れ替える。
なので、やり直したい変更を直して、addしてから、git commit --amend

git reset

これは図解gitにもあるので、見るといい。図解git
HistoryのHEADが指すcommitを変更するが、その際のオプションにより、新しく指されたcommit先の内容をindexと作業ディレクトリにも反映させるかどうかを指定する。


  • --softでHEADだけ。

  • デフォルトでindexも変更

  • --hardでindexと作業ディレクトリも変更。



git reflog

gitのHEADがたどってきたcommitのログ。
これがあるので、誤って失ったcommitは大抵取り戻せる。
git reset --hard HEAD@{自然数}