2010/03/30

MySQL Proxyをちょっと触った

MySQL Proxyを少し触ったのでメモ

MySQLサーバとクライアントに入るミドルウェア。
現在のversionは0.8.0でbeta状態。

--proxy-addressで自分の待ち受けポート等を指定できる。
FAQだとsocketで待ち受けはできないって書いてあるけど、すげー下の方にあるコメントを読むと待ち受けできるよ!って書いてあった。
実際できる。

ただし作成されるsocketの権限が1755で、オーナーが--userで指定したユーザではなく起動ユーザになっているので、
他のユーザから書き込めない可能性がある。
CentOS 5.4Finalのyumから入れたmysqld-serverだとデフォルトで作成されるsocketは1777になっていた。
同じパーミッションに変更してあげると普通にmysql-clientからも接続できた。

またmysqlはデフォルトでsocketとTCP接続の両方で待ち受けるけど、MySQL Proxyはどちらか片方でしか待ち受けできない。
localhost上にあるMySQLへの接続をProxyしようとすると、MySQL Proxyを二つ走らせる必要がありそう。

シグナルの処理がおかしい気がする SIGTERMとかSIGHUPを送っても反応がなかったりとか。

2010/03/05

Mojoliciousのメモ

Mojoliciousをちょっと使ってて覚えたことをメモ。

まずリダイレクトではまった

Apache(mod_proxy)+Mojolicious(daemon_prefork)の構成


ProxyRequests Off
ProxyVia On
ProxyPass /hoge/ http://localhost:3000/
ProxyPassReverse /hoge/ http://localhost:3000/

上記のように設定して、http://example.com/hoge/をhttp://example.com/hoge/fuga/xxxxxにredirectしようとredirect_toを使ったら、http://example.com/fuga/xxxxxにredirectされた。

原因はMojoliciousのredirect_toが吐き出すLocation headerが相対URLだったため、ProxyPassReverseでドメインが書き換えられなかったことだった。

解決策としてMojolicious::Controllerを継承したクラスにredirect_to_absを実装した。


package MyApp::Controller;

use strict;
use warnings;
use base 'Mojolicious::Controller';

sub redirect_to_abs {
my $self = shift;
my $url = $self->url_for(@_);
return $self->redirect_to( $url->to_abs->to_string);
}
1;


次にpathのcaptureで時間を食ったのでメモ

pathをcontroller側でパラメータとして受けとる場合は下記のようにしないといけない。

my $r = $self->routes;
$r->route('/hoge/:id')->to('example#hoge', id => undef);

"id => undef"がポイント。デフォルト値を与えない場合は明示的にundefを渡してやらないと、controller側で値を取得できない。

controller側では下記のようになる。

package MyApp::Example;

use strict;
use warnings;
use base 'Mojolicious::Controller';

sub hoge {
my $self = shift;
my $id = $self->param('id');
}
1;

Catalystみたいに$cに続いてキャプチャできるのかと思ってたら、全然違ってハマった。

2010/02/04

VMware上のUbuntuの移行でnetworkに接続できない

会社で使用しているPCがリースアップするため、新PCに移行作業中におきた現象。

旧PCで使用していたUbuntuのイメージを新PCへコピーしたところ、ネットワークに接続できなかった。
原因はNICのMACアドレスが変更されていたため、eth0になるべきところがeth1になっていたことだった。

検索すると同様の現象が結構でてきた。
VMWareのUbuntuは複製するとNetwork設定変更が必要

udevのruleを書きかえて再起動で無事ネットワークに接続可能になった。

2009/11/22

Lisp備忘録 リストを利用したその他の形式

ツリー構造
リストの各コンスセルの中にリストを押し込んでいけばいい

CL-USER> (list (list 1 2) (list 3 4) (list 5 6))
((1 2) (3 4) (5 6))

ツリーを丸ごとコピーするにはcopy-tree.
copy-listでは内部の(1 2)などのセルはコピーせずに参照になる.

集合
adjoinを使って作成できる.
adjoinは非破壊的関数なので,直接元の値を変更する場合はpushnewを使う.

CL-USER> (defvar *x* nil)
NIL
CL-USER> (setf *x* (adjoin 1 *x*))
(1)
CL-USER> (adjoin 1 *x*)
(1)
CL-USER> (pushnew 2 *x*)
(2 1)
CL-USER> *x*
(2 1)


集合操作関数
リストを一つだけとる関数
member - 集合にあるアイテムが含まれているかどうか.

リストを2つ引数に取る関数
intersection - 両方の集合に含まれている要素のリストを返す.
union - 2つのリストに含まれているユニークな値のリストを返す
set-differece - 最初のリストに含まれていて二つ目のリストには存在しないもののリストを返す.
set-exclusive-or - 両方のリストのどちらか一方にだけ存在している要素のリストを返す.
上記4つの関数は頭にNの付く破壊型関数がある.

連想リストと属性リスト
連想リストはassocを使用してアクセスできる.

CL-USER> (assoc 'a '((a 1) (b 2) (c 3)))
(A 1)


通常通りconsを使用して連想リストを作成できるがCommon Lispにはacons関数もある.
非破壊的関数なのでsetfやpushを利用して値を変更する.

CL-USER> (acons 'a 1 *x*)
((A . 1))


属性リストはキーと値が順にならんだリスト構造.
A,B,Cを1,2,3に対応させた属性リストは(A 1 B 2 C 3)といった構造になる.
getf関数でキーに対応した値を取り出せ,setfで値を変更できる.キーと値の両方を削除するにはremfを使用する.

destructuring-bind
マクロのパラメータリストを受け取る時と同様に任意のリストの構造を分配できる.

CL-USER> (destructuring-bind (x y z) (list 1 2 3)
(list :x x :y y :z z))
(:X 1 :Y 2 :Z 3)




2009/11/21

Lisp備忘録 リストについて

リストの基礎
consで作成されるコンスセルでリストは作られる.
コンスセルの前をcar部, 後ろをcdr部を呼び,同名の関数でコンスセルにアクセスできる.

CL-USER> (defvar *x* (cons 1 2))
*X*
CL-USER> (car *x*)
1
CL-USER> (cdr *x*)
2


コンスセルの中でcdr部が他のコンスセルやnilでないものを特別にドットペアと呼ぶ.

;ドットペア
CL-USER> (cons 1 2)
(1 . 2)
;リスト
CL-USER> (list 1 2)
(1 2)
CL-USER> (cons 1 nil)
;リスト
(1)
;(list 1 2)をconsで生成する
CL-USER> (cons 1 (cons 2 nil))
(1 2)


コンスセルをリストとして扱うときにはcar, cdrだけじゃなくfirst, restで扱おうと書いてある.
多分後でそのプログラムを見たときに何を扱っているのかが明確になるからだろうか.


破壊的,非破壊的
appendは最後に与えられた引数以外をコピーして新しいコンスセルを作り,最後の引数をそのコンスセルにくっつける.
最後の引数だけはappendが返すリストと最後の引数ので同じコンスセルを参照するようになる.

破壊的な関数の頭にはNがつくことが多い.
reverseとnreverse, appendとnconc

CL-USER> (defvar *x* (list 1 2 3 4))
(1 2 3 4)
CL-USER> *x*
(1 2 3 4)
CL-USER> (reverse *x*)
(4 3 2 1)
CL-USER> *x*
(1 2 3 4)
CL-USER> (nreverse *x*)
(4 3 2 1)
CL-USER> *x*
(4 3 2 1)


破壊的関数は引数を後で使うつもりがなければ使用してもいい.
たとえば関数内でのレキシカル変数など.

(defun upto (max)
(let ((result nil))
(dotime (i max)
(push i result))
(nreverse result)))

よく使われる組み合わせはsetf, deleteとpush, nreverse.

consp, listp, atom,null
この三つの区別がいまいちわからなかったのでまとめ.

conspはオブジェクトがコンスセルかどうか.
listpはオブジェクトがコンスセルかnilかどうか.
atomはオブジェクトがコンスセルではないかどうか.
nullはオブジェクトがnilかどうか.notと等価だが真偽の評価ではなく空リストのテストとしてはこちらを使うべきらしい

mapcar, maplist
mapcarはリスト専用なのでmapのように型を指定する必要がない.

2009/11/13

Lisp シーケンス操作関数の続き

シーケンス反復関数
count, find, position, remove, substituteがある
指定できるキーワードとしてeqlで比較されるが、testキーワードに2引数関数を渡すことで比較関数を変更できる
from-endキーワードで逆順に処理、keyに1引数関数を渡すこともできる。
start, endキーワードで開始位置や終了位置の変更が可能

それぞれの関数にsuffixとして"-if, -if-not"をつけたものがある。
remove-if-notはPerlのgrepと同様の処理になる
下記は#\fから始まる文字列を取得

* (remove-if-not #'(lambda (x) (char= (elt x 0) #\f)) #("foo" "bar"))

#("foo")


重複を取り除くremove-duplicatesもある

シーケンス全体を一度に扱う関数
concatenate, copy-seq reverse
concatenateは1引数目に作成するタイプを入れる

* (concatenate 'string "abc" '#(#\d #\e #\f))
"abcdef"

* (reverse #(1 2 3 4))
#(4 3 2 1)

* (defvar *x* nil)
*X*

* (setf *x* (copy-seq #(1 2 3)))
#(1 2 3)

* *x*
#(1 2 3)


ソートとマージ
sort, stable-sort, mergeがある
sortとstable-sortの違いは述語によって等価と判断された要素の順番がかわるかどうからしい。
sort, stable-sortは破壊的関数なので必ず返り値を使用すること
(sort シーケンス 述語)
(merge シーケンス1 シーケンス2 述語)

部分シーケンス操作
(subseq シーケンス 開始インデックス 終了インデックス)
Perlのsubstrと一緒

部分シーケンスを見つける関数
search

(position #\b "foobarbaz") → 3
(search "bar" "foobarbaz") → 3

二つのシーケンスから異なる部分を見つけるのに[I]mismatch[/I]が利用できる。
キーワードとしてstart1, end1, start2, end2を利用可能
[CODE]
* (mismatch "foobarbaz" "bar")
0
* (mismatch "foobarbaz" "foom")
3
* (mismatch "foobarbaz" "bar" :start1 6)
8


シーケンス述語
every, some, notany, notevery

* (setf *x* #(1 2 3 4 5))
#(1 2 3 4 5)
* (every #'evenp *x*)
NIL
* (some #'evenp *x*)
T
* (notany #'evenp *x*)
NIL
* (notevery #'evenp *x*)


マッピング関数
map, map-into, reduce
map-intoは第1引数のシーケンスに第2引数のシーケンスをセットする

Perlに比べるとすげー多い。
List:MoreUtilsを標準で組み込んだ感じ

ハッシュテーブル
make-hash-table, gethash,remhash, clrhash
gethashの返り値は多値なのでmultiple-bind-valueで多値を受け取れる

(defparameter *h* (make-hash-table))
(gethash 'foo *h*) → NIL
(setf (gethash 'foo *h*) 'quux)
(gethash 'foo *h*) → NIL
(multiple-bind-value (value present) (gethash 'foo *h*))

setfとgethashでキーにnilを設定すると値がnilになる
remhashでキーを削除できる。
clrhashですべてのキーと値を削除できる

2009/11/12

Lisp写経 2回目

ベクタの作成
vector, make-arrayで作成できる

(vector 1 2 3) → #(1 2 3)
(make-array 5 :initial-element 1 :fill-pointer 0) -> #(1 1 1 1 1)


vectorで作成したベクタはvector-pop, vector-pushで変更できない。
make-arrayに:fill-pointerオプションを指定するとvector-pop, vector-pushで要素の変更が可能なベクタを作成できる。
#(1 2 3)とリテラル表記でもベクタは作成できるが、リテラルオブジェクトを変更した場合の処理は定義されてないので変更すべきではないらしい。

可変サイズのベクタを作成するにはmake-arrayで:adjustable tを追加する。
vector-push-extendを使用する。vector-pushと違い要素が一杯の場合は自動的に領域を拡張する

fill-pointerが設定されていなくてもeltで要素を指定してsetfすることができる

(defvar *x* #(1 2 3))
(setf (elt *x* 1) 20) → #(1 20 3)



EmacsだからなのかSlime環境だからかはわからないが、ミニバッファに関数の取れる引数が表示されることに今ごろ気づいた
こんな感じ

(make-array arg0 &key adjustable element-type initial-element initial-contents
fill-pointer displaced-to displaced-index-offset)