<?xml version="1.0" encoding="UTF-8" ?> <rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>かつのりの日記２</title><link>http://blogs.wankuma.com/kacchan6/</link><description>わんくまでは珍しいJavaを中心とした日記です</description><managingEditor>かつのり</managingEditor><dc:language>ja-JP</dc:language><generator>.Text Version 0.95.2004.102</generator><item><dc:creator>かつのり</dc:creator><title>PostgreSQLでパーティショニング</title><link>http://blogs.wankuma.com/kacchan6/archive/2008/07/03/147194.aspx</link><pubDate>Thu, 03 Jul 2008 23:48:00 GMT</pubDate><guid>http://blogs.wankuma.com/kacchan6/archive/2008/07/03/147194.aspx</guid><wfw:comment>http://blogs.wankuma.com/kacchan6/comments/147194.aspx</wfw:comment><comments>http://blogs.wankuma.com/kacchan6/archive/2008/07/03/147194.aspx#Feedback</comments><slash:comments>249</slash:comments><wfw:commentRss>http://blogs.wankuma.com/kacchan6/comments/commentRss/147194.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/kacchan6/services/trackbacks/147194.aspx</trackback:ping><description>&lt;p&gt;久々の投稿です。最近PostgreSQLばっかりやっているので、ちょっとしたTipsでも書こうかなと思います。 &lt;p&gt;PostgreSQLで大規模なDWHを構築しようとした場合に、データファイルとストレージの容量の問題に悩まされます。数億オーダーのレコードが想定されるならば、気軽にPostgreSQLを使うとはいいにくいのではないでしょうか。素直にOracleとかを使えばよいのですが、そうもなかなか言ってられません。そこでテーブルのパーティショニングでデータファイルを分散化し、分散されたデータファイルを別ストレージに追いやる方法についてまとめてみます。  &lt;p&gt; （今手元に動くPostgreSQLがないので、下のコードにバグがあったら後日直します・・・。） &lt;p&gt;まずは、何を格納するかについてですが、アクセスログを格納するという感じでテーブル設計してみましょう。（実際の業務でも似たようなことを・・・ry)  &lt;p&gt;まずはリクエストテーブル(request)&lt;/p&gt; &lt;table cellspacing="0" cellpadding="2" width="442" border="0"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td valign="top" width="174"&gt;物理名&lt;/td&gt; &lt;td valign="top" width="137"&gt;論理名&lt;/td&gt; &lt;td valign="top" width="124"&gt;型&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td valign="top" width="177"&gt;request_id&lt;/td&gt; &lt;td valign="top" width="137"&gt;リクエストID&lt;/td&gt; &lt;td valign="top" width="124"&gt;serial8&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td valign="top" width="179"&gt;timestamp&lt;/td&gt; &lt;td valign="top" width="137"&gt;リクエスト日時&lt;/td&gt; &lt;td valign="top" width="124"&gt;timestamp&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td valign="top" width="181"&gt;uri&lt;/td&gt; &lt;td valign="top" width="137"&gt;URI&lt;/td&gt; &lt;td valign="top" width="124"&gt;text&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td valign="top" width="183"&gt;user_agent&lt;/td&gt; &lt;td valign="top" width="137"&gt;ユーザエージェント&lt;/td&gt; &lt;td valign="top" width="124"&gt;text&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td valign="top" width="183"&gt;remote_host&lt;/td&gt; &lt;td valign="top" width="137"&gt;リモートホスト&lt;/td&gt; &lt;td valign="top" width="124"&gt;text&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt; &lt;p&gt;次にパラメータテーブル(parameter)&lt;/p&gt; &lt;table cellspacing="0" cellpadding="2" width="437" border="0"&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td valign="top" width="174"&gt;物理名&lt;/td&gt; &lt;td valign="top" width="137"&gt;論理名&lt;/td&gt; &lt;td valign="top" width="124"&gt;型&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td valign="top" width="177"&gt;parameter_id&lt;/td&gt; &lt;td valign="top" width="137"&gt;パラメータID&lt;/td&gt; &lt;td valign="top" width="124"&gt;serial8&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td valign="top" width="177"&gt;request_id&lt;/td&gt; &lt;td valign="top" width="137"&gt;リクエストID&lt;/td&gt; &lt;td valign="top" width="124"&gt;int8&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td valign="top" width="179"&gt;timestamp&lt;/td&gt; &lt;td valign="top" width="137"&gt;リクエスト日時&lt;/td&gt; &lt;td valign="top" width="124"&gt;timestamp&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td valign="top" width="181"&gt;name&lt;/td&gt; &lt;td valign="top" width="137"&gt;パラメータ名&lt;/td&gt; &lt;td valign="top" width="124"&gt;text&lt;/td&gt;&lt;/tr&gt; &lt;tr&gt; &lt;td valign="top" width="183"&gt;value&lt;/td&gt; &lt;td valign="top" width="137"&gt;値&lt;/td&gt; &lt;td valign="top" width="124"&gt;text&lt;/td&gt;&lt;/tr&gt;&lt;/tbody&gt;&lt;/table&gt; &lt;p&gt;というような感じになりました。そしてDDL。&lt;/p&gt; &lt;hr&gt;  &lt;p&gt;create table request(&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; request_id serial8 not null,&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; timestamp timestamp not null default now(),&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; uri text not null default '',&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; user_agent text not null default '',&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; remote_host text not null default '',&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; primary key(request_id)&lt;br&gt;);&lt;br&gt;create table parameter(&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; parameter_id serial8 not null&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; request_id int8 not null default 0,&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; timestamp timestamp not null default now(),&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; name text not null default '',&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; value text not null default '',&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; primary key(parameter_id)&lt;br&gt;);&lt;/p&gt; &lt;p&gt; &lt;hr&gt; &lt;/p&gt; &lt;p&gt;この時点では、まだインデックスや外部キーは不要です。&lt;/p&gt; &lt;p&gt;そして次にパーティショニングの戦略を考える必要がありますが、年月単位でパーティショニングを行ってみましょう。PostgreSQLでのパーティショニングは自動化されないので、テーブル継承と振り分けルールによって行うようにしてみましょう。&lt;/p&gt; &lt;p&gt;まずは表領域を作成します。(事前にpostgresユーザでディレクトリを作っておきましょう)&lt;/p&gt; &lt;hr&gt;   &lt;p&gt;create tablespace log_space_200807 location '/var/local/pgsql/log_spaces/log_space_200807'; &lt;p&gt; &lt;hr&gt; &lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;この表領域を利用する、リクエストテーブルを継承したテーブルを作成します。check(条件)という構文が出てきましたが、これはこのテーブルにはこの条件のレコードしか入らないという宣言です。以下の場合、タイムスタンプが2008年7月の日付のレコードしか入りません。&lt;/p&gt; &lt;hr&gt;   &lt;p&gt;create table request_200807(&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; check(&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; '2008-07-01' &amp;lt;= timestamp and timestamp &amp;lt; '2008-08-01'&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; )&lt;br&gt;)&lt;br&gt;inherits(request)&lt;br&gt;tablespace log_space_200807;  &lt;p&gt;create index&lt;br&gt;ix_request_200807_1&lt;br&gt;on request_200807(request_id)&lt;br&gt;tablespace log_space_200807;  &lt;p&gt;create index&lt;br&gt;ix_request_200807_2&lt;br&gt;on request_200807(timestamp, uri)&lt;br&gt;tablespace log_space_200807; &lt;hr&gt;  &lt;p&gt;そしてパラメータテーブルを継承したテーブルを作成します。チェック制約は同様です。&lt;/p&gt; &lt;hr&gt;  &lt;p&gt;create table parameter_200807(check(&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; '2008-07-01' &amp;lt;= timestamp and timestamp &amp;lt; '2008-08-01'&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; )&lt;br&gt;)&lt;br&gt;inherits(parameter)&lt;br&gt;tablespace log_space_200807;  &lt;p&gt;create index&lt;br&gt;ix_parameter_200807_1&lt;br&gt;on parameter_200807(parameter_id)&lt;br&gt;tablespace log_space_200807;  &lt;p&gt;create index&lt;br&gt;ix_parameter_200807_2&lt;br&gt;on parameter_200807(&lt;br&gt;request_id, name, timestamp)&lt;br&gt;tablespace log_space_200807; &lt;p&gt; &lt;hr&gt; &lt;/p&gt; &lt;p&gt;ここでインデックスが出てきました。継承元にはデータを格納しない為インデックスは不要ですが、継承したテーブルはデータを格納するためインデックスが必要になります。そして外部キー制約を設定します。これも実際にデータを格納するテーブル同士で設定します。&lt;/p&gt; &lt;p&gt; &lt;hr&gt; &lt;/p&gt; &lt;p&gt;alter table parameter_200807&lt;br&gt;add constraint fk_parameter_200807_1&lt;br&gt;foreign key(request_id) references&lt;br&gt;request_200807(request_id)&lt;br&gt;on delete cascade; &lt;p&gt; &lt;hr&gt; &lt;/p&gt; &lt;p&gt;&lt;/p&gt; &lt;p&gt;最後に振り分けルールを設定します。振り分けルールとは、あるテーブルにレコードが挿入されるとき、どのテーブルにレコードが挿入されるかというルールです。チェック制約と同じ条件が設定される事になりますが、PostgreSQLにはチェック制約と振り分けルールが同じであるかを検証するすべがありません。慎重に同じ条件を設定する必要があります。&lt;/p&gt; &lt;p&gt; &lt;hr&gt; &lt;/p&gt; &lt;p&gt;create rule&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; rl_request_200807_1 as&lt;br&gt;on insert to&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; request&lt;br&gt;where&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ('2008-07-01' &amp;lt;= timestamp and timestamp &amp;lt; '2008-08-01')&lt;br&gt;do instead&lt;br&gt;insert into&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; request_200807&lt;br&gt;values(&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; new.request_id,&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; new.timestamp,&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; new.uri,&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; new.user_agent,&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; new.remote_host&lt;br&gt;);  &lt;p&gt;create rule&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; rl_parameter_200807_1 as&lt;br&gt;on insert to&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; parameter&lt;br&gt;where&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ('2008-07-01' &amp;lt;= timestamp and timestamp &amp;lt; '2008-08-01')&lt;br&gt;do instead&lt;br&gt;insert into&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; parameter_200807&lt;br&gt;values(&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; new.parameter_id,&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; new.request_id,&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; new.timestamp,&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; new.name,&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; new.value&lt;br&gt;); &lt;hr&gt;  &lt;p&gt;これでテーブルは以上です。次にサーバの設定で、constraint_exclusionをonにしておきましょう。レコードの検索条件にタイムスタンプが含まれる場合、関係のないテーブルは実行プランに含まれなくなります。&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;・・・と、非常に面倒なことになりますが、これはスクリプトを使って必要に応じて生成するのがオススメです。この構成を行った場合、通常のSQLはというと、request/parameterのテーブルに対して実行するだけでよくなります。年月のサフィックスが付いたテーブルを意識する必要はありません。&lt;/p&gt; &lt;p&gt;複数年月のテーブルを作成し、request/parameterに対してinsertを行ってから、以下のクエリを実行してみてください。キチンとテーブルがパーティショニングされていることが確認できると思います。&lt;/p&gt; &lt;p&gt; &lt;hr&gt; &lt;/p&gt; &lt;p&gt;select * from request;&lt;/p&gt; &lt;p&gt;select * from only request;&lt;/p&gt; &lt;p&gt;select * from request_200807;&lt;/p&gt; &lt;p&gt;select * from only request_200807;&lt;/p&gt; &lt;p&gt;select * from request_200808;&lt;/p&gt; &lt;p&gt;select * from only request_200808;&lt;/p&gt; &lt;p&gt; &lt;hr&gt; &lt;/p&gt; &lt;p&gt;で、最後に注意点になりますが、insertは年月付きの実テーブルへ行った方が早いです。ベンチマークしましたが、数倍は早いです。。。大量データのインサートは直接実テーブルを行うようにしましょう。&lt;/p&gt;&lt;img src ="http://blogs.wankuma.com/kacchan6/aggbug/147194.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>かつのり</dc:creator><title>AgitarのJUnitコード自動生成</title><link>http://blogs.wankuma.com/kacchan6/archive/2008/02/11/122624.aspx</link><pubDate>Mon, 11 Feb 2008 03:33:00 GMT</pubDate><guid>http://blogs.wankuma.com/kacchan6/archive/2008/02/11/122624.aspx</guid><wfw:comment>http://blogs.wankuma.com/kacchan6/comments/122624.aspx</wfw:comment><comments>http://blogs.wankuma.com/kacchan6/archive/2008/02/11/122624.aspx#Feedback</comments><slash:comments>34</slash:comments><wfw:commentRss>http://blogs.wankuma.com/kacchan6/comments/commentRss/122624.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/kacchan6/services/trackbacks/122624.aspx</trackback:ping><description>&lt;P&gt;Agitarというツールがあって、これはJUnitのコードを自動生成してくれたりするツールなんですが、これまたエラい高いツールだった記憶があります。しかし、いつの間にやらウェブサービス化しているみたいで、無料で扱えるみたいです。&lt;/P&gt;
&lt;P&gt;簡単に言うと、Agitarのサーバ上にアップしたクラスに対して、自動的にテストケースを作成してくれるみたいです。&lt;/P&gt;
&lt;P&gt;コードの中身を見て、より高いカバレッジでテストが必ず合格するテストケースを自動生成するので、元コードがバグっていたら、そのバグを正とするテストケースが生成されます。この辺は要注意です。&lt;/P&gt;
&lt;P&gt;詳しくはこちら。&lt;/P&gt;
&lt;P&gt;&lt;A href="http://www.atmarkit.co.jp/fjava/rensai3/eclipseplgn24/eclipseplgn24_1.html"&gt;http://www.atmarkit.co.jp/fjava/rensai3/eclipseplgn24/eclipseplgn24_1.html&lt;/A&gt;&lt;/P&gt;&lt;img src ="http://blogs.wankuma.com/kacchan6/aggbug/122624.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>かつのり</dc:creator><title>httpsとiframe</title><link>http://blogs.wankuma.com/kacchan6/archive/2008/02/07/121776.aspx</link><pubDate>Thu, 07 Feb 2008 00:15:00 GMT</pubDate><guid>http://blogs.wankuma.com/kacchan6/archive/2008/02/07/121776.aspx</guid><wfw:comment>http://blogs.wankuma.com/kacchan6/comments/121776.aspx</wfw:comment><comments>http://blogs.wankuma.com/kacchan6/archive/2008/02/07/121776.aspx#Feedback</comments><slash:comments>23</slash:comments><wfw:commentRss>http://blogs.wankuma.com/kacchan6/comments/commentRss/121776.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/kacchan6/services/trackbacks/121776.aspx</trackback:ping><description>&lt;P&gt;また同じ間違いをやってしまった・・・。&lt;/P&gt;
&lt;P&gt;IE6でhttpsのページを開くとたまに出る、「セキュリティ警告」。&lt;/P&gt;
&lt;DIV class=errormsg&gt;&lt;STRONG&gt;&lt;FONT size=2&gt;このページにはセキュリティで保護されている項目と保護されていない項目が含まれています。&lt;BR&gt;保護されていない項目を表示しますか?&lt;/FONT&gt;&lt;/STRONG&gt; &lt;/DIV&gt;
&lt;DIV class=errormsg&gt;&amp;nbsp;&lt;/DIV&gt;
&lt;P class=errormsg&gt;今作っているサイトでまたやってしまったんですが、原因はこれ。&lt;A href="http://support.microsoft.com/kb/261188/ja"&gt;http://support.microsoft.com/kb/261188/ja&lt;/A&gt;&lt;/P&gt;
&lt;P class=errormsg&gt;簡単にいうと、iframeタグにsrc属性を付け忘れると、この警告がでます。iframeタグのsrc属性を省略すると、なかのiframeのURLはabout:blankになります。aboutとhttps、スキーム名の違いで出てくるのでしょう。aboutは確かに非httpsです。&lt;/P&gt;
&lt;P class=errormsg&gt;&amp;nbsp;&lt;/P&gt;&lt;img src ="http://blogs.wankuma.com/kacchan6/aggbug/121776.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>かつのり</dc:creator><title>JTの餃子のパッケージを考えてみた。</title><link>http://blogs.wankuma.com/kacchan6/archive/2008/01/31/120254.aspx</link><pubDate>Thu, 31 Jan 2008 22:26:00 GMT</pubDate><guid>http://blogs.wankuma.com/kacchan6/archive/2008/01/31/120254.aspx</guid><wfw:comment>http://blogs.wankuma.com/kacchan6/comments/120254.aspx</wfw:comment><comments>http://blogs.wankuma.com/kacchan6/archive/2008/01/31/120254.aspx#Feedback</comments><slash:comments>39</slash:comments><wfw:commentRss>http://blogs.wankuma.com/kacchan6/comments/commentRss/120254.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/kacchan6/services/trackbacks/120254.aspx</trackback:ping><description>&lt;P&gt;なんだか事件で色々とかかわいそうなので、新しいパッケージを考えてみました。&lt;/P&gt;
&lt;P&gt;ここはやはりJT。JTらしさを取り入れてみました。&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;&lt;A href="http://kacchan6.wankuma.com/blog/images/JT_13B4A/100464091921.jpg"&gt;&lt;IMG style="BORDER-RIGHT: 0px; BORDER-TOP: 0px; BORDER-LEFT: 0px; BORDER-BOTTOM: 0px" height=604 alt=10046409192[1]のコピー src="http://kacchan6.wankuma.com/blog/images/JT_13B4A/100464091921_thumb.jpg" width=804 border=0&gt;&lt;/A&gt;&lt;/P&gt;&lt;img src ="http://blogs.wankuma.com/kacchan6/aggbug/120254.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>かつのり</dc:creator><title>久々にデッドロック＼(＾o＾)／</title><link>http://blogs.wankuma.com/kacchan6/archive/2008/01/31/120249.aspx</link><pubDate>Thu, 31 Jan 2008 21:38:00 GMT</pubDate><guid>http://blogs.wankuma.com/kacchan6/archive/2008/01/31/120249.aspx</guid><wfw:comment>http://blogs.wankuma.com/kacchan6/comments/120249.aspx</wfw:comment><comments>http://blogs.wankuma.com/kacchan6/archive/2008/01/31/120249.aspx#Feedback</comments><slash:comments>3</slash:comments><wfw:commentRss>http://blogs.wankuma.com/kacchan6/comments/commentRss/120249.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/kacchan6/services/trackbacks/120249.aspx</trackback:ping><description>&lt;P&gt;久々にデッドロックというものをやってしまいました。&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;トランザクション開始&lt;/LI&gt;
&lt;LI&gt;あるレコード更新&lt;/LI&gt;
&lt;LI&gt;外部のRESTのWEBサービス呼び出し⇒＼(＾o＾)／&lt;/LI&gt;
&lt;LI&gt;トランザクション終了&lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;という処理で、WEBサービス側は、&lt;/P&gt;
&lt;OL&gt;
&lt;LI&gt;呼ばれる&lt;/LI&gt;
&lt;LI&gt;こっち側のWEBサービスで対象レコード参照⇒＼(＾o＾)／&lt;/LI&gt;
&lt;LI&gt;処理完了&lt;/LI&gt;&lt;/OL&gt;
&lt;P&gt;という感じで、なんつーか絵に描いたようなデッドロックを経験しました。トランザクション内での外部リソースの呼び出しは要注意ですね。&lt;/P&gt;&lt;img src ="http://blogs.wankuma.com/kacchan6/aggbug/120249.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>かつのり</dc:creator><title>Attacking PHP</title><link>http://blogs.wankuma.com/kacchan6/archive/2008/01/30/119902.aspx</link><pubDate>Wed, 30 Jan 2008 00:23:00 GMT</pubDate><guid>http://blogs.wankuma.com/kacchan6/archive/2008/01/30/119902.aspx</guid><wfw:comment>http://blogs.wankuma.com/kacchan6/comments/119902.aspx</wfw:comment><comments>http://blogs.wankuma.com/kacchan6/archive/2008/01/30/119902.aspx#Feedback</comments><slash:comments>9</slash:comments><wfw:commentRss>http://blogs.wankuma.com/kacchan6/comments/commentRss/119902.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/kacchan6/services/trackbacks/119902.aspx</trackback:ping><description>&lt;P&gt;&lt;A href="http://mindblind.net/2008/01/24/attacking-php/"&gt;http://mindblind.net/2008/01/24/attacking-php/&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;&lt;A href="http://www.rubyist.net/~matz/20080126.html#p04"&gt;http://www.rubyist.net/~matz/20080126.html#p04&lt;/A&gt;&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;
&lt;P&gt;う～ん、PHPが叩かれています。PHPって言語としてはかなり微妙というかゆとり向けかなと思うんですが、テンプレートエンジンとしてはかなり賢いというか便利な方ですよ。&lt;/P&gt;
&lt;P&gt;でも手軽だし、初心者には最適じゃないでしょうか。初心者が学ぶには、Try&amp;amp;Errorをより短いサイクルで繰り返せる方が楽です。これって初心者に限らずベテランにも言えるでしょう。&lt;/P&gt;
&lt;P&gt;自分もほぼ静的なページを作るときにヘッダとフッタの共有やコピーライトの年の部分の動的化など、割と便利だなと思って使っています。&lt;/P&gt;
&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;img src ="http://blogs.wankuma.com/kacchan6/aggbug/119902.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>かつのり</dc:creator><title>JavaScriptでのクロージャの使い方</title><link>http://blogs.wankuma.com/kacchan6/archive/2008/01/28/119508.aspx</link><pubDate>Mon, 28 Jan 2008 01:15:00 GMT</pubDate><guid>http://blogs.wankuma.com/kacchan6/archive/2008/01/28/119508.aspx</guid><wfw:comment>http://blogs.wankuma.com/kacchan6/comments/119508.aspx</wfw:comment><comments>http://blogs.wankuma.com/kacchan6/archive/2008/01/28/119508.aspx#Feedback</comments><slash:comments>47</slash:comments><wfw:commentRss>http://blogs.wankuma.com/kacchan6/comments/commentRss/119508.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/kacchan6/services/trackbacks/119508.aspx</trackback:ping><description>&lt;p&gt;次はJavaScriptでのクロージャについてです。よく間違えやすいケースについて書いてみます。&lt;/p&gt; &lt;p&gt;まずは、シナリオを考えます。&lt;/p&gt; &lt;ul&gt; &lt;li&gt;ボタンが３つある  &lt;li&gt;1番目のボタンをクリックしたら１をアラートで表示  &lt;li&gt;2番目のボタンをクリックしたら2をアラートで表示  &lt;li&gt;3番目のボタンをクリックしたら3をアラートで表示&lt;/li&gt;&lt;/ul&gt; &lt;p&gt;これをコードにしてみましょう。まずはHTMLだけ。&lt;/p&gt; &lt;hr&gt; &lt;pre&gt;&amp;lt;html&amp;gt;
&amp;lt;head&amp;gt;
&amp;lt;script type="&lt;span style="color: #8b0000"&gt;text/javascript&lt;/span&gt;"&amp;gt;
&amp;lt;/script&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
&amp;lt;form name="&lt;span style="color: #8b0000"&gt;foo&lt;/span&gt;"&amp;gt;
&amp;lt;input type="&lt;span style="color: #8b0000"&gt;button&lt;/span&gt;" id="&lt;span style="color: #8b0000"&gt;button1&lt;/span&gt;" &lt;span style="color: #0000ff"&gt;value&lt;/span&gt;="&lt;span style="color: #8b0000"&gt;1&lt;/span&gt;"&amp;gt;
&amp;lt;input type="&lt;span style="color: #8b0000"&gt;button&lt;/span&gt;" id="&lt;span style="color: #8b0000"&gt;button2&lt;/span&gt;" &lt;span style="color: #0000ff"&gt;value&lt;/span&gt;="&lt;span style="color: #8b0000"&gt;2&lt;/span&gt;"&amp;gt;
&amp;lt;input type="&lt;span style="color: #8b0000"&gt;button&lt;/span&gt;" id="&lt;span style="color: #8b0000"&gt;button3&lt;/span&gt;" &lt;span style="color: #0000ff"&gt;value&lt;/span&gt;="&lt;span style="color: #8b0000"&gt;3&lt;/span&gt;"&amp;gt;
&amp;lt;/form&amp;gt;
&amp;lt;/body&amp;gt;&lt;/pre&gt;
&lt;hr&gt;
 
&lt;p&gt;次にScriptタグの中身を書いて見ましょう。&lt;/p&gt;
&lt;hr&gt;
 &lt;pre&gt;function button1Click(){
	alert(1);
}

function button2Click(){
	alert(2);
}

function button3Click(){
	alert(3);
}
&lt;/pre&gt;&lt;pre&gt;//前提として、bodyタグにonload="windowOnload()"が記述済みとする
function windowOnload(){
	var button1 = document.getElementById("&lt;span style="color: #8b0000"&gt;button1&lt;/span&gt;");
	button1.onclick = button1Click;
	var button2 = document.getElementById("&lt;span style="color: #8b0000"&gt;button2&lt;/span&gt;");
	button2.onclick = button2Click;
	var button3 = document.getElementById("&lt;span style="color: #8b0000"&gt;button3&lt;/span&gt;");
	button3.onclick = button3Click;
}&lt;/pre&gt;
&lt;hr&gt;
 
&lt;p&gt;これは取り合えず非常に冗長ですが、オーソドックスな書き方です。ではこれをクロージャで書いてみましょう。&lt;/p&gt; 
&lt;hr&gt;
 &lt;pre&gt;window.onload = function(){
	document.getElementById("&lt;span style="color: #8b0000"&gt;button1&lt;/span&gt;").onclick = function(){
		alert(1);
	};
	document.getElementById("&lt;span style="color: #8b0000"&gt;button2&lt;/span&gt;").onclick = function(){
		alert(2);
	};
	document.getElementById("&lt;span style="color: #8b0000"&gt;button3&lt;/span&gt;").onclick = function(){
		alert(3);
	};
};&lt;/pre&gt;
&lt;p&gt;
&lt;hr&gt;
&lt;/p&gt;
&lt;p&gt; &lt;font face="Courier New"&gt;少しシンプルになりました。色々なライブラリとのコンフリクションがあったりするので、最近のJavaScriptの主流の書き方では、極力グローバルの変数や関数を使いません。&lt;/font&gt;&lt;/p&gt;
&lt;p&gt;&lt;font face="Courier New"&gt;ただこれでもまだ冗長なので、普通に以下のようなコードを書かれると思います。&lt;/font&gt;&lt;/p&gt;
&lt;hr&gt;
 &lt;pre&gt;window.onload = function(){
	&lt;span style="color: #0000ff"&gt;for&lt;/span&gt;(var i = 1; i &amp;lt;= 3; i++){
		var button = document.getElementById("&lt;span style="color: #8b0000"&gt;button&lt;/span&gt;" + i);
		button.onclick = function(){
			alert(i);
		};
	}
};&lt;/pre&gt;
&lt;hr&gt;

&lt;p&gt;これを実行すると分かると思いますが、どのボタンをクリックしても4が表示されます。ループの中のクロージャはループカウンタの変数iに対する参照を持ちますが、最後に評価された結果の4が全てのクロージャから参照されてしまうのです。&lt;/p&gt;
&lt;p&gt;では、上記コードに手を入れて正しく動くようにしてみます。&lt;/p&gt;
&lt;hr&gt;
 &lt;pre&gt;window.onload = function(){
	&lt;span style="color: #0000ff"&gt;for&lt;/span&gt;(var i = 1; i &amp;lt;= 3; i++){
		var button = document.getElementById("&lt;span style="color: #8b0000"&gt;button&lt;/span&gt;" + i);
		&lt;span style="color: #008000"&gt;//もう一つ関数で囲む&lt;/span&gt;
		(function(n){
			button.onclick = function(){
				alert(n);
			};
		&lt;span style="color: #008000"&gt;//iを渡す&lt;/span&gt;
		})(i);
	}
};&lt;/pre&gt;
&lt;p&gt;
&lt;hr&gt;
 匿名関数にiを都度渡していますが、これによってiを参照しなくなります。関数に渡された仮引数を都度参照するので、この場合正しく動きます。&lt;/p&gt;
&lt;p&gt;では最後に効率化を行いましょう。関数リテラルはキャッシュされず、インタプリタによってそのステートメントが評価されるたびに新しい関数オブジェクトが作られます。すなわち"(function(n){"で始まる関数のオブジェクトは都度つくられるのです。&lt;/p&gt;
&lt;p&gt;
&lt;hr&gt;
&lt;/p&gt;&lt;pre&gt;window.onload = function(){
	var click = function(n, button){
		button.onclick = function(){
			alert(n);
		};
	};
	&lt;span style="color: #0000ff"&gt;for&lt;/span&gt;(var i = 1; i &amp;lt;= 3; i++){
		var button = document.getElementById("&lt;span style="color: #8b0000"&gt;button&lt;/span&gt;" + i);
		click(i, button);
	}
};&lt;/pre&gt;
&lt;p&gt;
&lt;hr&gt;
&lt;/p&gt;
&lt;p&gt;関数は都度作られるというのは、以下のコードで確認できます。&lt;/p&gt;
&lt;p&gt;
&lt;hr&gt;
&lt;/p&gt;
&lt;p&gt;var list = []; 
&lt;p&gt;for(var i = 0; i &amp;lt; 3; i++){&lt;br&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; list.push(function(){});&lt;br&gt;} 
&lt;p&gt;alert(list[0] == list[1]);&lt;br&gt;alert(list[1] == list[2]);&lt;br&gt;alert(list[0] == list[2]);
&lt;p&gt;
&lt;hr&gt;
&lt;/p&gt;
&lt;p&gt;上記は全てfalseになります。 &lt;/p&gt;&lt;img src ="http://blogs.wankuma.com/kacchan6/aggbug/119508.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>かつのり</dc:creator><title>Javaでクロージャ</title><link>http://blogs.wankuma.com/kacchan6/archive/2008/01/27/119480.aspx</link><pubDate>Sun, 27 Jan 2008 21:07:00 GMT</pubDate><guid>http://blogs.wankuma.com/kacchan6/archive/2008/01/27/119480.aspx</guid><wfw:comment>http://blogs.wankuma.com/kacchan6/comments/119480.aspx</wfw:comment><comments>http://blogs.wankuma.com/kacchan6/archive/2008/01/27/119480.aspx#Feedback</comments><slash:comments>139</slash:comments><wfw:commentRss>http://blogs.wankuma.com/kacchan6/comments/commentRss/119480.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/kacchan6/services/trackbacks/119480.aspx</trackback:ping><description>&lt;p&gt;Java7からはクロージャが利用できる予定みたいですが、コンパイラの実装も出てきました。&lt;/p&gt;&lt;a title="http://javac.info/jsr166z.ztar" href="http://javac.info/jsr166z.ztar"&gt;http://javac.info/jsr166z.ztar&lt;/a&gt; &lt;p&gt;まとまった資料は此方です。&lt;/p&gt; &lt;p&gt;&lt;a title="http://gafter.blogspot.com/2007/01/definition-of-closures.html" href="http://gafter.blogspot.com/2007/01/definition-of-closures.html"&gt;http://gafter.blogspot.com/2007/01/definition-of-closures.html&lt;/a&gt;&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;どんな感じで書けるかというと、&lt;/p&gt; &lt;div style="border-right: #000000 1px solid; padding-right: 3px; border-top: #000000 1px solid; padding-left: 3px; padding-bottom: 3px; border-left: #000000 1px solid; padding-top: 3px; border-bottom: #000000 1px solid"&gt;&lt;pre&gt;{&lt;span style="color: #0000ff"&gt;int&lt;/span&gt;, &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; =&amp;gt; &lt;span style="color: #0000ff"&gt;int&lt;/span&gt;} plus = {&lt;span style="color: #0000ff"&gt;int&lt;/span&gt; x, &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; y =&amp;gt; x + y};
&lt;span style="color: #0000ff"&gt;int&lt;/span&gt; result = plus.invoke(1, 2);&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;というような感じでかけます。なんとなくイメージはつかめますよね。これは、&lt;/p&gt;
&lt;div style="border-right: #000000 1px solid; padding-right: 3px; border-top: #000000 1px solid; padding-left: 3px; padding-bottom: 3px; border-left: #000000 1px solid; padding-top: 3px; border-bottom: #000000 1px solid"&gt;&lt;pre&gt;&lt;span style="color: #0000ff"&gt;interface&lt;/span&gt; I{
    &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; invoke(&lt;span style="color: #0000ff"&gt;int&lt;/span&gt; n, &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; m);
}

I plus = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; I(){
    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; invoke(&lt;span style="color: #0000ff"&gt;int&lt;/span&gt; n, &lt;span style="color: #0000ff"&gt;int&lt;/span&gt; m){
        &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; n + m;
    }
};
&lt;span style="color: #0000ff"&gt;int&lt;/span&gt; result = plus.invoke(1, 2);&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;というような感じに置き換えられます。内部でインターフェイスが作られます。仮引数として受け取るパターンはこちらです。ちなみに型パラメータもOKです。&lt;/p&gt;
&lt;div style="border-right: #000000 1px solid; padding-right: 3px; border-top: #000000 1px solid; padding-left: 3px; padding-bottom: 3px; border-left: #000000 1px solid; padding-top: 3px; border-bottom: #000000 1px solid"&gt;&lt;pre&gt;&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;static&lt;/span&gt; &amp;lt;T&amp;gt; List&amp;lt;T&amp;gt; select(List&amp;lt;T&amp;gt; list, {T =&amp;gt; &lt;span style="color: #0000ff"&gt;boolean&lt;/span&gt;} filter){
    List&amp;lt;T&amp;gt; result = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; ArrayList&amp;lt;T&amp;gt;();
    &lt;span style="color: #0000ff"&gt;for&lt;/span&gt;(T t : list){
        &lt;span style="color: #0000ff"&gt;if&lt;/span&gt;(filter.invoke(t)){
            result.add(t);
        }
    }

    &lt;span style="color: #0000ff"&gt;return&lt;/span&gt; result;
}

&lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; test(){
    List&amp;lt;Integer&amp;gt; list = &lt;span style="color: #0000ff"&gt;new&lt;/span&gt; ArrayList&amp;lt;Integer&amp;gt;();
    list.add(1);
    list.add(2);
    list.add(3);
    list.add(4);
    list.add(5);

    list = select(list, {&lt;span style="color: #0000ff"&gt;Integer&lt;/span&gt; n =&amp;gt; n % 2 == 0});
    &lt;span style="color: #008000"&gt;//list = [2,4]&lt;/span&gt;
}&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;既存のメソッドが1つだけのインターフェイスもクロージャとして使えます。例えば以下のような構文でスレッドを作成できます。&lt;/p&gt;
&lt;div style="border-right: #000000 1px solid; padding-right: 3px; border-top: #000000 1px solid; padding-left: 3px; padding-bottom: 3px; border-left: #000000 1px solid; padding-top: 3px; border-bottom: #000000 1px solid"&gt;&lt;pre&gt;&lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Thread({=&amp;gt;
    system.out.println(123);
}).start();&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;これは、&lt;/p&gt;
&lt;div style="border-right: #000000 1px solid; padding-right: 3px; border-top: #000000 1px solid; padding-left: 3px; padding-bottom: 3px; border-left: #000000 1px solid; padding-top: 3px; border-bottom: #000000 1px solid"&gt;&lt;pre&gt;&lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Thread(&lt;span style="color: #0000ff"&gt;new&lt;/span&gt; Runnable(){
    &lt;span style="color: #0000ff"&gt;public&lt;/span&gt; &lt;span style="color: #0000ff"&gt;void&lt;/span&gt; run(){
        System.out.println(123);
    }
}).start();&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;に置換え可能です。&lt;/p&gt;
&lt;p&gt;&amp;nbsp;&lt;/p&gt;
&lt;p&gt;これからローカル変数や例外の扱いについても調べてみようと思いますが、雰囲気的には、&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;匿名クラスのシンタックスシュガー&lt;/li&gt;
&lt;li&gt;メソッドが１つのインターフェイスの定義のシンタックスシュガー&lt;/li&gt;&lt;/ul&gt;
&lt;p&gt;という感じがします。また色々書いていこうと思います。&lt;/p&gt;&lt;img src ="http://blogs.wankuma.com/kacchan6/aggbug/119480.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>かつのり</dc:creator><title>勉強会お疲れ様でした～</title><link>http://blogs.wankuma.com/kacchan6/archive/2008/01/27/119476.aspx</link><pubDate>Sun, 27 Jan 2008 20:36:00 GMT</pubDate><guid>http://blogs.wankuma.com/kacchan6/archive/2008/01/27/119476.aspx</guid><wfw:comment>http://blogs.wankuma.com/kacchan6/comments/119476.aspx</wfw:comment><comments>http://blogs.wankuma.com/kacchan6/archive/2008/01/27/119476.aspx#Feedback</comments><slash:comments>1</slash:comments><wfw:commentRss>http://blogs.wankuma.com/kacchan6/comments/commentRss/119476.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/kacchan6/services/trackbacks/119476.aspx</trackback:ping><description>&lt;p&gt;勉強会お疲れ様でした。初めての勉強会でいきなり色々しゃべらせてもらいましたが、すごい緊張でした・・・。&lt;/p&gt; &lt;p&gt;ライブプログラミングは面白かったですね。Eclipseのコンソールに入力値が出力されていたのは単なる偶然なんですが、それがニコニコ動画っぽくて間が持った感じでした。参加型のセッションって面白いですね。ニコニコ風に突っ込みを入れれるプレゼンツールを作りたいなと思いました。&lt;/p&gt; &lt;p&gt;それなりに厳しい意見もあったのですが、もうちょっと今度はキチンと段取りしてからやろうと思います。&lt;/p&gt; &lt;p&gt;&amp;nbsp;&lt;/p&gt; &lt;p&gt;それと、みなさんに始めてお会いできたのですが、ネットで活動してからの念願でした。これからもよろしくお願いします。&lt;/p&gt;&lt;img src ="http://blogs.wankuma.com/kacchan6/aggbug/119476.aspx" width = "1" height = "1" /&gt;</description></item><item><dc:creator>かつのり</dc:creator><title>明日は（もう今日か・・）わんくま勉強会</title><link>http://blogs.wankuma.com/kacchan6/archive/2008/01/26/119354.aspx</link><pubDate>Sat, 26 Jan 2008 01:15:00 GMT</pubDate><guid>http://blogs.wankuma.com/kacchan6/archive/2008/01/26/119354.aspx</guid><wfw:comment>http://blogs.wankuma.com/kacchan6/comments/119354.aspx</wfw:comment><comments>http://blogs.wankuma.com/kacchan6/archive/2008/01/26/119354.aspx#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://blogs.wankuma.com/kacchan6/comments/commentRss/119354.aspx</wfw:commentRss><trackback:ping>http://blogs.wankuma.com/kacchan6/services/trackbacks/119354.aspx</trackback:ping><description>&lt;P&gt;またまた久々の更新。最近仕事が忙しくて、死にそうなかつのりです。&lt;/P&gt;
&lt;P&gt;皆さんにお会いするのも初なのに、いきなりトークとは・・・。いまから緊張しています。初回なのでムードもよくわかりませんし、とりあえずリードは凪瀬さんにお任せします。&lt;/P&gt;
&lt;P&gt;しゃべりが得意ではないので、聞き苦しいかもしれませんが、よろしくお願いします。&lt;/P&gt;&lt;img src ="http://blogs.wankuma.com/kacchan6/aggbug/119354.aspx" width = "1" height = "1" /&gt;</description></item></channel></rss>