<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>masakazu&#039;s Weblog</title>
	<atom:link href="http://bougaidenpa.org/masakazu/feed" rel="self" type="application/rss+xml" />
	<link>http://bougaidenpa.org/masakazu</link>
	<description></description>
	<lastBuildDate>Sat, 24 Jul 2010 16:40:58 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>FreeBSD で 6rd 環境を構築しよう</title>
		<link>http://bougaidenpa.org/masakazu/archives/54</link>
		<comments>http://bougaidenpa.org/masakazu/archives/54#comments</comments>
		<pubDate>Fri, 29 Jan 2010 17:29:52 +0000</pubDate>
		<dc:creator>masakazu</dc:creator>
				<category><![CDATA[Network]]></category>

		<guid isPermaLink="false">http://bougaidenpa.org/masakazu/?p=54</guid>
		<description><![CDATA[<p>前から 6rd のことは気になっていて、そろそろ Open Source で実装でないかなぁ、なんて思いながらもいっこうにでてきそうな気配もなく、こないだ JANOG25 で平井さんと松嶋さんが発表されてた “既存ユーザへのIPv6 提供と実装を考えてみる” を聞いたらやっぱり面白そうで、ここはひとつ FreeBSD に実装してみようか、ということで実装してみました。といってもすでに存在している 6to4 のインターフェース if_stf.c を改造しただけですけど。</p>

BR と CE 両方いけます。
FreeBSD 8 用です。
利用にあたっては自己責任で。

<p>6rd の詳細は “I-D. IPv6 via IPv4 Service Provider Networks &#8220;6rd&#8221;” を参照。</p>
概要
<p>とりあえずこんな感じを例に説明します。</p>
<p></p>
<p>4 つの 6rd elements はそれぞれ以下の通りとします。</p>



 IPv4PrefixLen
20


 6rdPrefix
fc00:0:0:1000::


 6rdPrefixLen
52


 6rdBRIPv4Address
10.0.0.1



<p>6rdPrefixLen + (32 &#8211; IPv4PrefixLen) = 64 なので CE は fc00:0:0:1xxx::/64 をもらうことになります。 xxx の部分には IPv4 アドレスの下位 12 [...]]]></description>
			<content:encoded><![CDATA[<p>前から 6rd のことは気になっていて、そろそろ Open Source で実装でないかなぁ、なんて思いながらもいっこうにでてきそうな気配もなく、こないだ JANOG25 で平井さんと松嶋さんが発表されてた <a href="http://www.janog.gr.jp/meeting/janog25/program/v6deploy.html">“既存ユーザへのIPv6 提供と実装を考えてみる”</a> を聞いたらやっぱり面白そうで、ここはひとつ FreeBSD に実装してみようか、ということで実装してみました。といってもすでに存在している 6to4 のインターフェース if_stf.c を改造しただけですけど。</p>
<ol>
<li>BR と CE 両方いけます。</li>
<li>FreeBSD 8 用です。</li>
<li>利用にあたっては自己責任で。</li>
</ol>
<p>6rd の詳細は <a href="http://tools.ietf.org/html/draft-ietf-softwire-ipv6-6rd">“I-D. IPv6 via IPv4 Service Provider Networks &#8220;6rd&#8221;”</a> を参照。</p>
<h2>概要</h2>
<p>とりあえずこんな感じを例に説明します。</p>
<p><img class="aligncenter size-full wp-image-72" title="6rdfig" src="http://bougaidenpa.org/masakazu/wp-content/uploads/2010/01/6rdfig1.png" alt="6rdfig" width="486" height="327" /></p>
<p>4 つの 6rd elements はそれぞれ以下の通りとします。</p>
<table border="0">
<tbody>
<tr>
<th> IPv4PrefixLen</th>
<td>20</td>
</tr>
<tr>
<th> 6rdPrefix</th>
<td>fc00:0:0:1000::</td>
</tr>
<tr>
<th> 6rdPrefixLen</th>
<td>52</td>
</tr>
<tr>
<th> 6rdBRIPv4Address</th>
<td>10.0.0.1</td>
</tr>
</tbody>
</table>
<p>6rdPrefixLen + (32 &#8211; IPv4PrefixLen) = 64 なので CE は fc00:0:0:1xxx::/64 をもらうことになります。 xxx の部分には IPv4 アドレスの下位 12 ビット(32 &#8211; IPv4PrefixLen)が埋まります。</p>
<h2>準備</h2>
<p>とりあえず上の図で 10.0.0.1/24 が振られている BR と 10.0.0.2/24 が振られている CE の設定方法を書きます。 10.0.0.3/24 の設定はほとんど 10.0.0.2/24 と同じです。違いは多分推測がつくと思います。</p>
<p>まずは <a href="http://bougaidenpa.org/masakazu/wp-content/uploads/2010/01/freebsd8-6rd-20100130.patch.gz">パッチ</a> を適用します。</p>
<pre># cd ~
# wget http://bougaidenpa.org/masakazu/wp-content/uploads/2010/01/freebsd8-6rd-20100130.patch.gz
# gzip -d freebsd8-6rd-20100130.patch.gz
# cd /usr
# patch -p0 &lt; ~/freebsd8-6rd-20100130.patch</pre>
<p>ifconfig のコンパイルのために if_srd.h が必要になるのでコピーします。</p>
<pre># cp /usr/src/sys/net/if_srd.h /usr/include/net/</pre>
<p>ifconfig をコンパイルしてインストールします。</p>
<pre># cd /usr/src/sbin/ifconfig
# make
# make install</pre>
<p>if_srd.ko をコンパイルしてインストールします。</p>
<pre># cd /usr/src/sys/modules/if_srd
# make
# make install</pre>
<p>/etc/rc.conf にそれぞれ以下のような記述をして再起動します。</p>
<pre># BR の rc.conf
keymap="jp.106"
ipv6_enable="YES"
gateway_enable="YES"
ipv6_gateway_enable="YES"
cloned_interfaces="srd0"
ifconfig_em0="inet 10.0.0.1 netmask 255.255.255.0"
ifconfig_srd0="v4plen 20 pfix fc00:0:0:1000:: plen 52 braddr 10.0.0.1"
ipv6_ifconfig_em1="fc00:1:0:1001::1 prefixlen 64"
ipv6_ifconfig_srd0="fc00:0:0:1001:: prefixlen 128"
ipv6_static_routes="xxx"
ipv6_route_xxx="fc00:0:0:1000:: -prefixlen 52 ::1 -ifp srd0"</pre>
<pre># CE の rc.conf
keymap="jp.106"
ipv6_enable="YES"
gateway_enable="YES"
ipv6_gateway_enable="YES"
cloned_interfaces="srd0"
ifconfig_le0="inet 10.0.0.2 netmask 255.255.255.0"
ifconfig_srd0="v4plen 20 pfix fc00:0:0:1000:: plen 52 braddr 10.0.0.1"
ipv6_ifconfig_le1="fc00:0:0:1002::1 prefixlen 64"
ipv6_ifconfig_srd0="fc00:0:0:1002:: prefixlen 128"
ipv6_defaultrouter="::1 -ifp srd0"</pre>
<p>BR の em1 側に fc00:1:0:1001::/64 の端末を、 CE の le1 側に fc00:0:0:1002::/64 の端末をそれぞれ接続し、端末間で通信可能か確認します。</p>
<h2>説明</h2>
<p>4 つの 6rd elements を srd_softc のなかに入れてます。</p>
<pre>struct srd_softc {
        struct ifnet    *sc_ifp;
        union {
                struct route  __sc_ro4;
                struct route_in6 __sc_ro6; /* just for safety */
        } __sc_ro46;
#define sc_ro   __sc_ro46.__sc_ro4
        struct mtx      sc_ro_mtx;
        u_int   sc_fibnum;
        const struct encaptab *encap_cookie;
        /* 6rd elements */
        u_int           sc_srd_v4plen;
        struct in6_addr sc_srd_pfix;
        u_int           sc_srd_plen;
        struct in_addr  sc_srd_braddr;
        /* 6rd calculated variables */
        struct in_addr  sc_srd_v4pmask;
        struct in6_addr sc_srd_pmask;
        struct in6_addr sc_srd_dpmask;
};</pre>
<p>これらの値は ifconfig コマンドで参照したり設定したりできます。</p>
<pre># ifconfig srd0 create
# ifconfig srd0
srd0: flags=0&lt;&gt; metric 0 mtu 1280
	srd: v4plen 0 pfix :: plen 0 braddr 0.0.0.0
# ifconfig srd0 up
# ifconfig srd0 v4plen 20 pfix fc00:0:0:1000:: plen 52 braddr 10.0.0.1
# ifconfig srd0
srd0: flags=1&lt;UP&gt; metric 0 mtu 1280
	srd: v4plen 20 pfix fc00:0:0:1000:: plen 52 braddr 10.0.0.1</pre>
<p>srd の設定をしたら適当にルーティングの設定をします。srd にルーティングをさせるためにはなにか IPv6 アドレスが振られていなければならないようなので適当なアドレスを振っておきます。</p>
<pre># BR の場合
# ifconfig srd0 inet6 fc00:0:0:1001:: prefixlen 128
# route add -inet6 fc00:0:0:1000:: -prefixlen 52 ::1 -ifp srd0</pre>
<pre># CE の場合
# ifconfig srd0 inet6 fc00:0:0:1002:: prefixlen 128
# route add -inet6 default ::1 -ifp srd0</pre>
<p>IPv4 アドレスの一部をもとに IPv6 プレフィクスが求まるので、実際のところは CE の LAN 側アドレスの設定は結構めんどくさくなると思います。ほとんどの場合で IPv4 アドレスは動的でしょうから。</p>
<p>あと、</p>
<blockquote><p>Since 6rd delegated prefixes are selected algorithmically from an<br />
IPv4 address, changing the IPv4 address will cause a change in the<br />
IPv6 delegated prefix which would ripple through the site&#8217;s network<br />
and could be disruptive.  As such, the service provider should assign<br />
CE IPv4 addresses with relatively long lifetimes.</p></blockquote>
<p>なんて書かれていたりしますが、もしそんな状況になったお客さんから問い合わせがあったとしても「ルーターとパソコンを全部再起動してください。」くらいしか対応できないかも。そんな状況でも IPv4 は影響受けないと思うのでよけいたちが悪いような気もします。どうなんでしょうね。</p>
]]></content:encoded>
			<wfw:commentRss>http://bougaidenpa.org/masakazu/archives/54/feed</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Catalyst::Manual::Tutorial:: CatalystBasics &#8211; Catalyst Tutorial &#8211; Part 2: Catalyst Application Development Basics [対訳]</title>
		<link>http://bougaidenpa.org/masakazu/archives/35</link>
		<comments>http://bougaidenpa.org/masakazu/archives/35#comments</comments>
		<pubDate>Fri, 18 Apr 2008 17:41:35 +0000</pubDate>
		<dc:creator>masakazu</dc:creator>
				<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://bougaidenpa.org/masakazu/?p=35</guid>
		<description><![CDATA[<p>Catalyst::Manual::Tutorial::CatalystBasics &#8211; Catalyst Tutorial &#8211; Part 2: Catalyst Application Development Basics の対訳。2008/01/18 時点での最新版 Catalyst-Manual-5.701003.tar.gz を元にしています。</p>
<p>書きかけなんだけど興味がなくなり更新見込みがなくなったので公開。</p>
<p>誤訳がありましたらコメントにてご指摘ください。</p>
NAME</p>
<p>名前
<p>Catalyst::Manual::Tutorial::CatalystBasics &#8211; Catalyst Tutorial &#8211; Part 2: Catalyst Application Development Basics</p>
<p>Catalyst::Manual::Tutorial::CatalystBasics &#8211; Catalyst チュートリアル &#8211; 第二部: Catalyst アプリケーション開発の基礎</p>
OVERVIEW</p>
<p>概要
<p>This is Part 2 of 9 for the Catalyst tutorial.</p>
<p>9 つある Catalyst チュートリアルのうちの 2 つめです。</p>
<p>Tutorial Overview</p>
<p> </p>
<p>チュートリアルの概要</p>

Introduction
導入
Catalyst Basics
Catalyst の基礎
Basic CRUD
基礎的な CRUD
Authentication
認証
Authorization
承認
Debugging
デバッグ
Testing
テスト
Advanced CRUD
高度な CRUD
Appendices
補遺

DESCRIPTION</p>
<p>説明
<p>In this part [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://search.cpan.org/~jrockway/Catalyst-Manual-5.701003/lib/Catalyst/Manual/Tutorial/CatalystBasics.pod">Catalyst::Manual::Tutorial::CatalystBasics &#8211; Catalyst Tutorial &#8211; Part 2: Catalyst Application Development Basics</a> の対訳。2008/01/18 時点での最新版 Catalyst-Manual-5.701003.tar.gz を元にしています。</p>
<p>書きかけなんだけど興味がなくなり更新見込みがなくなったので公開。</p>
<p>誤訳がありましたらコメントにてご指摘ください。</p>
<div class="myh">NAME</p>
<p><span class="trans">名前</span></div>
<p>Catalyst::Manual::Tutorial::CatalystBasics &#8211; Catalyst Tutorial &#8211; Part 2: Catalyst Application Development Basics</p>
<p><span class="trans">Catalyst::Manual::Tutorial::CatalystBasics &#8211; Catalyst チュートリアル &#8211; 第二部: Catalyst アプリケーション開発の基礎</span></p>
<div class="myh">OVERVIEW</p>
<p><span class="trans">概要</span></div>
<p>This is Part 2 of 9 for the Catalyst tutorial.</p>
<p><span class="trans">9 つある Catalyst チュートリアルのうちの 2 つめです。</span></p>
<p><a href="http://bougaidenpa.org/masakazu/entry/catalyst_manual_tutorial">Tutorial Overview</a></p>
<p><a href="http://bougaidenpa.org/masakazu/entry/catalyst_manual_tutorial"> </a></p>
<p><a href="http://bougaidenpa.org/masakazu/entry/catalyst_manual_tutorial"><span class="trans">チュートリアルの概要</span></a></p>
<ol>
<li><a href="http://bougaidenpa.org/masakazu/entry/catalyst_manual_tutorial_intro">Introduction<br />
<span class="trans">導入</span></a></li>
<li>Catalyst Basics<br />
<span class="trans">Catalyst の基礎</span></li>
<li><a>Basic CRUD<br />
<span class="trans">基礎的な CRUD</span></a></li>
<li><a>Authentication<br />
<span class="trans">認証</span></a></li>
<li><a>Authorization<br />
<span class="trans">承認</span></a></li>
<li><a>Debugging<br />
<span class="trans">デバッグ</span></a></li>
<li><a>Testing<br />
<span class="trans">テスト</span></a></li>
<li><a>Advanced CRUD<br />
<span class="trans">高度な CRUD</span></a></li>
<li><a>Appendices<br />
<span class="trans">補遺</span></a></li>
</ol>
<div class="myh">DESCRIPTION</p>
<p><span class="trans">説明</span></div>
<p>In this part of the tutorial, we will create a very basic Catalyst web application. Though simple in many respects, this section will already demonstrate a number of powerful capabilities such as:</p>
<p><span class="trans">このパートでは、とても基本的な Catalyst Web アプリケーションを作ります。シンプルな多くの側面を通して、次のようないくつかのパワフルな能力をデモします:</span></p>
<ul>
<li>Helper Scripts<span class="trans">ヘルパスクリプト</span>
<p>Catalyst helper scripts that can be used to rapidly bootstrap the skeletal structure of an application.</p>
<p><span class="trans">Catalyst ヘルパスクリプトはアプリケーションのひな形構造を素早く立ち上げるために利用されます。</span></li>
<li>MVC<span class="trans">MVC</span>
<p>Model/View/Controller (MVC) provides an architecture that facilitates a clean &#8220;separation of control&#8221; between the different portions of your application. Given that many other documents cover this subject in detail, MVC will not be discussed in depth here (for an excellent introduction to MVC and general Catalyst concepts, please see Catalyst::Manual::About. In short:</p>
<p><span class="trans">モデル/ビュー/コントローラ(MVC) はアプリケーションの異なる部品間で容易にクリーンな “制御の分離” を行えるようにするためのアーキテクチャです。この件つついては詳細に説明する文書が多くあるので、ここではこれ以上深く掘り下げません(MVC と一般的な Catalyst のコンセプトについてのすばらしい導入については Catalyst::Manual::Abount を参照してください)。簡単に説明すると:</span></p>
<ul>
<li>Model<span class="trans">モデル</span>
<p>The model usually represents a data store. In most applications, the model equates to the objects that are created from and saved to your SQL database.</p>
<p><span class="trans">モデルはたいていデータストアを表現します。多くのアプリケーションでは、モデルは SQL データベースに作られ、保存されるオブジェクトと同じです。</span></li>
<li>View<span class="trans">ビュー</span>
<p>The view takes model objects and renders them into something for the end user to look at. Normally this involves a template-generation tool that creates HTML for the user&#8217;s web browser, but it could easily be code that generates other forms such as PDF documents, e-mails, or Excel spreadsheets.</p>
<p><span class="trans">ビューはモデルオブジェクトを得てそれらをエンドユーザに見えるよう描画します。通常ユーザの Web ブラウザのための HTML を生成するテンプレート生成ツールを含みますが、それ以外のフォーム例えば PDF ドキュメントや e-mail や Excel シートなどの場合もあります。</span></li>
<li>Controller<span class="trans"> </span>
<p>As suggested by its name, the controller takes user requests and routes them to the necessary model and view.</p>
<p><span class="trans">名前の通り、コントローラはユーザのリクエストを得て必要なモデルとビユーへ送ります。</span></li>
</ul>
</li>
<li>ORM<span class="trans">ORM</span>
<p>The use of Object-Relational Mapping (ORM) technology for database access. Specifically, ORM provides an automated and standardized means to persist and restore objects to/from a relational database.</p>
<p><span class="trans">データベースへのアクセスにオブジェクト-リレーショナルマッピング(ORM)技術を用います。特に、 ORM はオブジェクトをリレーショナルデータベースへ書き込んだり読み出したりするための自動的で標準かされた方法を提供します。</span></li>
</ul>
<p>You can checkout the source code for this example from the catalyst subversion repository as per the instructions in Catalyst::Manual::Tutorial::Intro.</p>
<p><span class="trans">この例のソースコードを Catalyst Subversion リポジトリから Catalyst::Manual::Tutorial::Intro にある手順でチェックアウトできます。</span></p>
<div class="myh">CREATE A CATALYST PROJECT</p>
<p><span class="trans">Catalyst プロジェクトを作る</span></div>
<p>Catalyst provides a number of helper scripts that can be used to quickly flesh out the basic structure of your application. All Catalyst projects begin with the catalyst.pl helper (see Catalyst::Helper for more information on helpers). Also note that as of Catalyst 5.7000, you will not have the helper scripts unless you install both Catalyst::Runtime and Catalyst::Devel.</p>
<p><span class="trans">Catalyst にはアプリケーションの基本的な構造を素早く具体化するためのヘルパスクリプトがいくつか提供されています。すべての Catalyst プロジェクトは catalyst.pl ヘルパからはじまります(ヘルパに関する詳細な情報は Catalyst::Helper を参照してください)。Catalyst 5.7000 では Catalyst::Runtime と Catalyst::Devel の両方がインストールされていないとヘルパスクリプトを利用できないので注意してください。</span></p>
<p>In the case of this tutorial, use the Catalyst catalyst.pl script to initialize the framework for an application called MyApp:</p>
<p><span class="trans">このチュートリアルでは、 MyAppと呼ばれるアプリケーションのフレームワークを初期化するため catalyst.pl というスクリプトを用います:</span></p>
<pre class="console">$ catalyst.pl MyApp
created "MyApp"
created "MyApp/script"
created "MyApp/lib"
created "MyApp/root"
...
created "MyApp/script/myapp_create.pl"
$ cd MyApp</pre>
<p>The catalyst.pl helper script will display the names of the directories and files it creates.</p>
<p><span class="trans">catalyst.pl ヘルパスクリプトは作成したディレクトリとファイルを表示します。</span></p>
<p>Though it&#8217;s too early for any significant celebration, we already have a functioning application. Run the following command to run this application with the built-in development web server:</p>
<p><span class="trans">お祝いするにはまだ早いですが、すでに機能するアプリケーションになりました。以下のコマンドを実行することで組み込みの開発 Web サーバでアクリケーションを実行できます:</span></p>
<pre class="console">$ script/myapp_server.pl
[debug] Debug messages enabled
[debug] Loaded plugins:
.----------------------------------------------------------------------------.
| Catalyst::Plugin::ConfigLoader  0.13                                       |
| Catalyst::Plugin::Static::Simple  0.14                                     |
'----------------------------------------------------------------------------'
[debug] Loaded dispatcher "Catalyst::Dispatcher"
[debug] Loaded engine "Catalyst::Engine::HTTP"
[debug] Found home "/home/me/MyApp"
[debug] Loaded Config "/home/me/myapp.yml"
[debug] Loaded components:
.-----------------------------------------------------------------+----------.
| Class                                                           | Type     |
+-----------------------------------------------------------------+----------+
| MyApp::Controller::Root                                         | instance |
'-----------------------------------------------------------------+----------'
[debug] Loaded Private actions:
.----------------------+--------------------------------------+--------------.
| Private              | Class                                | Method       |
+----------------------+--------------------------------------+--------------+
| /default             | MyApp::Controller::Root              | default      |
| /end                 | MyApp::Controller::Root              | end          |
'----------------------+--------------------------------------+--------------'
[info] MyApp powered by Catalyst 5.7002
You can connect to your server at http://localhost:3000</pre>
<p>NOTE: Be sure you run the script/myapp_server.pl command from the &#8216;base&#8217; directory of your application, not inside the script directory itself. It doesn&#8217;t make a difference at this point, but it will as soon as we get the database going in the next section.</p>
<p><span class="trans">ノート: script ディレクトリの中からではなく、アプリケーションの ‘ベース’ ディレクトリから script/myapp_server.pl コマンドを実行することに注意してください。現時点ではいずれにせよかわりありませんが、時節でデータベースが出た時点でかわってきます。</span></p>
<p>Point your web browser to http://localhost:3000 (substituting a different hostname or IP address as appropriate) and you should be greeted by the Catalyst welcome screen. Information similar to the following should be appended to the logging output of the development server:</p>
<p><span class="trans">Web ブラウザで http://localhost:3000 を参照すると(異なるホスト名や IP アドレスなど適するものに置き換えてください)、 Catalyst のようこそ画面が表示されるはずです。開発サーバでは以下のようなロギング出力が表示されるはずです:</span></p>
<pre class="console">[info] *** Request 1 (0.043/s) [6003] [Fri Jul  7 13:32:53 2006] ***
[debug] "GET" request for "/" from "127.0.0.1"
[info] Request took 0.067675s (14.777/s)
.----------------------------------------------------------------+-----------.
| Action                                                         | Time      |
+----------------------------------------------------------------+-----------+
| /default                                                       | 0.002844s |
| /end                                                           | 0.000207s |
'----------------------------------------------------------------+-----------'</pre>
<p>Press Ctrl-C to break out of the development server.</p>
<p><span class="trans">Ctrl-C で開発サーバを停止します。</span></p>
<div class="myh">CREATE A SQLITE DATABASE</p>
<p><span class="trans">SQLite データベースの作成</span></div>
<p>In this step, we make a text file with the required SQL commands to create a database table and load some sample data. Open myapp01.sql in your editor and enter:</p>
<p><span class="trans">このステップでは、データベーステーブルを作りいくつかサンプルデータを読み込むために必要となる SQL コマンドを書いたテキストファイルを作ります。エディタで myapp01.sql を開き以下の内容を書いてください:</span></p>
<pre class="sourcecode">--
-- Create a very simple database to hold book and author information
--
CREATE TABLE books (
id          INTEGER PRIMARY KEY,
title       TEXT ,
rating      INTEGER
);
-- 'book_authors' is a many-to-many join table between books &amp; authors
CREATE TABLE book_authors (
book_id     INTEGER,
author_id   INTEGER,
PRIMARY KEY (book_id, author_id)
);
CREATE TABLE authors (
id          INTEGER PRIMARY KEY,
first_name  TEXT,
last_name   TEXT
);
---
--- Load some sample data
---
INSERT INTO books VALUES (1, 'CCSP SNRS Exam Certification Guide', 5);
INSERT INTO books VALUES (2, 'TCP/IP Illustrated, Volume 1', 5);
INSERT INTO books VALUES (3, 'Internetworking with TCP/IP Vol.1', 4);
INSERT INTO books VALUES (4, 'Perl Cookbook', 5);
INSERT INTO books VALUES (5, 'Designing with Web Standards', 5);
INSERT INTO authors VALUES (1, 'Greg', 'Bastien');
INSERT INTO authors VALUES (2, 'Sara', 'Nasseh');
INSERT INTO authors VALUES (3, 'Christian', 'Degu');
INSERT INTO authors VALUES (4, 'Richard', 'Stevens');
INSERT INTO authors VALUES (5, 'Douglas', 'Comer');
INSERT INTO authors VALUES (6, 'Tom', 'Christiansen');
INSERT INTO authors VALUES (7, 'Nathan', 'Torkington');
INSERT INTO authors VALUES (8, 'Jeffrey', 'Zeldman');
INSERT INTO book_authors VALUES (1, 1);
INSERT INTO book_authors VALUES (1, 2);
INSERT INTO book_authors VALUES (1, 3);
INSERT INTO book_authors VALUES (2, 4);
INSERT INTO book_authors VALUES (3, 5);
INSERT INTO book_authors VALUES (4, 6);
INSERT INTO book_authors VALUES (4, 7);
INSERT INTO book_authors VALUES (5, 8);</pre>
<p>TIP: See Appendix 1 for tips on removing the leading spaces when cutting and pasting example code from POD-based documents.</p>
<p><span class="trans">TIP: POD ベースのドキュメントからサンプルコードをコピー＆ペーストし最初にあるスペースを取り除く方法は補遺 1 をみてください。</span></p>
<p>Then use the following command to build a myapp.db SQLite database:</p>
<p><span class="trans">次のコマンドを実行し myapp.db SQLite データベースを構築します:</span></p>
<pre class="console">$ sqlite3 myapp.db &lt; myapp01.sql</pre>
<p>If you need to create the database more than once, you probably want to issue the rm myapp.db command to delete the database before you use the sqlite3 myapp.db &lt; myapp01.sql command.</p>
<p><span class="trans">もし一回以上データベースを作成したいときは sqlite3 myapp.db &lt; myapp01.sql を実行する前に rm myapp.db でデータベースを消したいと思うでしょう。<br />
</span></p>
<p>Once the myapp.db database file has been created and initialized, you can use the SQLite command line environment to do a quick dump of the database contents:</p>
<p><span class="trans">一度 myapp.db データベースが作成され、初期化されれば、 SQLite コマンドライン環境でデータベースの内容のクイックダンプを取得できます:</span></p>
<pre class="console">$ sqlite3 myapp.db
SQLite version 3.2.2
Enter ".help" for instructions
sqlite&gt; select * from books;
1|CCSP SNRS Exam Certification Guide|5
2|TCP/IP Illustrated, Volume 1|5
3|Internetworking with TCP/IP Vol.1|4
4|Perl Cookbook|5
5|Designing with Web Standards|5
sqlite&gt; .q
$</pre>
<p>Or:</p>
<p><span class="trans">或は:</span></p>
<pre class="console">$ sqlite3 myapp.db "select * from books"
1|CCSP SNRS Exam Certification Guide|5
2|TCP/IP Illustrated, Volume 1|5
3|Internetworking with TCP/IP Vol.1|4
4|Perl Cookbook|5
5|Designing with Web Standards|5</pre>
<p>As with most other SQL tools, if you are using the full &#8220;interactive&#8221; environment you need to terminate your SQL commands with a &#8220;;&#8221; (it&#8217;s not required if you do a single SQL statement on the command line). Use &#8220;.q&#8221; to exit from SQLite from the SQLite interactive mode and return to your OS command prompt.</p>
<p><span class="trans">ほとんどの他の SQL ツールのように、もし完全に “インタラクティブ” な環境を使っているのであれば SQL コマンドを “;” で終端する必要がある(これはコマンドラインからひとつの SQL 分を実行するときは必要ない)。SQLite のインタラクティブモードから抜けたいときは “.q” を使う。そうすると OS のコマンドプロンプトに戻ることができる。</span></p>
<div class="myh">EDIT THE LIST OF CATALYST PLUGINS</p>
<p><span class="trans">Catalyst プラグインリストの編集</span></div>
<p>One of the greatest benefits of Catalyst is that it has such a large library of plugins available. Plugins are used to seamlessly integrate existing Perl modules into the overall Catalyst framework. In general, they do this by adding additional methods to the context object (generally written as $c) that Catalyst passes to every component throughout the framework.</p>
<p><span class="trans">Catalyst を使う最も大きな利点のひとつは利用可能なプラグインライブラリ大量に存在することです。プラグインは Catalyst フレームワークを超えてすでに存在する Perl モジュールとシームレスに利用できます。一般に、フレームワークないのすべてのコンポーネントに渡される context オブジェクト(一般に $c と書かれます)に追加のメソッドを加えることによって実現します。</span></p>
<p>By default, Catalyst enables three plugins/flags:</p>
<p><span class="trans">デフォルトでは、 Catalyst は以下の 3 つのプラグインとフラグを有効にします:</span></p>
<ul>
<li>-Debug Flag<span class="trans">-Debug フラグ</span>
<p>Enables the Catalyst debug output you saw when we started the script/myapp_server.pl development server earlier. You can remove this plugin when you place your application into production.</p>
<p><span class="trans">先ほど開発サーバーで script/myapp_server.pl を実行した際にみた Catalyst デバッグ出力を有効にします。アプリケーションを製品として設置する際にこのプラグインを削ることができます。</span></p>
<p>As you may have noticed, -Debug is not a plugin, but a flag. Although most of the items specified on the use Catalyst line of your application class will be plugins, Catalyst supports a limited number of flag options (of these, -Debug is the most common). See the documentation for Catalyst.pm to get details on other flags (currently -Engine, -Home, and -Log).</p>
<p><span class="trans">気づいたかもしれませんが -Debug はプラグインではなく、フラグです。しかしながら、ほとんどの use Catalyst 行で指定されるアイテムはプラグインです。 Catalyst でサポートしているフラグの数は限られています(これらのなかで -Debug が最も一般的です)。他のフラグ(現時点では -Engine、 -Home、そして -Log があります)の詳細については Catalyst.pm のドキュメントを参照してください。</span></p>
<p>If you prefer, you can use the $c-&gt;debug method to enable debug messages.</p>
<p><span class="trans">お好みに応じて、 $c-&gt;debug というメソッドを用いてデバッグメッセージを有効化することもできます。</span></li>
<li>Catalyst::Plugin::ConfigLoader<span class="trans">Catalyst::Plugin::ConfigLoader</span>
<p>ConfigLoader provides an automatic way to load configurable parameters for your application from a central YAML file (versus having the values hard-coded inside your Perl modules). If you have not been exposed to YAML before, it is a human-readable data serialization format that can be used to read (and write) values to/from text files. We will see how to use this feature of Catalyst during the authentication and authorization sections (Part 4 and Part 5).</p>
<p><span class="trans">ConfigLoader はあなたのアプリケーションで(Perl コード中に値をハードコードする代わりに)自動的に中央に配置した YAML ファイルから設定パラメータを取得する方法を提供します。YAML に触れたことがない方のために説明すると、 YAML はテキストファイル(から/へ)データを読む(もしくは書く)ことができる人が読めるデータ永続化フォーマットです。認証と承認の箇所(第四部と第五部)でこれらの機能の使い方をみます。</span></li>
<li>Catalyst::Plugin::Static::Simple<span class="trans">Catalyst::Plugin::Static::Simple</span>
<p>Static::Simple provides an easy method of serving static content such as images and CSS files under the development server.</p>
<p><span class="trans">Static::Simple は開発サーバで画像や CSS ファイルといったスタティックなコンテンツを簡単に提供するための方法を提供します。</span></li>
</ul>
<p>To modify the list of plugins, edit lib/MyApp.pm (this file is generally referred to as your application class) and delete the line with:</p>
<p><span class="trans">プラグインリストを変更するためには、 lib/MyApp.pm(このファイルはアプリケーションクラスとして参照されます)を編集し、以下の行を:</span></p>
<pre class="sourcecode">use Catalyst qw/-Debug ConfigLoader Static::Simple/;</pre>
<p>Replace it with:</p>
<p><span class="trans">以下のように差し替えます:</span></p>
<pre class="sourcecode">use Catalyst qw/
-Debug
ConfigLoader
Static::Simple
StackTrace
/;</pre>
<p>This tells Catalyst to start using one new plugin:</p>
<p><span class="trans">上記では Catalyst に対して新しいプラグインを使い始めることを教えています。</span></p>
<ul>
<li>Catalyst::Plugin::StackTrace<span class="trans">Catalyst::Plugin::StackTrace</span>
<p>Adds a stack trace to the standard Catalyst &#8220;debug screen&#8221; (this is the screen Catalyst sends to your browser when an error occurs).</p>
<p><span class="trans">標準の Catalyst “デバッグ画面”(エラーが起こったときに Catalyst がブラウザに対して表示する画面です)にスタックトレースを追加します。</span></p>
<p>Note: StackTrace output appears in your browser, not in the console window from which you&#8217;re running your application, which is where logging output usually goes.</p>
<p><span class="trans">StackTrace 出力はアプリケーションを実行しているコンソール上ではなくブラウザ上に現れます。ログ出力は通常こちらに現れます。</span></li>
</ul>
<p>Note that when specifying plugins on the use Catalyst line, you can omit Catalyst::Plugin:: from the name. Additionally, you can spread the plugin names across multiple lines as shown here, or place them all on one (or more) lines as with the default configuration.</p>
<p><span class="trans">use Catalyst 行でプラグインを指定する際、その名前から Catalyst::Plugin:: を省くことができます。また、ここに書いたようにプラグイン名を複数業にわたって書くことも、デフォルトの設定のようにすべてを一行(あるいはもっと)に書くこともできます。</span></p>
<p>TIP: You may see examples that include the Catalyst::Plugin::DefaultEnd plugins. As of Catalyst 5.7000, DefaultEnd has been deprecated in favor of Catalyst::Action::RenderView (as the name of the package suggests, RenderView is not a plugin, but an action). The purpose of both is essentially the same: forward processing to the view to be rendered. Applications generated under 5.7000 should automatically use RenderView and &#8220;just work&#8221; for most applications. For more information on RenderView and the various options for forwarding to your view logic, please refer to the &#8220;Using RenderView for the Default View&#8221; section under &#8220;CATALYST VIEWS&#8221; below.</p>
<p><span class="trans">Catalyst::Plugin::DefaultEnd を利用しているサンプルを見かけるかもしれません。Catalyst 5.7000 現在、 DefaultEnd は Catalyst::Action::RenderView(名前の通り RenderView はプラグインではなくアクションです)により非推奨となっています。これらの目的は本質的には一緒です: 表示されるべきビューへ処理を進めます。 5.7000 の元に生成されたアプリケーションは自動的に RenderView を利用し、ほとんどのアプリケーションで&#8221;うまく動きます”。 RenderView の詳細な情報とビューロジックを転送する多彩なオプションについては以下の “Catalyst ビュー” の “デフォルトのビューに RenderView を使う” を参照してください。</span></p>
<div class="myh">DATABASE ACCESS WITH DBIx::Class</p>
<p><span class="trans">DBIx::Class によるデータベースアクセス</span></div>
<p>Catalyst can be used with virtually any form of persistent datastore available via Perl. For example, Catalyst::Model::DBI can be used to easily access databases through the traditional Perl DBI interface. However, most Catalyst applications use some form of ORM technology to automatically create and save model objects as they are used. Although Tony Bowden&#8217;s Class::DBI has been the traditional Perl ORM engine, Matt Trout&#8217;s DBIx::Class (abbreviated as &#8220;DBIC&#8221;) has rapidly emerged as the Perl-based ORM technology of choice. Most new Catalyst applications rely on DBIC, as will this tutorial.</p>
<p><span class="trans">Catalyst は Perl で利用可能なすべての永続データストアを仮想的に利用できます。例えば Catalyst::Model::DBI を伝統的な Perl の DBI インターフェースを通じた簡単なデータベースアクセスに利用できます。しかし、ほとんどの Catalyst アプリケーションは利用するモデルオブジェクトを自動的に生成したり保存したりするためになにかしらの ORM 技術を利用します。Tony Bowden の Class:DBI は伝統的な Perl ORM エンジンですが、 Matt Trout の DBIx::Class(“DBIC” と略されます) は Perl での ORM 技術の選択として急に浮かび上がってきました。ほとんどの新しい Catalyst アプリケーションは DBIC に依っていますので、このチュートリアルでも従います。</span></p>
<p>Note: See Catalyst::Model::CDBI for more information on using Catalyst with Class::DBI.</p>
<p><span class="trans">ノート: Class::DBI で Catalyst を利用するときの詳細な情報は Catalyst::Model::CDBI を参照してください。</span></p>
<div class="myh">Create a DBIC Schema File</p>
<p><span class="trans">DBIC スキーマファイルの作成</span></div>
<p>DBIx::Class uses a schema file to load other classes that represent the tables in your database (DBIC refers to these &#8220;table objects&#8221; as &#8220;result sources&#8221;; see DBIx::Class::ResultSource). In this case, we want to load the model object for the books, book_authors, and authors tables created in the previous step.</p>
<p><span class="trans"> </span></p>
<p>Create lib/MyAppDB.pm in your editor and insert:</p>
<p><span class="trans"> </span></p>
<pre class="sourcecode">package MyAppDB;
=head1 NAME
MyAppDB - DBIC Schema Class
=cut
# Our schema needs to inherit from 'DBIx::Class::Schema'
use base qw/DBIx::Class::Schema/;
# Need to load the DB Model classes here.
# You can use this syntax if you want:
#    __PACKAGE__-&gt;load_classes(qw/Book BookAuthor Author/);
# Also, if you simply want to load all of the classes in a directory
# of the same name as your schema class (as we do here) you can use:
#    __PACKAGE__-&gt;load_classes(qw//);
# But the variation below is more flexible in that it can be used to
# load from multiple namespaces.
__PACKAGE__-&gt;load_classes({
MyAppDB =&gt; [qw/Book BookAuthor Author/]
});
1;</pre>
<p>Note: __PACKAGE__ is just a shorthand way of referencing the name of the package where it is used. Therefore, in MyAppDB.pm, __PACKAGE__ is equivalent to MyAppDB.</p>
<p><span class="trans"> </span></p>
<p>Note: As with any Perl package, we need to end the last line with a statement that evaluates to true. This is customarily done with 1 on a line by itself as shown above.</p>
<p><span class="trans"> </span></p>
<div class="myh">Create the DBIC &#8220;Result Source&#8221; Files</p>
<p><span class="trans"> </span></div>
<p>In this step, we create &#8220;table classes&#8221; (again, these are called a &#8220;result source&#8221; classes in DBIC) that act as model objects for the books, book_authors, and authors tables in our database.</p>
<p><span class="trans"> </span></p>
<p>First, create a directory to hold the class:</p>
<p><span class="trans"> </span></p>
<pre class="console">$ mkdir lib/MyAppDB</pre>
<p>Then create lib/MyAppDB/Book.pm in your editor and enter:</p>
<p><span class="trans"> </span></p>
<pre class="sourcecode">package MyAppDB::Book;
use base qw/DBIx::Class/;
# Load required DBIC stuff
__PACKAGE__-&gt;load_components(qw/PK::Auto Core/);
# Set the table name
__PACKAGE__-&gt;table('books');
# Set columns in table
__PACKAGE__-&gt;add_columns(qw/id title rating/);
# Set the primary key for the table
__PACKAGE__-&gt;set_primary_key(qw/id/);
#
# Set relationships:
#
# has_many():
#   args:
#     1) Name of relationship, DBIC will create accessor with this name
#     2) Name of the model class referenced by this relationship
#     3) Column name in *foreign* table
__PACKAGE__-&gt;has_many(book_authors =&gt; 'MyAppDB::BookAuthor', 'book_id');
# many_to_many():
#   args:
#     1) Name of relationship, DBIC will create accessor with this name
#     2) Name of has_many() relationship this many_to_many() is shortcut for
#     3) Name of belongs_to() relationship in model class of has_many() above
#   You must already have the has_many() defined to use a many_to_many().
__PACKAGE__-&gt;many_to_many(authors =&gt; 'book_authors', 'author');
=head1 NAME
MyAppDB::Book - A model object representing a book.
=head1 DESCRIPTION
This is an object that represents a row in the 'books' table of your application
database.  It uses DBIx::Class (aka, DBIC) to do ORM.
For Catalyst, this is designed to be used through MyApp::Model::MyAppDB.
Offline utilities may wish to use this class directly.
=cut
1;</pre>
<p>This defines both a has_many and a many_to_many relationship. The many_to_many relationship is optional, but it makes it easier to map a book to its collection of authors. Without it, we would have to &#8220;walk&#8221; though the book_authors table as in $book-&gt;book_authors-&gt;first-&gt;author-&gt;last_name (we will see examples on how to use DBIC objects in your code soon, but note that because $book-&gt;book_authors can return multiple authors, we have to use first to display a single author). many_to_many allows us to use the shorter $book-&gt;authors-&gt;first-&gt;last_name. Note that you cannot define a many_to_many relationship without also having the has_many relationship in place.</p>
<p><span class="trans"> </span></p>
<p>Next, create lib/MyAppDB/Author.pm in your editor and enter:</p>
<p><span class="trans"> </span></p>
<pre class="sourcecode">package MyAppDB::Author;
use base qw/DBIx::Class/;
# Load required DBIC stuff
__PACKAGE__-&gt;load_components(qw/PK::Auto Core/);
# Set the table name
__PACKAGE__-&gt;table('authors');
# Set columns in table
__PACKAGE__-&gt;add_columns(qw/id first_name last_name/);
# Set the primary key for the table
__PACKAGE__-&gt;set_primary_key(qw/id/);
#
# Set relationships:
#
# has_many():
#   args:
#     1) Name of relationship, DBIC will create accessor with this name
#     2) Name of the model class referenced by this relationship
#     3) Column name in *foreign* table
__PACKAGE__-&gt;has_many(book_author =&gt; 'MyAppDB::BookAuthor', 'author_id');
# many_to_many():
#   args:
#     1) Name of relationship, DBIC will create accessor with this name
#     2) Name of has_many() relationship this many_to_many() is shortcut for
#     3) Name of belongs_to() relationship in model class of has_many() above
#   You must already have the has_many() defined to use a many_to_many().
__PACKAGE__-&gt;many_to_many(books =&gt; 'book_author', 'book');
=head1 NAME
MyAppDB::Author - A model object representing an author of a book (if a book has
multiple authors, each will be represented be separate Author object).
=head1 DESCRIPTION
This is an object that represents a row in the 'authors' table of your application
database.  It uses DBIx::Class (aka, DBIC) to do ORM.
For Catalyst, this is designed to be used through MyApp::Model::MyAppDB.
Offline utilities may wish to use this class directly.
=cut
1;</pre>
<p>Finally, create lib/MyAppDB/BookAuthor.pm in your editor and enter:</p>
<p><span class="trans"> </span></p>
<pre class="sourcecode">package MyAppDB::BookAuthor;
use base qw/DBIx::Class/;
# Load required DBIC stuff
__PACKAGE__-&gt;load_components(qw/PK::Auto Core/);
# Set the table name
__PACKAGE__-&gt;table('book_authors');
# Set columns in table
__PACKAGE__-&gt;add_columns(qw/book_id author_id/);
# Set the primary key for the table
__PACKAGE__-&gt;set_primary_key(qw/book_id author_id/);
#
# Set relationships:
#
# belongs_to():
#   args:
#     1) Name of relationship, DBIC will create accessor with this name
#     2) Name of the model class referenced by this relationship
#     3) Column name in *this* table
__PACKAGE__-&gt;belongs_to(book =&gt; 'MyAppDB::Book', 'book_id');
# belongs_to():
#   args:
#     1) Name of relationship, DBIC will create accessor with this name
#     2) Name of the model class referenced by this relationship
#     3) Column name in *this* table
__PACKAGE__-&gt;belongs_to(author =&gt; 'MyAppDB::Author', 'author_id');
=head1 NAME
MyAppDB::BookAuthor - A model object representing the JOIN between an author and
a book.
=head1 DESCRIPTION
This is an object that represents a row in the 'book_authors' table of your
application database.  It uses DBIx::Class (aka, DBIC) to do ORM.
You probably won't need to use this class directly -- it will be automatically
used by DBIC where joins are needed.
For Catalyst, this is designed to be used through MyApp::Model::MyAppDB.
Offline utilities may wish to use this class directly.
=cut
1;</pre>
<p>Note: This sample application uses a plural form for the database tables (e.g., books and authors) and a singular form for the model objects (e.g., Book and Author); however, Catalyst places no restrictions on the naming conventions you wish to use.</p>
<p><span class="trans"> </span></p>
<div class="myh">Use Catalyst::Model::DBIC::Schema To Load The Model Class</div>
<p>When Catalyst::Model::DBIC::Schema is in use, Catalyst essentially reads an existing copy of your database model and creates a new set of objects under MyApp::Model for use inside of Catalyst.</p>
<p>Note: With Catalyst::Model::DBIC::Schema you essentially end up with two sets of model classes (only one of which you write&#8230; the other set is created automatically in memory when your Catalyst application initializes). For this tutorial application, the important points to remember are: you write the result source files in MyAppDB, but within Catalyst you use the automatically created model classes in MyApp::Model.</p>
<p>Use the Catalyst::Helper::Model::DBIC::Schema helper script to create the model class that loads up the model we created in the previous step:</p>
<pre class="console">$ script/myapp_create.pl model MyAppDB DBIC::Schema MyAppDB dbi:SQLite:myapp.db '' '' '{ AutoCommit =&gt; 1 }'
exists "/root/dev/MyApp/script/../lib/MyApp/Model"
exists "/root/dev/MyApp/script/../t"
created "/root/dev/MyApp/script/../lib/MyApp/Model/MyAppDB.pm"
created "/root/dev/MyApp/script/../t/model_MyAppDB.t"</pre>
<p>Where the first MyAppDB is the name of the class to be created by the helper in lib/MyApp/Model and the second MyAppDB is the name of existing schema file we created (in lib/MyAppDB.pm). You can see that the helper creates a model file under lib/MyApp/Model (Catalyst has a separate directory under lib/MyApp for each of the three parts of MVC: Model, View, and Controller [although older Catalyst applications often use the directories M, V, and C]).</p>
<div class="myh">CREATE A CATALYST CONTROLLER</div>
<p>Controllers are where you write methods that interact with user input&#8211;typically, controller methods respond to GET and POST messages from the user&#8217;s web browser.</p>
<p>Use the Catalyst create script to add a controller for book-related actions:</p>
<pre class="console">$ script/myapp_create.pl controller Books
exists "/root/dev/MyApp/script/../lib/MyApp/Controller"
exists "/root/dev/MyApp/script/../t"
created "/root/dev/MyApp/script/../lib/MyApp/Controller/Books.pm"
created "/root/dev/MyApp/script/../t/controller_Books.t"</pre>
<p>Then edit lib/MyApp/Controller/Books.pm and add the following method to the controller:</p>
<pre class="sourcecode">=head2 list
Fetch all book objects and pass to books/list.tt2 in stash to be displayed
=cut
sub list : Local {
# Retrieve the usual perl OO '$self' for this object. $c is the Catalyst
# 'Context' that's used to 'glue together' the various components
# that make up the application
my ($self, $c) = @_;
# Retrieve all of the book records as book model objects and store in the
# stash where they can be accessed by the TT template
$c-&gt;stash-&gt;{books} = [$c-&gt;model('MyAppDB::Book')-&gt;all];
# Set the TT template to use.  You will almost always want to do this
# in your action methods (action methods respond to user input in
# your controllers).
$c-&gt;stash-&gt;{template} = 'books/list.tt2';
}</pre>
<p>Note: Programmers experienced with object-oriented Perl should recognize $self as a reference to the object where this method was called. On the other hand, $c will be new to many Perl programmers who have not used Catalyst before (it&#8217;s sometimes written as $context). The Context object is automatically passed to all Catalyst components. It is used to pass information between components and provide access to Catalyst and plugin functionality.</p>
<p>TIP: You may see the $c-&gt;model(&#8216;MyAppDB::Book&#8217;) used above written as $c-&gt;model(&#8216;MyAppDB&#8217;)-&gt;resultset(&#8216;Book). The two are equivalent.</p>
<p>Note: Catalyst actions are regular Perl methods, but they make use of Nicholas Clark&#8217;s attributes module (that&#8217;s the : Local next to the sub list in the code above) to provide additional information to the Catalyst dispatcher logic.</p>
<div class="myh">CATALYST VIEWS</div>
<p>Views are where you render output, typically for display in the user&#8217;s web browser, but also possibly using other display output-generation systems. As with virtually every aspect of Catalyst, options abound when it comes to the specific view technology you adopt inside your application. However, most Catalyst applications use the Template Toolkit, known as TT (for more information on TT, see http://www.template-toolkit.org). Other popular view technologies include Mason (http://www.masonhq.com and http://www.masonbook.com) and HTML::Template (http://html-template.sourceforge.net).</p>
<div class="myh">Create a Catalyst View Using TTSite</div>
<p>When using TT for the Catalyst view, there are two main helper scripts:</p>
<ul>
<li>Catalyst::Helper::View::TT</li>
<li>Catalyst::Helper::View::TTSite</li>
</ul>
<p>Both are similar, but TT merely creates the lib/MyApp/View/TT.pm file and leaves the creation of any hierarchical template organization entirely up to you. (It also creates a t/view_TT.t file for testing; test cases will be discussed in Part 7). The TTSite helper creates a modular and hierarchical view layout with separate Template Toolkit (TT) files for common header and footer information, configuration values, a CSS stylesheet, and more.</p>
<p>While TTSite is useful to bootstrap a project, we recommend that unless you know what your&#8217;re doing or want to pretty much use the supplied templates as is, that you use the plain Template Toolkit view when starting a project from scratch. This is because TTSite can be tricky to customize. Additionally TT contains constructs that you need to learn yourself if you&#8217;re going to be a serious user of TT. Our experience suggests that you&#8217;re better off learning these from scratch. We use TTSite here precisely because it is useful for bootstrap/prototype purposes.</p>
<p>Enter the following command to enable the TTSite style of view rendering for this tutorial:</p>
<pre class="console">$ script/myapp_create.pl view TT TTSite
exists "/root/dev/MyApp/script/../lib/MyApp/View"
exists "/root/dev/MyApp/script/../t"
created "/root/dev/MyApp/script/../lib/MyApp/View/TT.pm"
created "/root/dev/MyApp/script/../root/lib"
...
created "/root/dev/MyApp/script/../root/src/ttsite.css"</pre>
<p>This puts a number of files in the root/lib and root/src directories that can be used to customize the look and feel of your application. Also take a look at lib/MyApp/View/TT.pm for config values set by the TTSite helper.</p>
<p>TIP: Note that TTSite does one thing that could confuse people who are used to the normal TT Catalyst view: it redefines the Catalyst context object in templates from its usual c to Catalyst. When looking at other Catalyst examples, remember that they almost always use c. Note that Catalyst and TT do not complain when you use the wrong name to access the context object&#8230;TT simply outputs blanks for that bogus logic (see next tip to change this behavior with TT DEBUG options). Finally, be aware that this change in name only applies to how the context object is accessed inside your TT templates; your controllers will continue to use $c (or whatever name you use when fetching the reference from @_ inside your methods). (You can change back to the &#8220;default&#8221; behavior be removing the CATALYST_VAR line from lib/MyApp/View/TT.pm, but you will also have to edit root/lib/config/main and root/lib/config/url. If you do this, be careful not to have a collision between your own c variable and the Catalyst c variable.)</p>
<p>TIP: When troubleshooting TT it can be helpful to enable variable DEBUG options. You can do this in a Catalyst environment by adding a DEBUG line to the __PACKAGE__-config&gt; declaration in lib/MyApp/View/TT.pm:</p>
<pre class="sourcecode">__PACKAGE__-&gt;config({
CATALYST_VAR =&gt; 'Catalyst',
...
DEBUG        =&gt; 'undef',
...
});</pre>
<p>There are a variety of options you can use, such as &#8216;undef&#8217;, &#8216;all&#8217;, &#8216;service&#8217;, &#8216;context&#8217;, &#8216;parser&#8217;, &#8216;provider&#8217;, and &#8216;service&#8217;. See Template::Constants for more information (remove the DEBUG_ portion of the name shown in the TT docs and convert to lower case for use inside Catalyst).</p>
<p>NOTE: Please be sure to disable TT debug options before continuing the tutorial (especially the &#8216;undef&#8217; option &#8212; leaving this enabled will conflict with several of the conventions used by this tutorial and TTSite to leave some variables undefined on purpose).</p>
<div class="myh">Using RenderView for the Default View</div>
<p>Once your controller logic has processed the request from a user, it forwards processing to your view in order to generate the appropriate response output. Catalyst v5.7000 ships with a new mechanism, Catalyst::Action::RenderView, that automatically performs this operation. If you look in lib/MyApp/Controller/Root.pm, you should see the empty definition for the sub end method:</p>
<pre class="sourcecode">sub end : ActionClass('RenderView') {}</pre>
<p>The following bullet points provide a quick overview of the RenderView process:</p>
<ul>
<li>Root.pm is designed to hold application-wide logic.</li>
<li>At the end of a given user request, Catalyst will call the most specific end method that&#8217;s appropriate. For example, if the controller for a request has an end method defined, it will be called. However, if the controller does not define a controller-specific end method, the &#8220;global&#8221; end method in Root.pm will be called.</li>
<li>Because the definition includes an ActionClass attribute, the Catalyst::Action::RenderView logic will be executed after any code inside the definition of sub end is run. See Catalyst::Manual::Actions for more information on ActionClass.</li>
<li>Because sub end is empty, this effectively just runs the default logic in RenderView. However, you can easily extend the RenderView logic by adding your own code inside the empty method body ({}) created by the Catalyst Helpers when we first ran the catalyst.pl to initialize our application. See Catalyst::Action::RenderView for more detailed information on how to extended RenderView in sub end.</li>
</ul>
<div class="myh">The History Leading Up To RenderView</div>
<p>Although RenderView strikes a nice balance between default behavior and easy extensibility, it is a new feature that won&#8217;t appear in most existing Catalyst examples. This section provides some brief background on the evolution of default view rendering logic with an eye to how they can be migrated to RenderView:</p>
<ul>
<li>Private end Action in Application ClassOlder Catalyst-related documents often suggest that you add a &#8220;private end action&#8221; to your application class (MyApp.pm) or Root.pm (MyApp/Controller/Root.pm). These examples should be easily converted to RenderView by simply adding the attribute :ActionClass(&#8216;RenderView&#8217;) to the sub end definition. If end sub is defined in your application class (MyApp.pm), you should also migrate it to MyApp/Controller/Root.pm.</li>
<li>Catalyst::Plugin::DefaultEndDefaultEnd represented the &#8220;next step&#8221; in passing processing from your controller to your view. It has the advantage of only requiring that DefaultEnd be added to the list of plugins in lib/MyApp.pm. It also allowed you to add &#8220;dump_info=1&#8243; (precede with &#8220;?&#8221; or &#8220;&amp;&#8221; depending on where it is in the URL) to force the debug screen at the end of the Catalyst request processing cycle. However, it was more difficult to extend than the RenderView mechanism, and is now deprecated.</li>
<li>Catalyst::Action::RenderViewAs discussed above, the current recommended approach to handling your view logic relies on Catalyst::Action::RenderView. Although similar in first appearance to the &#8220;private end action&#8221; approach, it utilizes Catalyst&#8217;s &#8220;ActionClass&#8221; mechanism to provide both automatic default behavior (you don&#8217;t have to include a plugin as with DefaultEnd) and easy extensibility. As with DefaultEnd, it allows you to add &#8220;dump_info=1&#8243; (precede with &#8220;?&#8221; or &#8220;&amp;&#8221; depending on where it is in the URL) to force the debug screen at the end of the Catalyst request processing cycle.</li>
</ul>
<p>It is recommended that all Catalyst applications use or migrate to the RenderView approach.</p>
<div class="myh">Globally Customize Every View</div>
<p>When using TTSite, files in the subdirectories of root/lib can be used to make changes that will appear in every view. For example, to display optional status and error messages in every view, edit root/lib/site/layout, updating it to match the following (the two HTML span elements are new):</p>
<pre class="sourcecode">&lt;div id="header"&gt;[% PROCESS site/header %]&lt;/div&gt;
&lt;div id="content"&gt;
&lt;span class="message"&gt;[% status_msg %]&lt;/span&gt;
&lt;span class="error"&gt;[% error_msg %]&lt;/span&gt;
[% content %]
&lt;/div&gt;
&lt;div id="footer"&gt;[% PROCESS site/footer %]&lt;/div&gt;</pre>
<p>If we set either message in the Catalyst stash (e.g., $c-&gt;stash-&gt;{status_msg} = &#8216;Request was successful!&#8217;) it will be displayed whenever any view used by that request is rendered. The message and error CSS styles are automatically defined in root/src/ttsite.css and can be customized to suit your needs.</p>
<p>Note: The Catalyst stash only lasts for a single HTTP request. If you need to retain information across requests you can use Catalyst::Plugin::Session (we will use Catalyst sessions in the Authentication part of the tutorial).</p>
<div class="myh">Create a TT Template Page</div>
<p>To add a new page of content to the TTSite view hierarchy, just create a new .tt2 file in root/src. Only include HTML markup that goes inside the HTML  and  tags, TTSite will use the contents of root/lib/site to add the top and bottom.</p>
<p>First create a directory for book-related TT templates:</p>
<pre class="console">$ mkdir root/src/books</pre>
<p>Then create root/src/books/list.tt2 in your editor and enter:</p>
<pre class="sourcecode">[% # This is a TT comment.  The '-' at the end "chomps" the newline.  You won't -%]
[% # see this "chomping" in your browser because HTML ignores blank lines, but  -%]
[% # it WILL eliminate a blank line if you view the HTML source.  It's purely   -%]
[%- # optional, but both the beginning and the ending TT tags support chomping. -%]
[% # Provide a title to root/lib/site/header -%]
[% META title = 'Book List' -%]
&lt;table&gt;
&lt;tr&gt;&lt;th&gt;Title&lt;/th&gt;&lt;th&gt;Rating&lt;/th&gt;&lt;th&gt;Author(s)&lt;/th&gt;&lt;/tr&gt;
[% # Display each book in a table row %]
[% FOREACH book IN books -%]
&lt;tr&gt;
&lt;td&gt;[% book.title %]&lt;/td&gt;
&lt;td&gt;[% book.rating %]&lt;/td&gt;
&lt;td&gt;
[% # First initialize a TT variable to hold a list.  Then use a TT FOREACH -%]
[% # loop in 'side effect notation' to load just the last names of the     -%]
[% # authors into the list.  Note that the 'push' TT vmethod does not      -%]
[% # a value, so nothing will be printed here.  But, if you have something -%]
[% # in TT that does return a method and you don't want it printed, you    -%]
[% # can: 1) assign it to a bogus value, or 2) use the CALL keyword to     -%]
[% # call it and discard the return value.                                 -%]
[% tt_authors = [ ];
tt_authors.push(author.last_name) FOREACH author = book.authors %]
[% # Now use a TT 'virtual method' to display the author count in parens   -%]
([% tt_authors.size %])
[% # Use another TT vmethod to join &amp; print the names &amp; comma separators   -%]
[% tt_authors.join(', ') %]
&lt;/td&gt;
&lt;/tr&gt;
[% END -%]
&lt;/table&gt;</pre>
<p>As indicated by the inline comments above, the META title line uses TT&#8217;s META feature to provide a title to root/lib/site/header. Meanwhile, the outer FOREACH loop iterates through each book model object and prints the title and rating fields. An inner FOREACH loop prints the last name of each author in a comma-separated list within a single table cell.</p>
<p>If you are new to TT, the [% and %] tags are used to delimit TT code. TT supports a wide variety of directives for &#8220;calling&#8221; other files, looping, conditional logic, etc. In general, TT simplifies the usual range of Perl operators down to the single dot (.) operator. This applies to operations as diverse as method calls, hash lookups, and list index values (see http://www.template-toolkit.org/docs/default/Manual/Variables.html for details and examples). In addition to the usual Template module Pod documentation, you can access the TT manual at http://www.template-toolkit.org/docs/default/.</p>
<p>NOTE: The TTSite helper creates several TT files using an extension of .tt2. Most other Catalyst and TT examples use an extension of .tt. You can use either extension (or no extension at all) with TTSite and TT, just be sure to use the appropriate extension for both the file itself and the $c-&gt;stash-&gt;{template} = &#8230; line in your controller. This document will use .tt2 for consistency with the files already created by the TTSite helper.</p>
<div class="myh">RUN THE APPLICATION</div>
<p>First, let&#8217;s enable an environment variable option that causes DBIx::Class to dump the SQL statements it&#8217;s using to access the database (this option can provide extremely helpful troubleshooting information):</p>
<pre class="console">$ export DBIC_TRACE=1</pre>
<p>NOTE: You can also use the older export DBIX_CLASS_STORAGE_DBI_DEBUG=1, but that&#8217;s a lot more to type.</p>
<p>This assumes you are using BASH as your shell &#8212; adjust accordingly if you are using a different shell (for example, under tcsh, use setenv DBIX_CLASS_STORAGE_DBI_DEBUG 1).</p>
<p>NOTE: You can also set this in your code using $class-&gt;storage-&gt;debug(1);. See DBIx::Class::Manual::Troubleshooting for details (including options to log to file instead of displaying to the Catalyst development server log).</p>
<p>Then run the Catalyst &#8220;demo server&#8221; script:</p>
<pre class="console">$ script/myapp_server.pl</pre>
<p>Your development server log output should display something like:</p>
<pre class="console">$ script/myapp_server.pl
[debug] Debug messages enabled
[debug] Loaded plugins:
.----------------------------------------------------------------------------.
| Catalyst::Plugin::ConfigLoader  0.13                                       |
| Catalyst::Plugin::StackTrace  0.06                                         |
| Catalyst::Plugin::Static::Simple  0.14                                     |
'----------------------------------------------------------------------------'
[debug] Loaded dispatcher "Catalyst::Dispatcher"
[debug] Loaded engine "Catalyst::Engine::HTTP"
[debug] Found home "/home/me/MyApp"
[debug] Loaded Config "/home/me/myapp.yml"
[debug] Loaded components:
.-----------------------------------------------------------------+----------.
| Class                                                           | Type     |
+-----------------------------------------------------------------+----------+
| MyApp::Controller::Books                                        | instance |
| MyApp::Controller::Root                                         | instance |
| MyApp::Model::MyAppDB                                           | instance |
| MyApp::Model::MyAppDB::Author                                   | class    |
| MyApp::Model::MyAppDB::Book                                     | class    |
| MyApp::Model::MyAppDB::BookAuthor                               | class    |
| MyApp::View::TT                                                 | instance |
'-----------------------------------------------------------------+----------'
[debug] Loaded Private actions:
.----------------------+--------------------------------------+--------------.
| Private              | Class                                | Method       |
+----------------------+--------------------------------------+--------------+
| /default             | MyApp::Controller::Root              | default      |
| /end                 | MyApp::Controller::Root              | end          |
| /books/index         | MyApp::Controller::Books             | index        |
| /books/list          | MyApp::Controller::Books             | list         |
'----------------------+--------------------------------------+--------------'
[debug] Loaded Path actions:
.-------------------------------------+--------------------------------------.
| Path                                | Private                              |
+-------------------------------------+--------------------------------------+
| /books/list                         | /books/list                          |
'-------------------------------------+--------------------------------------'
[info] MyApp powered by Catalyst 5.7002
You can connect to your server at http://localhost:3000</pre>
<p>Some things you should note in the output above:</p>
<ul>
<li>Catalyst::Model::DBIC::Schema took our MyAppDB::Book and made it MyApp::Model::MyAppDB::Book (and similar actions were performed on MyAppDB::Author and MyAppDB::BookAuthor).</li>
<li>The &#8220;list&#8221; action in our Books controller showed up with a path of /books/list.</li>
</ul>
<p>Point your browser to http://localhost:3000 and you should still get the Catalyst welcome page.</p>
<p>Next, to view the book list, change the URL in your browser to http://localhost:3000/books/list. You should get a list of the five books loaded by the myapp01.sql script above, with TTSite providing the formatting for the very simple output we generated in our template. The count and space-separated list of author last names appear on the end of each row.</p>
<p>Also notice in the output of the script/myapp_server.pl that DBIC used the following SQL to retrieve the data:</p>
<pre class="sourcecode">SELECT me.id, me.title, me.rating FROM books me</pre>
<p>Along with a list of the following commands to retrieve the authors for each book (the lines have been &#8220;word wrapped&#8221; here to improve legibility):</p>
<pre class="sourcecode">SELECT author.id, author.first_name, author.last_name
FROM book_authors me
JOIN authors author ON ( author.id = me.author_id )
WHERE ( me.book_id = ? ): `1'</pre>
<p>You should see 5 such lines of debug output as DBIC fetches the author information for each book.</p>
<div class="myh">USING THE DEFAULT TEMPLATE NAME</div>
<p>By default, Catalyst::View::TT will look for a template that uses the same name as your controller action, allowing you to save the step of manually specifying the template name in each action. For example, this would allow us to remove the $c-&gt;stash-&gt;{template} = &#8216;books/list.tt2&#8242;; line of our list action in the Books controller. Open lib/MyApp/Controller/Books.pm in your editor and comment out this line to match the following (only the $c-&gt;stash-&gt;{template} line has changed):</p>
<pre class="sourcecode">=head2 list
Fetch all book objects and pass to books/list.tt2 in stash to be displayed
=cut
sub list : Local {
# Retrieve the usual perl OO '$self' for this object. $c is the Catalyst
# 'Context' that's used to 'glue together' the various components
# that make up the application
my ($self, $c) = @_;
# Retrieve all of the book records as book model objects and store in the
# stash where they can be accessed by the TT template
$c-&gt;stash-&gt;{books} = [$c-&gt;model('MyAppDB::Book')-&gt;all];
# Set the TT template to use.  You will almost always want to do this
# in your action methods (actions methods respond to user input in
# your controllers).
#$c-&gt;stash-&gt;{template} = 'books/list.tt2';
}</pre>
<p>Catalyst::View::TT defaults to looking for a template with no extension. In our case, we need to override this to look for an extension of .tt2. Open lib/MyApp/View/TT.pm and add the TEMPLATE_EXTENSION definition as follows:</p>
<pre class="sourcecode">__PACKAGE__-&gt;config({
CATALYST_VAR =&gt; 'Catalyst',
INCLUDE_PATH =&gt; [
MyApp-&gt;path_to( 'root', 'src' ),
MyApp-&gt;path_to( 'root', 'lib' )
],
PRE_PROCESS  =&gt; 'config/main',
WRAPPER      =&gt; 'site/wrapper',
ERROR        =&gt; 'error.tt2',
TIMER        =&gt; 0,
TEMPLATE_EXTENSION =&gt; '.tt2',
});</pre>
<p>You should now be able to restart the development server as per the previous section and access the http://localhost:3000/books/list as before.</p>
<p>NOTE: Please note that if you use the default template technique, you will not be able to use either the $c-&gt;forward or the $c-&gt;detach mechanisms (these are discussed in Part 2 and Part 8 of the Tutorial).</p>
<div class="myh">RETURN TO A MANUALLY-SPECIFIED TEMPLATE</div>
<p>In order to be able to use $c-&gt;forward and $c-&gt;detach later in the tutorial, you should remove the comment from the statement in sub list:</p>
<pre class="sourcecode">$c-&gt;stash-&gt;{template} = 'books/list.tt2';</pre>
<p>Then delete the TEMPLATE_EXTENSION line in lib/MyApp/View/TT.pm.</p>
<p>You should then be able to restart the development server and access http://localhost:3000/books/list in the same manner as with earlier sections.</p>
<div class="myh">AUTHOR</p>
<p><span class="trans">著者</span></div>
<p>Kennedy Clark, hkclark [a] gmail.com</p>
<p><span class="trans">Kennedy Clark, hkclark [a] gmail.com</span></p>
<p>Please report any errors, issues or suggestions to the author. The most recent version of the Catalyst Tutorial can be found at http://dev.catalyst.perl.org/repos/Catalyst/trunk/Catalyst-Manual/lib/Catalyst/Manual/Tutorial/.</p>
<p><span class="trans">Please report any errors, issues or suggestions to the author. The most recent version of the Catalyst Tutorial can be found at http://dev.catalyst.perl.org/repos/Catalyst/trunk/Catalyst-Manual/lib/Catalyst/Manual/Tutorial/.</span></p>
<p>Copyright 2006, Kennedy Clark, under Creative Commons License (http://creativecommons.org/licenses/by-nc-sa/2.5/).</p>
<p><span class="trans">Copyright 2006, Kennedy Clark, under Creative Commons License (http://creativecommons.org/licenses/by-nc-sa/2.5/).</span></p>
]]></content:encoded>
			<wfw:commentRss>http://bougaidenpa.org/masakazu/archives/35/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Primary/Primary 構成の DRBD デバイス上に構築した Cluster Filesystem 上に構築した Xen 準仮想化仮想マシン上の Filesystem Benchmark</title>
		<link>http://bougaidenpa.org/masakazu/archives/34</link>
		<comments>http://bougaidenpa.org/masakazu/archives/34#comments</comments>
		<pubDate>Sun, 24 Feb 2008 14:18:48 +0000</pubDate>
		<dc:creator>masakazu</dc:creator>
				<category><![CDATA[OS]]></category>

		<guid isPermaLink="false">http://bougaidenpa.org/masakazu/?p=34</guid>
		<description><![CDATA[<p>
以下の環境で iozone による Benchmark を実施してみました。
</p>

/dev/sdb1 上に作成した Ext3 Filesystem
/dev/drbd0 上に作成した Ext3 Filesystem
/dev/drbd0 上に作成した OCFS2 Filesystem
/dev/drbd0 上に作成した GFS Filesystem
/dev/sdb1 上に作成した Ext3 Filesystem 上に作成したファイルを Disk Image として構築した Xen 準仮想化仮想マシン上に作成した Ext3 Filesystem
/dev/drbd0 上に作成した Ext3 Filesystem 上に作成したファイルを Disk Image として構築した Xen 準仮想化仮想マシン上に作成した Ext3 Filesystem
/dev/drbd0 上に作成した OCFS2 Filesystem 上に作成したファイルを Disk Image として構築した Xen 準仮想化仮想マシン上に作成した Ext3 Filesystem
/dev/drbd0 上に作成した GFS Filesystem 上に作成したファイルを Disk Image [...]]]></description>
			<content:encoded><![CDATA[<p>
以下の環境で <a href="http://www.iozone.org/">iozone</a> による Benchmark を実施してみました。
</p>
<ul>
<li>/dev/sdb1 上に作成した Ext3 Filesystem</li>
<li>/dev/drbd0 上に作成した Ext3 Filesystem</li>
<li>/dev/drbd0 上に作成した OCFS2 Filesystem</li>
<li>/dev/drbd0 上に作成した GFS Filesystem</li>
<li>/dev/sdb1 上に作成した Ext3 Filesystem 上に作成したファイルを Disk Image として構築した Xen 準仮想化仮想マシン上に作成した Ext3 Filesystem</li>
<li>/dev/drbd0 上に作成した Ext3 Filesystem 上に作成したファイルを Disk Image として構築した Xen 準仮想化仮想マシン上に作成した Ext3 Filesystem</li>
<li>/dev/drbd0 上に作成した OCFS2 Filesystem 上に作成したファイルを Disk Image として構築した Xen 準仮想化仮想マシン上に作成した Ext3 Filesystem</li>
<li>/dev/drbd0 上に作成した GFS Filesystem 上に作成したファイルを Disk Image として構築した Xen 準仮想化仮想マシン上に作成した Ext3 Filesystem</li>
</ul>
<p>
Benchmark 実行環境は以下の通り。
</p>
<table>
<tr>
<td>CPU</td>
<td>Intel(R) Pentium(R) D CPU 3.00GHz</td>
</tr>
<tr>
<td>メモリ</td>
<td>2GB(ただし Dom0 に 512MB のみ割り当て)</td>
</tr>
<tr>
<td>ディスク</td>
<td>FUJITSU MAX3073RC(容量:73.5GB/回転数:15000rpm/SAS 3Gbps)</td>
</tr>
<tr>
<td>NIC</td>
<td>Broadcom NetXtreme BCM5721 Gigabit Ethernet PCI Express</td>
</tr>
</table>
<p>
DRBD でミラー先として用いた環境は以下の通り。
</p>
<table>
<tr>
<td>CPU</td>
<td>Intel(R) Celeron(R) CPU 3.06GHz</td>
</tr>
<tr>
<td>メモリ</td>
<td>1GB(ただし Dom0 に 512MB のみ割り当て)</td>
</tr>
<tr>
<td>ディスク</td>
<td>FUJITSU MAX3073RC(容量:73.5GB/回転数:15000rpm/SAS 3Gbps)</td>
</tr>
<tr>
<td>NIC</td>
<td>Broadcom NetXtreme BCM5721 Gigabit Ethernet PCI Express</td>
</tr>
</table>
<p>
結果は以下の通り。念のため 3 回実行した平均値を求めています。
</p>
<ul>
<li><a href="http://jinkakunashi.com/~masakazu/fs16mb.htm">16MB のファイルを 4kB から 16MB までのレコードサイズで読み書きした際の結果</a></li>
<li><a href="http://jinkakunashi.com/~masakazu/fs512mb.htm">512MB のファイルを 4kB から 16MB までのレコードサイズで読み書きした際の結果</a></li>
<li><a href="http://jinkakunashi.com/~masakazu/rs128mb.htm">レコードサイズを 128kB 固定にして 128kB から 512MB までのサイズのファイルを読み書きした際の結果</a></li>
<li><a href="http://jinkakunashi.com/~masakazu/result.xls">上記結果を格納した Excel ファイル</a></li>
</ul>
<p>
書き込み系の処理ではなぜか OCFS2/GFS の方がローカルディスクの Ext3 よりもスループットが高いことになってしまいました。なんでこんな結果になるのか理解できません。ひょっとしてライトバックでもしている？
</p>
<p>
あと Xen 上の Filesystem が全然遅くなっていない。本当か？
</p>
<p>
Xen の仮想マシン上はもっと性能が悪いのかと思っていたけど実際にはなかなかよさげです。</p>
]]></content:encoded>
			<wfw:commentRss>http://bougaidenpa.org/masakazu/archives/34/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Catalyst::Manual::Tutorial:: Intro &#8211; Catalyst Tutorial &#8211; Part 1: Introduction [対訳]</title>
		<link>http://bougaidenpa.org/masakazu/archives/33</link>
		<comments>http://bougaidenpa.org/masakazu/archives/33#comments</comments>
		<pubDate>Sat, 19 Jan 2008 11:33:24 +0000</pubDate>
		<dc:creator>masakazu</dc:creator>
				<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://bougaidenpa.org/masakazu/?p=33</guid>
		<description><![CDATA[<p>Catalyst::Manual::Tutorial::Intro &#8211; Catalyst Tutorial &#8211; Part 1: Introduction の対訳。2008/01/18 時点での最新版 Catalyst-Manual-5.701003.tar.gz を元にしています。</p>
<p>誤訳がありましたらコメントにてご指摘ください。</p>
NAME</p>
<p>名前
<p>Catalyst::Manual::Tutorial::Intro &#8211; Catalyst Tutorial &#8211; Part 1: Introduction</p>
<p>Catalyst::Manual::Tutorial::Intro &#8211; Catalyst チュートリアル &#8211; 第一部: 導入</p>
OVERVIEW</p>
<p>概要
<p>This is Part 1 of 9 of the Catalyst Tutorial.</p>
<p>9 つある Catalyst チュートリアルのうちの 1 つめです。</p>
<p>Tutorial Overview</p>
<p>チュートリアルの概要</p>

Introduction
導入
Catalyst Basics
Catalyst の基礎
Basic CRUD
基礎的な CRUD
Authentication
認証
Authorization
承認
Debugging
デバッグ
Testing
テスト
Advanced CRUD
高度な CRUD
Appendices
補遺

DESCRIPTION</p>
<p>説明
<p>This tutorial provides a multipart introduction to the Catalyst web framework. [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://search.cpan.org/~jrockway/Catalyst-Manual-5.701003/lib/Catalyst/Manual/Tutorial/Intro.pod">Catalyst::Manual::Tutorial::Intro &#8211; Catalyst Tutorial &#8211; Part 1: Introduction</a> の対訳。2008/01/18 時点での最新版 Catalyst-Manual-5.701003.tar.gz を元にしています。</p>
<p>誤訳がありましたらコメントにてご指摘ください。</p>
<div class="myh">NAME</p>
<p><span class="trans">名前</span></div>
<p>Catalyst::Manual::Tutorial::Intro &#8211; Catalyst Tutorial &#8211; Part 1: Introduction</p>
<p><span class="trans">Catalyst::Manual::Tutorial::Intro &#8211; Catalyst チュートリアル &#8211; 第一部: 導入</span></p>
<div class="myh">OVERVIEW</p>
<p><span class="trans">概要</span></div>
<p>This is Part 1 of 9 of the Catalyst Tutorial.</p>
<p><span class="trans">9 つある Catalyst チュートリアルのうちの 1 つめです。</span></p>
<p><a href="http://bougaidenpa.org/masakazu/entry/catalyst_manual_tutorial">Tutorial Overview</p>
<p><span class="trans">チュートリアルの概要</span></a></p>
<ol>
<li>Introduction<br />
<span class="trans">導入</span></li>
<li><a>Catalyst Basics<br />
<span class="trans">Catalyst の基礎</span></a></li>
<li><a>Basic CRUD<br />
<span class="trans">基礎的な CRUD</span></a></li>
<li><a>Authentication<br />
<span class="trans">認証</span></a></li>
<li><a>Authorization<br />
<span class="trans">承認</span></a></li>
<li><a>Debugging<br />
<span class="trans">デバッグ</span></a></li>
<li><a>Testing<br />
<span class="trans">テスト</span></a></li>
<li><a>Advanced CRUD<br />
<span class="trans">高度な CRUD</span></a></li>
<li><a>Appendices<br />
<span class="trans">補遺</span></a></li>
</ol>
<div class="myh">DESCRIPTION</p>
<p><span class="trans">説明</span></div>
<p>This tutorial provides a multipart introduction to the Catalyst web framework. It seeks to provide a rapid overview of many of its most commonly used features. The focus is on the real-world best practices required in the construction of nearly all Catalyst applications.</p>
<p><span class="trans">このチュートリアルは Catalyst web フレームワークへの複合的な導入を提供します。最もよく利用されるたくさんの機能の概要を素早く提供しようと努めます。ほぼすべての Catalyst アプリケーションの構築で必要とされる実用的な良い慣例に焦点を合わせます。</span></p>
<p>Although the primary target of the tutorial is users new to the Catalyst framework, experienced users may wish to review specific sections (for example, how to use DBIC for their model classes or how to add authentication and authorization to an existing application).</p>
<p><span class="trans">このチュートリアルの第一ターゲットは Catalyst フレームワークを初めて使うユーザですが、経験者もいくつかのセクションを再考したいと考えるかもしれません(たとえば、自分のモデルクラスで DBIC を使う方法だとか、すでに存在するアプリケーションに認証と承認を加える方法など)。</span></p>
<p>You can obtain the code for all the tutorial examples from the catalyst subversion repository by issuing the command:</p>
<p><span class="trans">以下のコマンドを実行することでこのチュートリアルの例すべてのコードを Catalyst の Subversion リポジトリから取得することができます:</span></p>
<pre class="console">svn co http://dev.catalyst.perl.org/repos/Catalyst/tags/examples/Tutorial/MyApp/5.7/ CatalystTutorial</pre>
<p>This will download the current code for each tutorial chapter in the CatalystTutorial directory. Each example application directory has the same name as the tutorial chapter.</p>
<p><span class="trans">このコマンドを実行すると CatalystTutorial というディレクトリに各チュートリアルの章ごとの最新のコードがダウンロードされます。それぞれのサンプルアプリケーションディレクトリはチュートリアルの章と同じ名前になっています。</span></p>
<p>These reference implementations are provided so that when you follow the tutorial, you can use the code from the subversion repository to ensure that your system is set up correctly, and that you have not inadvertently made any typographic errors, or accidentally skipped part of the tutorial.</p>
<p><span class="trans">これらの参照実装はチュートリアルを追いかけていく為に提供されているので、 Subversion リポジトリから得たコードによりあなたのシステムが正しくセットアップされているかを確認でますし、うっかり文字の打ち間違いによるエラーを起こすことも、チュートリアルを一部読み飛ばしてしまうというアクシデントも起こりません。</span></p>
<p>Additionally, if you&#8217;re reading this manual online, you can download the example program and all the necessary dependencies to your local machine by installing the Task::Catalyst::Tutorial distribution from CPAN:</p>
<p><span class="trans">加えて、もしこのマニュアルをオンラインで読んでいるのであれば、 Task::Catalyst::Tutorial ディストリビューションを CPAN からインストールすることでサンプルプログラムとあなたのローカルマシンで必要となるすべての依存するものをダウンロードすることができます:</span></p>
<pre class="console">cpan Task::Catalyst::Tutorial</pre>
<p>This will also test to make sure the dependencies are working. If you have trouble installing these, please ask for help on the #catalyst IRC channel, or the Catalyst mailing list.</p>
<p><span class="trans">このコマンドでは依存するものがちゃんと動いているかも確認してくれます。もしこれらのインストールで問題があったなら、 IRC の #catalyst チャネルか Catalyst メーリングリストに助けを求めてください。</span></p>
<p>Subjects covered include:</p>
<p><span class="trans">ここでふれる話題は以下の通りです:</span></p>
<ul>
<li>A simple application that lists and adds books.
<p><span class="trans">本を表示したり加えたりする単純なアプリケーション。</span></li>
<li>The use of DBIx::Class (DBIC) for the model.
<p><span class="trans">モデルのためにDBIx::Class(DBIC) を使う。</span></li>
<li>How to write CRUD (Create, Read, Update, and Delete) operations in Catalyst.
<p><span class="trans">Catalyst で CRUD(Create, Read, Update,と Delete) を書くための方法。</span></li>
<li>Authentication (&#8220;auth&#8221;).
<p><span class="trans">認証(&#8220;auth&#8221;)。</span></li>
<li>Role-based authorization (&#8220;authz&#8221;).
<p><span class="trans">ロールによる承認(&#8220;authz&#8221;)。</span></li>
<li>Attempts to provide an example showing current (5.7XXX) Catalyst practices. For example, the use of Catalyst::Action::RenderView, DBIC, Catalyst::Plugin::ConfigLoader with myapp.yml, the use of lib/MyApp/Controller/Root.pm vs. lib/MyApp.pm, etc.
<p><span class="trans">Catalyst の最新(5.7XXX) の機能を見せるためのサンプルを提供することを試みる。例えば、 Catalyst::Action::RenderView の使い方、 DBIC、 Catalyst::Plugin::ConfigLoader と myapp.yml、 lib/MyApp/Controller/Root.pm 対 lib/MyApp.pm の使い方、など。</span></li>
<li>The use of Template Toolkit (TT) and the Catalyst::Helper::View::TTSite view helper.
<p><span class="trans">Template Toolkit(TT) と Catalyst::Helper::View::TTSite ビューヘルパーの使い方。</span></li>
<li>Useful techniques for troubleshooting and debugging Catalyst applications.
<p><span class="trans">Catalyst アプリケーションでのトラブルシューティングとデバッグに役立つテクニック。</span></li>
<li>The use of SQLite as a database (with code also provided for MySQL and PostgreSQL).
<p><span class="trans">SQLite をデータベースとして使う方法(MySQL と PostgreSQL も同じように提供)。</span></li>
<li>The use of HTML::Widget for automated form processing and validation.
<p><span class="trans">自動 FORM 処理と値検査のための HTML::Widget の使い方。</span></li>
</ul>
<p>This tutorial makes the learning process its main priority. For example, the level of comments in the code found here would likely be considered excessive in a &#8220;normal project&#8221;. Because of their contextual value, this tutorial will generally favor inline comments over a separate discussion in the text. It also deliberately tries to demonstrate multiple approaches to various features (in general, you should try to be as consistent as possible with your own production code).</p>
<p><span class="trans">このチュートリアルでは学ぶプロセスを確立することを第一優先としています。例えば、コードの中には “普通のプロジェクト” からみたら過度なレベルのコメントが見られます。文脈上の価値のために、このチュートリアルでは一般にテキストで議論を分断するよりもインラインコメントの方を好むからです。またさまざまな機能に対して意図的に複数のアプローチのしかたを試みることもあります(一般には、あなたのプロジェクトのコードではできるだけ一貫性をもたせるようにすべきです)。</span></p>
<p>Furthermore, this tutorial tries to minimize the number of controllers, models, TT templates, and database tables. Although this does result in things being a bit contrived at times, the concepts should be applicable to more complex environments. More complete and complicated example applications can be found in the examples area of the Catalyst Subversion repository at http://dev.catalyst.perl.org/repos/Catalyst/trunk/examples/.</p>
<p><span class="trans">さらに、このチュートリアルではコントローラ、モデル、 TT テンプレート、そしてデータベースを最小限とするよう努めています。より複雑な環境へ適用できるようにというコンセプトによる意図的な結果です。より完全で複雑なサンプルアプリケーションは http://dev.catalyst.perl.org/repos/Catalyst/trunk/examples/ にある Catalyst Subversion リポジトリの examples エリアにあります。</span></p>
<p>Note: There are a variety of other introductory materials available through the Catalyst web site and at http://dev.catalyst.perl.org/wiki/UserIntroductions and http://dev.catalyst.perl.org/.</p>
<p><span class="trans">ノート: ほかにもさまざまな紹介的なものが Catalyst の Web サイトと http://dev.catalyst.perl.org/wiki/UserIntroductions と http://dev.catalyst.perl.org/ を通じて手に入れることができます。</span></p>
<div class="myh">VERSIONS AND CONVENTIONS USED IN THIS TUTORIAL</p>
<p><span class="trans">このチュートリアルで用いられるバージョンと慣例</span></div>
<p>This tutorial was built using the following resources. Please note that you may need to make adjustments for different environments and versions:</p>
<p><span class="trans">このチュートリアルは以下のリソースを用いて構築されています。違う環境やバージョンではどこか調整しなければならなくなるかもしれないことに注意してください:</span></p>
<ul>
<li>OS = CentOS 4 Linux (RHEL 4)
<p><span class="trans">OS = CentOS 4 Linux (RHEL 4)</span></li>
<li>Catalyst v5.7
<p><span class="trans">Catalyst v5.7</span></li>
<li>Catalyst::Devel v1.02
<p><span class="trans">Catalyst::Devel v1.02</span></li>
<li>DBIx::Class v0.06003
<p><span class="trans">DBIx::Class v0.06003</span></li>
<li>Catalyst Plugins &#8211; The plugins used in this tutorial all have sufficiently stable APIs that you shouldn&#8217;t need to worry about versions. However, there could be cases where the tutorial is affected by what version of plugins you use. This tutorial has been tested against the following set of plugins:
<p><span class="trans">Catalyst プラグイン &#8211; このチュートリアルで用いるプラグインはすべて十分に安定している API なのでバージョンに関する心配は必要ありません。しかしながら、あなたが使っているプラグインのバージョンの影響を受けるケースもあるかもしれません。このチュートリアルは以下のプラグインでテストしています。</span></p>
<ul>
<li>Catalyst::Plugin::Authentication &#8212; 0.09
<p><span class="trans">Catalyst::Plugin::Authentication &#8212; 0.09</span></li>
<li>Catalyst::Plugin::Authentication::Store::DBIC &#8212; 0.07
<p><span class="trans">Catalyst::Plugin::Authentication::Store::DBIC &#8212; 0.07</span></li>
<li>Catalyst::Plugin::Authorization::ACL &#8212; 0.08
<p><span class="trans">Catalyst::Plugin::Authorization::ACL &#8212; 0.08</span></li>
<li>Catalyst::Plugin::Authorization::Roles &#8212; 0.04
<p><span class="trans">Catalyst::Plugin::Authorization::Roles &#8212; 0.04</span></li>
<li>Catalyst::Plugin::ConfigLoader &#8212; 0.13
<p><span class="trans">Catalyst::Plugin::ConfigLoader &#8212; 0.13</span></li>
<li>Catalyst::Plugin::HTML::Widget &#8212; 1.1
<p><span class="trans">Catalyst::Plugin::HTML::Widget &#8212; 1.1</span></li>
<li>Catalyst::Plugin::Session &#8212; 0.12
<p><span class="trans">Catalyst::Plugin::Session &#8212; 0.12</span></li>
<li>Catalyst::Plugin::Session::State::Cookie &#8212; 0.05
<p><span class="trans">Catalyst::Plugin::Session::State::Cookie &#8212; 0.05</span></li>
<li>Catalyst::Plugin::Session::Store::FastMmap &#8212; 0.02
<p><span class="trans">Catalyst::Plugin::Session::Store::FastMmap &#8212; 0.02</span></li>
<li>Catalyst::Plugin::StackTrace &#8212; 0.06
<p><span class="trans">Catalyst::Plugin::StackTrace &#8212; 0.06</span></li>
<li>Catalyst::Plugin::Static::Simple &#8212; 0.14
<p><span class="trans">Catalyst::Plugin::Static::Simple &#8212; 0.14</span></li>
</ul>
</li>
<li>Since the web browser is being used on the same box where Perl and the Catalyst development server is running, the URL of http://localhost:3000 will be used (the Catalyst development server defaults to port 3000). If you are running Perl on a different box than where your web browser is located (or using a different port number via the -p port_number option to the development server), then you will need to update the URL you use accordingly.
<p><span class="trans">Perl と Catalyst 開発サーバが動作するのと同じマシンで Web ブラウザを利用するのであれば、 http://localhost:3000 という URL を使います(Catalyst 開発サーバのデフォルトのポートは 3000 です)。もし Web ブラウザを実行しているのと異なるマシンで Perl を実行しているのであれば(もしくは開発サーバで -p port_number オプションにより異なるポート番号を用いているのであれば)、それに応じて URL をアップデートする必要があります。</span></li>
<li>Depending on the web browser you are using, you might need to hit Shift+Reload to pull a fresh page when testing your application at various points. Also, the -k keepalive option to the development server can be necessary with some browsers (especially Internet Explorer).
<p><span class="trans">使っている Web ブラウザによっては、いくつかの点であなたのアプリケーションをテストする際に最新ページを引っ張ってくるためには Shift+Reload を押す必要があるかもしれません。また、いくつかのブラウザ(特に Internet Explorer)では開発サーバで -k keepalive オプションが必要となるかもしれません。</span></li>
</ul>
<div class="myh">CATALYST INSTALLATION</p>
<p><span class="trans">Catalyst のインストール</span></div>
<p>Unfortunately, one of the most daunting tasks faced by newcomers to Catalyst is getting it installed. Although a compelling strength of Catalyst is that it can easily make use of many of the modules in the vast repository that is CPAN, this can result in initial installations that are both time consuming and frustrating. However, there are a growing number of methods that can dramatically ease this undertaking. Of these, the following are likely to be applicable to the largest number of potential new users:</p>
<p><span class="trans">不幸にも、 Catalyst 初心者がもっともよく直面するやる気をなくしてしまう作業の一つがそのインストールです。Although a compelling strength of Catalyst is that it can easily make use of many of the modules in the vast repository that is CPAN, this can result in initial installations that are both time consuming and frustrating. しかしながら、これらを劇的に簡単にしてくれる方法がたくさん存在しています。もちろん、これらの方法は多くの潜在的な新規利用者にも適用できます。</span></p>
<ul>
<li>Matt Trout&#8217;s cat-install &#8211; Available at http://www.shadowcatsystems.co.uk/static/cat-install, cat-install can be a quick and painless way to get Catalyst up and running. Just download the script from the link above and type perl cat-install.
<p><span class="trans">Matt Trout の cat-install &#8211; http://www.shadowcatsystems.co.uk/static/cat-install から入手できる cat-install は Catalyst の入手と実行を素早く苦痛なしに実現する方法です。ただスクリプトを上記リンクからダウンロードし perl cat-install を打ち込むだけでけです。</span></li>
<li>Chris Laco&#8217;s CatInABox &#8211; Download the tarball from http://handelframework.com/downloads/CatInABox.tar.gz and unpack it on your machine. Depending on your OS platform, either run start.bat or start.sh.
<p><span class="trans">Chris Laco の CatInABox &#8211; http://handelframework.com/downloads/CatInABox.tar.gz から Tar アーカイブをダウンロードしあなたのマシンに解凍してください。あなたの OS プラットフォームに依存しますが、 start.bat か start.sh を実行します。</span></li>
<li>Pre-Built VMWare Images &#8211; Under the VMWare community program, work is ongoing to develop a number of VMWare images where an entire Catalyst development environment has already been installed, complete with database engines and a full complement of Catalyst plugins.
<p><span class="trans">Pre-Built VMWare Images &#8211; VMWare コミュニティプログラムの元、いくつかのデータベースエンジンとすべての Catalyst プラグインを含む Catalyst 開発環境があらかじめインストールされた VMWare イメージが継続して開発されています。</span></li>
</ul>
<p>For additional information and recommendations on Catalyst installation, please refer to Catalyst::Manual::Installation.</p>
<p><span class="trans">Catalyst のインストールに関する追加の情報とおすすめは Catalyst::Manual::Installation を参照してください。</span></p>
<p>NOTE: Step-by-step instructions to replicate the environment on which this tutorial was developed can be found at Catalyst::Manual::Installation::CentOS4. Using these instructions, you should be able to build a complete CentOS 4.X server with Catalyst and all the plugins required to run this tutorial.</p>
<p><span class="trans">ノート: このチュートリアルを開発した環境を複製するためのステップバイステップ手順は Catalyst::Manual::Installation::CentOS4 にあります。これらの手順を使えば、このチュートリアルを実行するために必要となる Catalyst とすべてのプラグインがそろった完全な CentOS 4.x サーバを構築することができます。</span></p>
<div class="myh">DATABASES</p>
<p><span class="trans">データベース</span></div>
<p>This tutorial will primarily focus on SQLite because of its simplicity of installation and use; however, modifications in the script required to support MySQL and PostgreSQL will be presented in Appendix 2.</p>
<p><span class="trans">このチュートリアルではインストールと利用が簡単な SQLite に焦点を当てます。が、 MySQL と PostgreSQL をサポートするために必要となるスクリプトの変更について補遺 2 で紹介します。</span></p>
<p>Note: One of the advantages of the MVC design patterns is that applications become much more database independent. As such, you will notice that only the .sql files used to initialize the database change between database systems: the Catalyst code generally remains the same.</p>
<p><span class="trans">ノート: MVC デザインパターンのひとつの利点はアプリケーションがデータベースに依存しなくなることです。そのため、 .sql ファイルはデータベース間をまたがるデータベース変更のときのみ用いられることに注意してください: Catalyst コードは同じままです。</span></p>
<div class="myh">WHERE TO GET WORKING CODE</p>
<p><span class="trans">動いているコードがある場所</span></div>
<p>Each part of the tutorial has complete code available in the main Catalyst Subversion repository (see the note at the beginning of each part for the appropriate svn command to use). Additionally, the final code is available as a ready-to-run tarball at http://dev.catalyst.perl.org/repos/Catalyst/trunk/examples/Tutorial/Final_Tarball/MyApp.tgz.</p>
<p><span class="trans">チュートリアルのそれぞれの部分はメインの Catalyst Subversion リポジトリ(実行すべき svn コマンドはそれぞれの部の冒頭にあるノートをみてください)から得られる完全なコードを持っています。加えて、実行可能な最終コードの Tar アーカイブが http://dev.catalyst.perl.org/repos/Catalyst/trunk/examples/Tutorial/Final_Tarball/MyApp.tgz にあります。</span></p>
<p>NOTE: You can run the test cases for the final code with the following commands:</p>
<p><span class="trans">ノート: 次のコマンドにより最終コードのテストケースを実行することができます:</span></p>
<pre class="console">wget http://dev.catalyst.perl.org/repos/Catalyst/trunk/examples/Tutorial/Final_Tarball/MyApp.tgz
tar zxvf MyApp.tgz
cd MyApp
CATALYST_DEBUG=0 prove --lib lib  t</pre>
<div class="myh">AUTHOR</p>
<p><span class="trans">著者</span></div>
<p>Kennedy Clark, hkclark [a] gmail.com</p>
<p><span class="trans">Kennedy Clark, hkclark [a] gmail.com</span></p>
<p>Please report any errors, issues or suggestions to the author. The most recent version of the Catalyst Tutorial can be found at http://dev.catalyst.perl.org/repos/Catalyst/trunk/Catalyst-Manual/lib/Catalyst/Manual/Tutorial/.</p>
<p><span class="trans">Please report any errors, issues or suggestions to the author. The most recent version of the Catalyst Tutorial can be found at http://dev.catalyst.perl.org/repos/Catalyst/trunk/Catalyst-Manual/lib/Catalyst/Manual/Tutorial/.</span></p>
<p>Copyright 2006, Kennedy Clark, under Creative Commons License (http://creativecommons.org/licenses/by-nc-sa/2.5/).</p>
<p><span class="trans">Copyright 2006, Kennedy Clark, under Creative Commons License (http://creativecommons.org/licenses/by-nc-sa/2.5/).</span></p>
]]></content:encoded>
			<wfw:commentRss>http://bougaidenpa.org/masakazu/archives/33/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Catalyst::Manual::Tutorial &#8211; Catalyst Tutorial: Overview [対訳]</title>
		<link>http://bougaidenpa.org/masakazu/archives/32</link>
		<comments>http://bougaidenpa.org/masakazu/archives/32#comments</comments>
		<pubDate>Thu, 17 Jan 2008 16:25:34 +0000</pubDate>
		<dc:creator>masakazu</dc:creator>
				<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://bougaidenpa.org/masakazu/?p=32</guid>
		<description><![CDATA[<p>
Catalyst::Manual::Tutorial &#8211; Catalyst Tutorial: Overview の対訳。2008/01/18 時点での最新版 Catalyst-Manual-5.701003.tar.gz を元にしています。
</p>
<p>
このページは目次ばっかりでつまんないのでとりあえず後回しにします。
</p>
<p>
誤訳がありましたらコメントにてご指摘ください。
</p>
NAME
名前

<p>
Catalyst::Manual::Tutorial &#8211; Catalyst Tutorial: Overview
Catalyst::Manual::Tutorial &#8211; Catalyst チュートリアル: 概要
</p>
DESCRIPTION
説明

<p>
The Catalyst framework is a flexible and comprehensive environment for quickly building high-functionality web applications. This tutorial is designed to provide a rapid introduction to its basics and its most commonly used features while focusing on real-world best practices.
Catalyst フレームワークは、素早く高機能な [...]]]></description>
			<content:encoded><![CDATA[<p>
<a href="http://search.cpan.org/~jrockway/Catalyst-Manual-5.701003/lib/Catalyst/Manual/Tutorial.pod">Catalyst::Manual::Tutorial &#8211; Catalyst Tutorial: Overview</a> の対訳。2008/01/18 時点での最新版 Catalyst-Manual-5.701003.tar.gz を元にしています。
</p>
<p>
このページは目次ばっかりでつまんないのでとりあえず後回しにします。
</p>
<p>
誤訳がありましたらコメントにてご指摘ください。
</p>
<div class="myh">NAME<br/><br />
<span class="trans">名前</span>
</div>
<p>
Catalyst::Manual::Tutorial &#8211; Catalyst Tutorial: Overview<br/><br />
<span class="trans">Catalyst::Manual::Tutorial &#8211; Catalyst チュートリアル: 概要</span>
</p>
<div class="myh">DESCRIPTION<br/><br />
<span class="trans">説明</span>
</div>
<p>
The Catalyst framework is a flexible and comprehensive environment for quickly building high-functionality web applications. This tutorial is designed to provide a rapid introduction to its basics and its most commonly used features while focusing on real-world best practices.<br/><br />
<span class="trans">Catalyst フレームワークは、素早く高機能な Web アプリケーションを構築するための、柔軟で包括的な環境です。このチュートリアルは、実世界で用いられているよい慣例に焦点を当て、その基礎とよく共通して用いられる機能を足早に紹介するために作られています。</span>
</p>
<p>
The tutorial is divided into the following sections:<br/><br />
<span class="trans">このチュートリアルは以下のセクションに分かれています:</span>
</p>
<p>
NOTE: CLICK THESE LINKS TO JUMP TO CHAPTERS (the index links above only navigate inside this page).<br/><br />
<span class="trans">ノート: これらのリンクをクリックすることで対応する各章へ移動することができます(以下のインデックスリンクはこのページ内でのナビゲートしかしてくれません)。</span>
</p>
<ul>
<li><a href="">Introduction<br/>導入</a></li>
<li><a href="">Catalyst Basics<br/>Catalyst の基礎</a></li>
<li><a href="">Basic CRUD<br/>基礎的な CRUD</a></li>
<li><a href="">Authentication<br/>認証</a></li>
<li><a href="">Authorization<br/>承認</a></li>
<li><a href="">Debugging<br/>デバッグ</a></li>
<li><a href="">Testing<br/>テスト</a></li>
<li><a href="">Advanced CRUD<br/>高度な CRUD</a></li>
<li><a href="">Appendices<br/>補遺</a></li>
</ul>
<p>A tarball of the final application is available at <a href="http://dev.catalyst.perl.org/repos/Catalyst/trunk/examples/Tutorial/Final_Tarball/MyApp.tgz">http://dev.catalyst.perl.org/repos/Catalyst/trunk/examples/Tutorial/Final_Tarball/MyApp.tgz</a>.<br/><br />
<span class="trans">最終的なアプリケーションを tar で固めたものが <a href="http://dev.catalyst.perl.org/repos/Catalyst/trunk/examples/Tutorial/Final_Tarball/MyApp.tgz">http://dev.catalyst.perl.org/repos/Catalyst/trunk/examples/Tutorial/Final_Tarball/MyApp.tgz</a> にあります。</span>
</p>
<div class="myh">Detailed Table of Contents<br/><br />
<span class="trans">詳しい目次</span>
</div>
<p/>
<div class="myh">Part 1: Introduction<br/><br />
<span class="trans">第一部: 導入</span>
</div>
<ul>
<li>VERSIONS AND CONVENTIONS USED IN THIS TUTORIAL<br/><br />
<span class="trans">このチュートリアルで用いられるバージョンと慣例</span></li>
<li>CATALYST INSTALLATION<br/><br />
<span class="trans">Catalyst のインストール</span></li>
<li>DATABASES<br/><br />
<span class="trans">データベース</span></li>
<li>WHERE TO GET WORKING CODE<br/><br />
<span class="trans">動いているコードがある場所</span></li>
</ul>
<div class="myh">Part 2: Catalyst Basics<br/><br />
<span class="trans">第二部: Catalyst の基礎</span>
</div>
<ul>
<li>CREATE A CATALYST PROJECT<br/><br />
<span class="trans">Catalyst プロジェクトを作る</span></li>
<li>CREATE A SQLITE DATABASE<br/><br />
<span class="trans">SQLite データベースを作る</span></li>
<li>EDIT THE LIST OF CATALYST PLUGINS<br/><br />
<span class="trans">Catalyst プラグインのリストを編集する</span></li>
<li>DATABASE ACCESS WITH DBIx::Class<br/><br />
<span class="trans">DBIx::Class をつかってデータベースへアクセスする</span></p>
<ul>
<li>Create a DBIC Schema File<br/><br />
<span class="trans">DBIC スキーマファイルの作成</span></li>
<li>Create the DBIC &#8220;Result Source&#8221; Files<br/><br />
<span class="trans">DBIC &#8220;Result Source&#8221; ファイルの作成</span></li>
<li>Use Catalyst::Model::DBIC::Schema to Load the Model Class<br/><br />
<span class="trans">Catalyst::Model::DBIC::Schema を使ってモデルクラスの読み込み</span></li>
</ul>
</li>
<li>CREATE A CATALYST CONTROLLER<br/><br />
<span class="trans">Catalyst コントローラを作る</span></li>
<li>CATALYST VIEWS<br/><br />
<span class="trans">Catalyst ビュー</span></p>
<ul>
<li>Create a Catalyst View Using TTSite<br/><br />
<span class="trans">TTSite を利用した Catalyst ビューの作成</span></li>
<li>Using RenderView for the Default View<br/><br />
<span class="trans">RenderView を利用したデフォルトビュー</span></li>
<li>Globally Customize Every View<br/><br />
<span class="trans">すべてのビューへの大域的なカスタマイズ</span></li>
<li>Create a TT Template Page<br/><br />
<span class="trans">TT テンプレートページの作成</span></li>
</ul>
</li>
<li>RUN THE APPLICATION<br/><br />
<span class="trans">アプリケーションを実行する</span></li>
<li>USING THE DEFAULT TEMPLATE NAME<br/><br />
<span class="trans">デフォルトのテンプレート名を使う</span></li>
</ul>
<div class="myh">Part 3: Basic CRUD<br/><br />
<span class="trans">第三部: CRUD の基礎</span>
</div>
<ul>
<li>FORMLESS SUBMISSION<br/><br />
<span class="trans">FORM を用いない SUBMIT 処理</span></p>
<ul>
<li>Include a Create Action in the Books Controller<br/><br />
<span class="trans">Book コントローラへクリエイトアクションを組み込む</span></li>
<li>Include a Template for the url_create Action:<br/><br />
<span class="trans">url_create アクションへテンプレートを組み込む</span></li>
<li>Try the url_create Feature<br/><br />
<span class="trans">url_create 機能を試す</span></li>
</ul>
</li>
<li>MANUALLY BUILDING A CREATE FORM<br/><br />
<span class="trans">手動でクリエイトフォームを構築する</span></p>
<ul>
<li>Add a Method to Display the Form<br/><br />
<span class="trans">フォームを表示するメソッドを追加する</span></li>
<li>Add a Template for the Form<br/><br />
<span class="trans">フォームにテンプレートを追加する</span></li>
<li>Add Method to Process Form Values and Update Database<br/><br />
<span class="trans">フォーム変数を処理するメソッドとデータベースを更新するメソッドを追加する</span></li>
<li>Test Out the Form<br/><br />
<span class="trans">フォームをテストする</span></li>
</ul>
</li>
<li>A SIMPLE DELETE FEATURE<br/><br />
<span class="trans">単純な削除機能</span></p>
<ul>
<li>Include a Delete Link in the List<br/><br />
<span class="trans">リストにリンクを削除を組み込む</span></li>
<li>Add a Delete Action to the Controller<br/><br />
<span class="trans">コントローラに削除アクションを加える</span></li>
<li>Try the Delete Feature<br/><br />
<span class="trans">削除機能を試す</span></li>
</ul>
</li>
</ul>
<div class="myh">Part 4: Authentication<br/><br />
<span class="trans">第四部: 認証</span>
</div>
<ul>
<li>BASIC AUTHENTICATION<br/><br />
<span class="trans">基本認証</span></p>
<ul>
<li>Add Users and Roles to the Database<br/><br />
<span class="trans">データベースへユーザとロールを追加する</span></li>
<li>Add User and Role Information to DBIC Schema<br/><br />
<span class="trans">ユーザとロールの情報を DBIC スキーマへ追加する</span></li>
<li>Create New “Result Source Objects”<br/><br />
<span class="trans">新しい “Result Source Objects” を作成する</span></li>
<li>Sanity-Check Reload of Development Server<br/><br />
<span class="trans"></span></li>
<li>Include Authentication and Session Plugins<br/><br />
<span class="trans"></span></li>
<li>Configure Authentication<br/><br />
<span class="trans"></span></li>
<li>Add Login and Logout Controllers<br/><br />
<span class="trans"></span></li>
<li>Add a Login Form TT Template Page<br/><br />
<span class="trans"></span></li>
<li>Add Valid User Check<br/><br />
<span class="trans"></span></li>
<li>Displaying Content Only to Authenticated Users<br/><br />
<span class="trans"></span></li>
<li>Try Out Authentication<br/><br />
<span class="trans"></span></li>
</ul>
</li>
<li>USING PASSWORD HASHES<br/><br />
<span class="trans"></span></p>
<ul>
<li>Get a SHA-1 Hash for the Password<br/><br />
<span class="trans"></span></li>
<li>Switch to SHA-1 Password Hashes in the Database<br/><br />
<span class="trans"></span></li>
<li>Enable SHA-1 Hash Passwords in Catalyst::Plugin::Authentication::Store::DBIC<br/><br />
<span class="trans"></span></li>
<li>Try Out the Hashed Passwords<br/><br />
<span class="trans"></span></li>
</ul>
</li>
</ul>
<div class="myh">Part 5: Authorization<br/><br />
<span class="trans">第五部: 承認</span>
</div>
<ul>
<li>BASIC AUTHORIZATION<br/><br />
<span class="trans"></span></p>
<ul>
<li>Update Plugins to Include Support for Authorization<br/><br />
<span class="trans"></span></li>
<li>Add Config Information for Authorization<br/><br />
<span class="trans"></span></li>
<li>Add Role-Specific Logic to the &#8220;Book List&#8221; Template<br/><br />
<span class="trans"></span></li>
<li>Limit Books::add to admin Users<br/><br />
<span class="trans"></span></li>
<li>Try Out Authentication And Authorization<br/><br />
<span class="trans"></span></li>
</ul>
</li>
<li>ENABLE ACL-BASED AUTHORIZATION<br/><br />
<span class="trans"></span></p>
<ul>
<li>Add the Catalyst::Plugin::Authorization::ACL Plugin<br/><br />
<span class="trans"></span></li>
<li>Add ACL Rules to the Application Class<br/><br />
<span class="trans"></span></li>
<li>Add a Method to Handle Access Violations<br/><br />
<span class="trans"></span></li>
</ul>
</li>
</ul>
<div class="myh">Part 6: Debugging<br/><br />
<span class="trans">第六部: デバッグ</span>
</div>
<ul>
<li>LOG STATEMENTS<br/><br />
<span class="trans"></span></li>
<li>RUNNING CATALYST UNDER THE PERL DEBUGGER<br/><br />
<span class="trans"></span></li>
<li>DEBUGGING MODULES FROM CPAN<br/><br />
<span class="trans"></span></li>
</ul>
<div class="myh">Part 7: Testing<br/><br />
<span class="trans">第七部: テスト</span>
</div>
<ul>
<li>RUNNING THE &#8220;CANNED&#8221; CATALYST TESTS<br/><br />
<span class="trans"></span></li>
<li>RUNNING A SINGLE TEST<br/><br />
<span class="trans"></span></li>
<li>ADDING YOUR OWN TEST SCRIPT<br/><br />
<span class="trans"></span></li>
<li>SUPPORTING BOTH PRODUCTION AND TEST DATABASES<br/><br />
<span class="trans"></span></li>
</ul>
<div class="myh">Part 8: Advanced CRUD<br/><br />
<span class="trans">第八部: 高度な CRUD</span>
</div>
<ul>
<li>HTML::WIDGET FORM CREATION<br/><br />
<span class="trans"></span></p>
<ul>
<li>Add the HTML::Widget Plugin<br/><br />
<span class="trans"></span></li>
<li>Add a Form Creation Helper Method<br/><br />
<span class="trans"></span></li>
<li>Add Actions to Display and Save the Form<br/><br />
<span class="trans"></span></li>
<li>Update the CSS<br/><br />
<span class="trans"></span></li>
<li>Create a Template Page To Display The Form<br/><br />
<span class="trans"></span></li>
<li>Add Links for Create and Update via HTML::Widget<br/><br />
<span class="trans"></span></li>
<li>Test The &lt;HTML::Widget&gt; Create Form<br/><br />
<span class="trans"></span></li>
</ul>
</li>
<li>HTML::WIDGET VALIDATION AND FILTERING<br/><br />
<span class="trans"></span></p>
<ul>
<li>Add Constraints and Filters to the Widget Creation Method<br/><br />
<span class="trans"></span></li>
<li>Rebuild the Form Submission Method to Include Validation<br/><br />
<span class="trans"></span></li>
<li>Try Out the Form<br/><br />
<span class="trans"></span></li>
</ul>
</li>
<li>Enable DBIx::Class::HTMLWidget Support<br/><br />
<span class="trans"></span></p>
<ul>
<li>Add DBIx::Class::HTMLWidget to DBIC Model<br/><br />
<span class="trans"></span></li>
<li>Use populate_from_widget in hw_create_do<br/><br />
<span class="trans"></span></li>
</ul>
</li>
</ul>
<div class="myh">Part 9: Appendices<br/><br />
<span class="trans">第九部: 補遺</span>
</div>
<ul>
<li>APPENDIX 1: CUT AND PASTE FOR POD-BASED EXAMPLES<br/><br />
<span class="trans"></span></p>
<ul>
<li>&#8220;Un-indenting&#8221; with Vi/Vim<br/><br />
<span class="trans"></span></li>
<li>&#8220;Un-indenting&#8221; with Emacs<br/><br />
<span class="trans"></span></li>
</ul>
</li>
<li>APPENDIX 2: USING MYSQL AND POSTGRESQL<br/><br />
<span class="trans"></span></p>
<ul>
<li>MySQL<br/><br />
<span class="trans"></span></li>
<li>PostgreSQL<br/><br />
<span class="trans"></span></li>
</ul>
</li>
<li>APPENDIX 3: IMPROVED HASHING SCRIPT<br/><br />
<span class="trans"></span></li>
</ul>
<div class="myh">THANKS<br/><br />
<span class="trans">謝辞</span>
</div>
<p>
<br/><br />
<span class="trans"></span>
</p>
<ul>
<li><br/><br />
<span class="trans"></span></li>
<li><br/><br />
<span class="trans"></span></li>
<li><br/><br />
<span class="trans"></span></li>
<li><br/><br />
<span class="trans"></span></li>
<li><br/><br />
<span class="trans"></span></li>
</ul>
<div class="myh">AUTHOR<br/><br />
<span class="trans">著者</span>
</div>
<p>Kennedy Clark, hkclark [a] gmail.com<br/><br />
<span class="trans">Kennedy Clark, hkclark [a] gmail.com</span>
</p>
<p>Please report any errors, issues or suggestions to the author. The most recent version of the Catalyst Tutorial can be found at http://dev.catalyst.perl.org/repos/Catalyst/trunk/Catalyst-Manual/lib/Catalyst/Manual/Tutorial/.<br/><br />
<span class="trans">Please report any errors, issues or suggestions to the author. The most recent version of the Catalyst Tutorial can be found at http://dev.catalyst.perl.org/repos/Catalyst/trunk/Catalyst-Manual/lib/Catalyst/Manual/Tutorial/.</span>
</p>
<p>Copyright 2006, Kennedy Clark, under Creative Commons License (http://creativecommons.org/licenses/by-nc-sa/2.5/).<br/><br />
<span class="trans">Copyright 2006, Kennedy Clark, under Creative Commons License (http://creativecommons.org/licenses/by-nc-sa/2.5/).</span></p>
]]></content:encoded>
			<wfw:commentRss>http://bougaidenpa.org/masakazu/archives/32/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>プログラミング言語 Erlang 入門</title>
		<link>http://bougaidenpa.org/masakazu/archives/31</link>
		<comments>http://bougaidenpa.org/masakazu/archives/31#comments</comments>
		<pubDate>Thu, 03 Jan 2008 15:49:54 +0000</pubDate>
		<dc:creator>masakazu</dc:creator>
				<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://bougaidenpa.org/masakazu/?p=31</guid>
		<description><![CDATA[<p></p>
<p>
かなり久々の更新。
</p>
<p>
最近何かと話題のプログラミング言語 Erlang の入門書がようやく日本語で読めるように。ということでさっそく読んでみました。
</p>
<p>
Erlang はスウェーデンの通信機器メーカー、エリクソン社が開発した関数型言語です。他の関数型言語にはない大きな特徴として並行処理と分散処理のサポートが上げられます。 Erlang 自体は結構枯れた言語ということですが、この並行処理と分散処理のサポートのおかげで、最近は(ごく一部で？)注目を集めているようです。
</p>
<p>
なぜ並行処理と分散処理がサポートされていることで注目を集めているのか？という疑問に答えるためには、最近になって CPU 開発の方向性が変わってきていることに触れる必要があります。
</p>
<p>
CPU の性能の指標として一番わかりやすいものに“クロックスピード”があります。CPU は、クロックと呼ばれる定期的に発生する時間刻みにしたがいながら命令を実行していきます。一秒間あたりにクロックを何回発生させるかがクロックスピードです。当然、クロックスピードを早くすればその分一秒間あたりに実行できる命令数は多くなるので CPU の性能が上がることになります。つい最近まではこの方法で CPU は性能を向上させてきました。
</p>
<p>
もちろん、いまでもクロックスピードを上げることで性能を向上させよう(させたい？)という基本的な動きに変わりはないのですが、ここにきて様々な技術的制約によりクロックスピードを上げにくいような状況になってしまっているのです。そこで最近の Intel や AMD は、クロックスピードを上げるよりもコア数を増やし並行処理で CPU の性能を強化しようという方針にシフトしているわけです。
</p>
<p>
ところが、たとえば CPU の数を二倍にしたからといって性能も単純に二倍になるかというとそうはいかないわけです。OS や実行するプログラム側で同時に複数の CPU を利用するような工夫がされていなければせっかく二つある CPU も片方しか利用されません。しかしプログラム側でマルチコアを有効活用できるような工夫をするのは結構面倒で&#8230;
</p>
<p>
ということで、並行処理と分散処理を言語の特徴として謳う Erlang ってどうなんだろう、と、実は結構まえから気になっていたのです。
</p>
<p>
そして&#8230; ちょっと魔法のようなモノを期待しちゃってたかもしれません&#8230;
</p>
<p></p>
<p>
読んでみての率直な感想を言うと、“やっぱりお手軽に並行実行可能なプログラムを書くことはできないんだな”と、すこしがっかりしてしまいました。“逐次実行っぽくない”、“状態を持たない”といった聞きかじりの知識による偏見たっぷりの関数型言語への無理解も手伝い、プログラマがまったく意識しなくても並行処理してくれるような凄いモノを想像しちゃっていたので&#8230;
</p>
<p>
並行処理について触れるのは一番最後の章で、フィボナッチ級数を求める関数を並行実行させているんですけど、なんか pthread で実装させるのとたいして変わんないんじゃない？ってくらい並行処理を意識しなきゃならない実装になっているような気がしました。メモリを共有しない(できない？)ことで同期処理について意識する必要がなくなるという特徴についてもうすこし説明が欲しいように感じましたが、それは普通の thread プログラミングの知識を前提しなければ難しいのかもしれません。
</p>
<p>
ただ Erlang という言語を学ぶ本としては割とよくできているように思います。例文もしっかりしていて、はじめて関数型言語に触れるというひとでも読みやすいんじゃないでしょうか。ただ関数型言語の勉強がしたい、というのであれば、個人的には“ふつうのHaskellプログラミング ふつうのプログラマのための関数型言語入門”の方が極端でおすすめですが&#8230;
</p>
<p>
はたしてプログラマがなにも意識せずともマルチコアの恩恵をうけるプログラムが書けるようになる時代は来るのでしょうか。
</p>
<p>
以下は参考です。
</p>

Erlang &#8211; Wikipedia- http://ja.wikipedia.org/wiki/Erlang※ Erlang が具体的なコードを用いながら説明されています。
マルチコア &#8211; Wikipedia- [...]]]></description>
			<content:encoded><![CDATA[<p><iframe src="http://rcm-jp.amazon.co.jp/e/cm?t=ae937b48baa89-22&#038;o=9&#038;p=8&#038;l=as1&#038;asins=4756150705&#038;fc1=000000&#038;IS2=1&#038;lt1=_top&#038;lc1=0000FF&#038;bc1=FFFFFF&#038;bg1=FFFFFF&#038;f=ifr" class="amazonbox" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"></iframe></p>
<p>
かなり久々の更新。
</p>
<p>
最近何かと話題のプログラミング言語 Erlang の入門書がようやく日本語で読めるように。ということでさっそく読んでみました。
</p>
<p>
Erlang はスウェーデンの通信機器メーカー、エリクソン社が開発した関数型言語です。他の関数型言語にはない大きな特徴として並行処理と分散処理のサポートが上げられます。 Erlang 自体は結構枯れた言語ということですが、この並行処理と分散処理のサポートのおかげで、最近は(ごく一部で？)注目を集めているようです。
</p>
<p>
なぜ並行処理と分散処理がサポートされていることで注目を集めているのか？という疑問に答えるためには、最近になって CPU 開発の方向性が変わってきていることに触れる必要があります。
</p>
<p>
CPU の性能の指標として一番わかりやすいものに“クロックスピード”があります。CPU は、クロックと呼ばれる定期的に発生する時間刻みにしたがいながら命令を実行していきます。一秒間あたりにクロックを何回発生させるかがクロックスピードです。当然、クロックスピードを早くすればその分一秒間あたりに実行できる命令数は多くなるので CPU の性能が上がることになります。つい最近まではこの方法で CPU は性能を向上させてきました。
</p>
<p>
もちろん、いまでもクロックスピードを上げることで性能を向上させよう(させたい？)という基本的な動きに変わりはないのですが、ここにきて様々な技術的制約によりクロックスピードを上げにくいような状況になってしまっているのです。そこで最近の Intel や AMD は、クロックスピードを上げるよりもコア数を増やし並行処理で CPU の性能を強化しようという方針にシフトしているわけです。
</p>
<p>
ところが、たとえば CPU の数を二倍にしたからといって性能も単純に二倍になるかというとそうはいかないわけです。OS や実行するプログラム側で同時に複数の CPU を利用するような工夫がされていなければせっかく二つある CPU も片方しか利用されません。しかしプログラム側でマルチコアを有効活用できるような工夫をするのは結構面倒で&#8230;
</p>
<p>
ということで、並行処理と分散処理を言語の特徴として謳う Erlang ってどうなんだろう、と、実は結構まえから気になっていたのです。
</p>
<p>
そして&#8230; ちょっと魔法のようなモノを期待しちゃってたかもしれません&#8230;
</p>
<p><iframe src="http://rcm-jp.amazon.co.jp/e/cm?t=ae937b48baa89-22&#038;o=9&#038;p=8&#038;l=as1&#038;asins=4797336021&#038;fc1=000000&#038;IS2=1&#038;lt1=_top&#038;lc1=0000FF&#038;bc1=FFFFFF&#038;bg1=FFFFFF&#038;f=ifr" class="amazonbox2" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"></iframe></p>
<p>
読んでみての率直な感想を言うと、“やっぱりお手軽に並行実行可能なプログラムを書くことはできないんだな”と、すこしがっかりしてしまいました。“逐次実行っぽくない”、“状態を持たない”といった聞きかじりの知識による偏見たっぷりの関数型言語への無理解も手伝い、プログラマがまったく意識しなくても並行処理してくれるような凄いモノを想像しちゃっていたので&#8230;
</p>
<p>
並行処理について触れるのは一番最後の章で、フィボナッチ級数を求める関数を並行実行させているんですけど、なんか pthread で実装させるのとたいして変わんないんじゃない？ってくらい並行処理を意識しなきゃならない実装になっているような気がしました。メモリを共有しない(できない？)ことで同期処理について意識する必要がなくなるという特徴についてもうすこし説明が欲しいように感じましたが、それは普通の thread プログラミングの知識を前提しなければ難しいのかもしれません。
</p>
<p>
ただ Erlang という言語を学ぶ本としては割とよくできているように思います。例文もしっかりしていて、はじめて関数型言語に触れるというひとでも読みやすいんじゃないでしょうか。ただ関数型言語の勉強がしたい、というのであれば、個人的には<a href="http://www.amazon.co.jp/dp/4797336021?tag=ae937b48baa89-22&#038;camp=243&#038;creative=1615&#038;linkCode=as1&#038;creativeASIN=4797336021&#038;adid=0HE6HSAZJMNVBY6YJPWC&#038;">“ふつうのHaskellプログラミング ふつうのプログラマのための関数型言語入門”</a>の方が極端でおすすめですが&#8230;
</p>
<p>
はたしてプログラマがなにも意識せずともマルチコアの恩恵をうけるプログラムが書けるようになる時代は来るのでしょうか。
</p>
<p>
以下は参考です。
</p>
<ul>
<li><a href="http://ja.wikipedia.org/wiki/Erlang">Erlang &#8211; Wikipedia<br />- http://ja.wikipedia.org/wiki/Erlang</a><br />※ Erlang が具体的なコードを用いながら説明されています。</li>
<li><a href="http://ja.wikipedia.org/wiki/%E3%83%9E%E3%83%AB%E3%83%81%E3%82%B3%E3%82%A2">マルチコア &#8211; Wikipedia<br />- http://ja.wikipedia.org/wiki/%E3%83%9E%E3%83%AB%E3%83%81%E3%82%B3%E3%82%A2</a><br />※ クロックスピードを上げにくくなっている技術的背景が詳しく説明されている。</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://bougaidenpa.org/masakazu/archives/31/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>めがね</title>
		<link>http://bougaidenpa.org/masakazu/archives/30</link>
		<comments>http://bougaidenpa.org/masakazu/archives/30#comments</comments>
		<pubDate>Sun, 23 Sep 2007 18:22:04 +0000</pubDate>
		<dc:creator>masakazu</dc:creator>
				<category><![CDATA[Movie]]></category>

		<guid isPermaLink="false">http://bougaidenpa.org/masakazu/?p=30</guid>
		<description><![CDATA[[...]]]></description>
			<content:encoded><![CDATA[<p>
最近たそがれてないなぁ。<br />
もしハマダが実在するなら、僕は絶対行くね。<br />
才能ある自信あるし。<br />
そこにいる才能。
</p>
<p>
ていうか市川実日子の存在感が絶妙すぎる。<br />
劇中何度か出てくる「死にたい。」と吐く場面が特に素晴らしい。<br />
このこやばいかも。
</p>
<p>
こういう日本映画、僕は大好きです。<br />
ていうか「こういうの意味わかんない」とかいうひととはうまくやっていける気がしない。<br />
それくらい。
</p>
<ul>
<li><a href="http://www.megane-movie.com/">映画「めがね」公式サイト<br />- http://www.megane-movie.com/</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://bougaidenpa.org/masakazu/archives/30/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>DRBD &amp; Heartbeat &#8211; takeover/failback verification</title>
		<link>http://bougaidenpa.org/masakazu/archives/29</link>
		<comments>http://bougaidenpa.org/masakazu/archives/29#comments</comments>
		<pubDate>Wed, 12 Sep 2007 15:57:12 +0000</pubDate>
		<dc:creator>masakazu</dc:creator>
				<category><![CDATA[OS]]></category>

		<guid isPermaLink="false">http://bougaidenpa.org/masakazu/?p=29</guid>
		<description><![CDATA[<p>
DRBD 上の ext3 filesystem を Heartbeat 配下に設定し、 Primary を落としたときと、落としてからあげたときの syslog。
</p>
<p>
何が起きているのかさっぱりですが、時間を作って追っかけたいと思います。
</p>
<p>
とりあえず、 Primary で mount されてた /var/lib/mysql という directory は、 Primary の shutdown 後、ちゃんと Secondary で mount されました。そして落とした Primary の復旧後、ちゃんと Secondary から Primary に戻りました。
</p>
<p>
以下の document が参考になるかも。
</p>

DRBD &#8211; Integrating with Heartbeat V1 [対訳]- http://bougaidenpa.org/masakazu/entry/drbd_integrating_with_heartbeat_v1

<p>
以下は設定。
</p>

FILE: /etc/drbd.conf
--
resource r0 {
protocol C;
incon-degr-cmd &#34;echo '!DRBD! pri on incon-degr' &#124; wall ; sleep 60 ; [...]]]></description>
			<content:encoded><![CDATA[<p>
DRBD 上の ext3 filesystem を Heartbeat 配下に設定し、 Primary を落としたときと、落としてからあげたときの syslog。
</p>
<p>
何が起きているのかさっぱりですが、時間を作って追っかけたいと思います。
</p>
<p>
とりあえず、 Primary で mount されてた /var/lib/mysql という directory は、 Primary の shutdown 後、ちゃんと Secondary で mount されました。そして落とした Primary の復旧後、ちゃんと Secondary から Primary に戻りました。
</p>
<p>
以下の document が参考になるかも。
</p>
<ul>
<li><a href="http://bougaidenpa.org/masakazu/entry/drbd_integrating_with_heartbeat_v1">DRBD &#8211; Integrating with Heartbeat V1 [対訳]<br />- http://bougaidenpa.org/masakazu/entry/drbd_integrating_with_heartbeat_v1</a></li>
</ul>
<p>
以下は設定。
</p>
<pre class="sourcecode">
FILE: /etc/drbd.conf
--
resource r0 {
protocol C;
incon-degr-cmd &quot;echo '!DRBD! pri on incon-degr' | wall ; sleep 60 ; halt -f&quot;;
startup {
degr-wfc-timeout 120;
}
disk {
on-io-error   detach;
}
net {
}
syncer {
rate 10M;
group 1;
al-extents 257;
}
on debiancluster1 {
device     /dev/drbd0;
disk       /dev/sdb1;
address    192.168.2.16:7788;
meta-disk  internal;
}
on debiancluster2 {
device    /dev/drbd0;
disk      /dev/sdb1;
address   192.168.2.17:7788;
meta-disk internal;
}
}
</pre>
<pre class="sourcecode">
FILE: /etc/ha.d/ha.cf
--
logfacility     local0
ucast eth1 192.168.2.17
#ucast eth1 192.168.2.16
auto_failback on
node debiancluster1
node debiancluster2
</pre>
<pre class="sourcecode">
FILE: /etc/ha.d/haresources
--
debiancluster1 drbddisk::r0 Filesystem::/dev/drbd0::/var/lib/mysql::ext3
</pre>
<p>
以下は Primary 側を強制 shutdown させたときの Secondary 側の syslog。
</p>
<pre class="console">
Sep 13 00:08:38 debiancluster2 kernel: drbd0: PingAck did not arrive in time.
Sep 13 00:08:38 debiancluster2 kernel: drbd0: drbd0_asender [6652]: cstate Connected --> NetworkFailure
Sep 13 00:08:38 debiancluster2 kernel: drbd0: asender terminated
Sep 13 00:08:38 debiancluster2 kernel: drbd0: drbd0_receiver [3462]: cstate NetworkFailure --> BrokenPipe
Sep 13 00:08:38 debiancluster2 kernel: drbd0: short read expecting header on sock: r=-512
Sep 13 00:08:38 debiancluster2 kernel: drbd0: worker terminated
Sep 13 00:08:38 debiancluster2 kernel: drbd0: drbd0_receiver [3462]: cstate BrokenPipe --> Unconnected
Sep 13 00:08:38 debiancluster2 kernel: drbd0: Connection lost.
Sep 13 00:08:38 debiancluster2 kernel: drbd0: drbd0_receiver [3462]: cstate Unconnected --> WFConnection
Sep 13 00:08:56 debiancluster2 heartbeat: [6088]: WARN: node debiancluster1: is dead
Sep 13 00:08:56 debiancluster2 heartbeat: [6088]: WARN: No STONITH device configured.
Sep 13 00:08:56 debiancluster2 heartbeat: [6088]: WARN: Shared disks are not protected.
Sep 13 00:08:56 debiancluster2 heartbeat: [6088]: info: Resources being acquired from debiancluster1.
Sep 13 00:08:56 debiancluster2 heartbeat: [6088]: info: Link debiancluster1:eth1 dead.
Sep 13 00:08:56 debiancluster2 heartbeat: [6925]: debug: notify_world: setting SIGCHLD Handler to SIG_DFL
Sep 13 00:08:56 debiancluster2 harc[6925]: info: Running /etc/ha.d/rc.d/status status
Sep 13 00:08:56 debiancluster2 heartbeat: [6926]: info: No local resources [/usr/lib/heartbeat/ResourceManager listkeys debiancluster2] to acquire.
Sep 13 00:08:56 debiancluster2 heartbeat: [6088]: debug: StartNextRemoteRscReq(): child count 1
Sep 13 00:08:56 debiancluster2 mach_down[6945]: info: Taking over resource group drbddisk::r0
Sep 13 00:08:57 debiancluster2 ResourceManager[6965]: info: Acquiring resource group: debiancluster1 drbddisk::r0 Filesystem::/dev/drbd0::/var/lib/mysql::ext3
Sep 13 00:08:57 debiancluster2 ResourceManager[6965]: info: Running /etc/ha.d/resource.d/drbddisk r0 start
Sep 13 00:08:57 debiancluster2 ResourceManager[6965]: debug: Starting /etc/ha.d/resource.d/drbddisk r0 start
Sep 13 00:08:57 debiancluster2 kernel: drbd0: Secondary/Unknown --> Primary/Unknown
Sep 13 00:08:57 debiancluster2 ResourceManager[6965]: debug: /etc/ha.d/resource.d/drbddisk r0 start done. RC=0
Sep 13 00:08:57 debiancluster2 Filesystem[7101]: INFO: Running status for /dev/drbd0 on /var/lib/mysql
Sep 13 00:08:57 debiancluster2 Filesystem[7101]: INFO: /var/lib/mysql is unmounted (stopped)
Sep 13 00:08:57 debiancluster2 Filesystem[7037]: INFO: Filesystem Resource is stopped
Sep 13 00:08:57 debiancluster2 ResourceManager[6965]: info: Running /etc/ha.d/resource.d/Filesystem /dev/drbd0 /var/lib/mysql ext3 start
Sep 13 00:08:57 debiancluster2 ResourceManager[6965]: debug: Starting /etc/ha.d/resource.d/Filesystem /dev/drbd0 /var/lib/mysql ext3 start
Sep 13 00:08:57 debiancluster2 Filesystem[7210]: INFO: Running start for /dev/drbd0 on /var/lib/mysql
Sep 13 00:08:57 debiancluster2 kernel: kjournald starting.  Commit interval 5 seconds
Sep 13 00:08:57 debiancluster2 kernel: EXT3 FS on drbd0, internal journal
Sep 13 00:08:57 debiancluster2 kernel: EXT3-fs: recovery complete.
Sep 13 00:08:57 debiancluster2 kernel: EXT3-fs: mounted filesystem with ordered data mode.
Sep 13 00:08:57 debiancluster2 Filesystem[7146]: INFO: Filesystem Success
Sep 13 00:08:58 debiancluster2 ResourceManager[6965]: debug: /etc/ha.d/resource.d/Filesystem /dev/drbd0 /var/lib/mysql ext3 start done. RC=0
Sep 13 00:08:58 debiancluster2 mach_down[6945]: info: /usr/lib/heartbeat/mach_down: nice_failback: foreign resources acquired
Sep 13 00:08:58 debiancluster2 mach_down[6945]: info: mach_down takeover complete for node debiancluster1.
Sep 13 00:08:58 debiancluster2 heartbeat: [6088]: info: mach_down takeover complete.
</pre>
<p>
以下は強制 shutdown した Primary を再起動したときの Primary 側の syslog。
</p>
<pre class="console">
Sep 13 09:11:24 debiancluster1 kernel: drbd: initialised. Version: 0.7.21 (api:79/proto:74)
Sep 13 09:11:24 debiancluster1 kernel: drbd: SVN Revision: 2326 build by root@debiancluster1, 2007-09-13 07:55:36
Sep 13 09:11:24 debiancluster1 kernel: drbd: registered as block device major 147
Sep 13 09:11:24 debiancluster1 kernel: drbd0: resync bitmap: bits=5208430 words=81382
Sep 13 09:11:24 debiancluster1 kernel: drbd0: size = 19 GB (20833720 KB)
Sep 13 09:11:24 debiancluster1 kernel: drbd0: 0 KB marked out-of-sync by on disk bit-map.
Sep 13 09:11:24 debiancluster1 kernel: drbd0: Found 6 transactions (267 active extents) in activity log.
Sep 13 09:11:24 debiancluster1 kernel: drbd0: Marked additional 809 MB as out-of-sync based on AL.
Sep 13 09:11:24 debiancluster1 kernel: drbd0: drbdsetup [2198]: cstate Unconfigured --> StandAlone
Sep 13 09:11:25 debiancluster1 kernel: drbd0: drbdsetup [2211]: cstate StandAlone --> Unconnected
Sep 13 09:11:25 debiancluster1 kernel: drbd0: drbd0_receiver [2212]: cstate Unconnected --> WFConnection
Sep 13 09:11:25 debiancluster1 kernel: drbd0: drbd0_receiver [2212]: cstate WFConnection --> WFReportParams
Sep 13 09:11:25 debiancluster1 kernel: drbd0: Handshake successful: DRBD Network Protocol version 74
Sep 13 09:11:25 debiancluster1 kernel: drbd0: Connection established.
Sep 13 09:11:25 debiancluster1 kernel: drbd0: I am(S): 1:00000002:00000001:00000003:00000002:10
Sep 13 09:11:25 debiancluster1 kernel: drbd0: Peer(P): 1:00000002:00000001:00000003:00000003:10
Sep 13 09:11:25 debiancluster1 kernel: drbd0: drbd0_receiver [2212]: cstate WFReportParams --> WFBitMapT
Sep 13 09:11:25 debiancluster1 kernel: drbd0: Secondary/Unknown --> Secondary/Primary
Sep 13 09:11:25 debiancluster1 kernel: drbd0: drbd0_receiver [2212]: cstate WFBitMapT --> SyncTarget
Sep 13 09:11:25 debiancluster1 kernel: drbd0: Resync started as SyncTarget (need to sync 828856 KB [207214 bits set]).
Sep 13 09:11:30 debiancluster1 heartbeat: [2278]: WARN: Core dumps could be lost if multiple dumps occur
Sep 13 09:11:30 debiancluster1 heartbeat: [2278]: WARN: Consider setting /proc/sys/kernel/core_uses_pid (or equivalent) to 1 for maximum supportability
Sep 13 09:11:31 debiancluster1 heartbeat: [2278]: WARN: Logging daemon is disabled --enabling logging daemon is recommended
Sep 13 09:11:31 debiancluster1 heartbeat: [2278]: info: **************************
Sep 13 09:11:31 debiancluster1 heartbeat: [2278]: info: Configuration validated. Starting heartbeat 2.0.7
Sep 13 09:11:31 debiancluster1 heartbeat: [2279]: info: heartbeat: version 2.0.7
Sep 13 09:11:31 debiancluster1 heartbeat: [2279]: info: Heartbeat generation: 4
Sep 13 09:11:31 debiancluster1 heartbeat: [2279]: info: G_main_add_TriggerHandler: Added signal manual handler
Sep 13 09:11:31 debiancluster1 heartbeat: [2279]: info: G_main_add_TriggerHandler: Added signal manual handler
Sep 13 09:11:31 debiancluster1 heartbeat: [2279]: info: Removing /var/run/heartbeat/rsctmp failed, recreating.
Sep 13 09:11:31 debiancluster1 heartbeat: [2279]: info: glib: ucast: write socket priority set to IPTOS_LOWDELAY on eth1
Sep 13 09:11:31 debiancluster1 heartbeat: [2279]: info: glib: ucast: bound send socket to device: eth1
Sep 13 09:11:31 debiancluster1 heartbeat: [2279]: info: glib: ucast: bound receive socket to device: eth1
Sep 13 09:11:31 debiancluster1 heartbeat: [2279]: info: glib: ucast: started on port 694 interface eth1 to 192.168.2.17
Sep 13 09:11:31 debiancluster1 heartbeat: [2279]: info: G_main_add_SignalHandler: Added signal handler for signal 17
Sep 13 00:11:42 debiancluster1 heartbeat: [2279]: info: Local status now set to: 'up'
Sep 13 00:11:42 debiancluster1 heartbeat: [2279]: info: Link debiancluster2:eth1 up.
Sep 13 00:11:42 debiancluster1 heartbeat: [2279]: info: Status update for node debiancluster2: status active
Sep 13 00:11:42 debiancluster1 heartbeat: [2343]: debug: notify_world: setting SIGCHLD Handler to SIG_DFL
Sep 13 00:11:42 debiancluster1 harc[2343]: info: Running /etc/ha.d/rc.d/status status
Sep 13 00:11:43 debiancluster1 heartbeat: [2279]: info: Comm_now_up(): updating status to active
Sep 13 00:11:43 debiancluster1 heartbeat: [2279]: info: Local status now set to: 'active'
Sep 13 00:11:43 debiancluster1 heartbeat: [2279]: WARN: G_CH_dispatch_int: Dispatch function for read child took too long to execute: 480 ms (> 50 ms) (GSource: 0x5dfeb8)
Sep 13 00:11:43 debiancluster1 heartbeat: [2279]: info: remote resource transition completed.
Sep 13 00:11:43 debiancluster1 heartbeat: [2279]: info: remote resource transition completed.
Sep 13 00:11:43 debiancluster1 heartbeat: [2279]: info: Local Resource acquisition completed. (none)
Sep 13 00:11:44 debiancluster1 heartbeat: [2279]: info: debiancluster2 wants to go standby [foreign]
Sep 13 00:11:46 debiancluster1 kernel: drbd0: Secondary/Primary --> Secondary/Secondary
Sep 13 00:11:46 debiancluster1 heartbeat: [2279]: info: standby: acquire [foreign] resources from debiancluster2
Sep 13 00:11:46 debiancluster1 heartbeat: [2354]: info: acquire local HA resources (standby).
Sep 13 00:11:46 debiancluster1 ResourceManager[2364]: info: Acquiring resource group: debiancluster1 drbddisk::r0 Filesystem::/dev/drbd0::/var/lib/mysql::ext3
Sep 13 00:11:46 debiancluster1 ResourceManager[2364]: info: Running /etc/ha.d/resource.d/drbddisk r0 start
Sep 13 00:11:46 debiancluster1 ResourceManager[2364]: debug: Starting /etc/ha.d/resource.d/drbddisk r0 start
Sep 13 00:11:46 debiancluster1 kernel: drbd0: Secondary/Secondary --> Primary/Secondary
Sep 13 00:11:46 debiancluster1 ResourceManager[2364]: debug: /etc/ha.d/resource.d/drbddisk r0 start done. RC=0
Sep 13 00:11:47 debiancluster1 Filesystem[2500]: INFO: Running status for /dev/drbd0 on /var/lib/mysql
Sep 13 00:11:47 debiancluster1 Filesystem[2500]: INFO: /var/lib/mysql is unmounted (stopped)
Sep 13 00:11:47 debiancluster1 Filesystem[2436]: INFO: Filesystem Resource is stopped
Sep 13 00:11:47 debiancluster1 ResourceManager[2364]: info: Running /etc/ha.d/resource.d/Filesystem /dev/drbd0 /var/lib/mysql ext3 start
Sep 13 00:11:47 debiancluster1 ResourceManager[2364]: debug: Starting /etc/ha.d/resource.d/Filesystem /dev/drbd0 /var/lib/mysql ext3 start
Sep 13 00:11:47 debiancluster1 Filesystem[2609]: INFO: Running start for /dev/drbd0 on /var/lib/mysql
Sep 13 00:11:49 debiancluster1 kernel: kjournald starting.  Commit interval 5 seconds
Sep 13 00:11:49 debiancluster1 kernel: EXT3 FS on drbd0, internal journal
Sep 13 00:11:49 debiancluster1 kernel: EXT3-fs: mounted filesystem with ordered data mode.
Sep 13 00:11:49 debiancluster1 Filesystem[2545]: INFO: Filesystem Success
Sep 13 00:11:49 debiancluster1 ResourceManager[2364]: debug: /etc/ha.d/resource.d/Filesystem /dev/drbd0 /var/lib/mysql ext3 start done. RC=0
Sep 13 00:11:49 debiancluster1 heartbeat: [2354]: info: local HA resource acquisition completed (standby).
Sep 13 00:11:49 debiancluster1 heartbeat: [2279]: info: Standby resource acquisition done [foreign].
Sep 13 00:11:49 debiancluster1 heartbeat: [2279]: info: Initial resource acquisition complete (auto_failback)
Sep 13 00:11:49 debiancluster1 heartbeat: [2279]: info: remote resource transition completed.
Sep 13 00:13:40 debiancluster1 kernel: drbd0: Resync done (total 127 sec; paused 0 sec; 6524 K/sec)
Sep 13 00:13:40 debiancluster1 kernel: drbd0: drbd0_worker [2199]: cstate SyncTarget --> Connected
</pre>
<p>
以下は強制 shutdown した Primary を再起動したときの Secondary 側の syslog。
</p>
<pre class="console">
Sep 13 00:11:32 debiancluster2 kernel: drbd0: drbd0_receiver [3462]: cstate WFConnection --> WFReportParams
Sep 13 00:11:32 debiancluster2 kernel: drbd0: Handshake successful: DRBD Network Protocol version 74
Sep 13 00:11:32 debiancluster2 kernel: drbd0: Connection established.
Sep 13 00:11:32 debiancluster2 kernel: drbd0: I am(P): 1:00000002:00000001:00000003:00000003:10
Sep 13 00:11:32 debiancluster2 kernel: drbd0: Peer(S): 1:00000002:00000001:00000003:00000002:10
Sep 13 00:11:32 debiancluster2 kernel: drbd0: drbd0_receiver [3462]: cstate WFReportParams --> WFBitMapS
Sep 13 00:11:32 debiancluster2 kernel: drbd0: Primary/Unknown --> Primary/Secondary
Sep 13 00:11:32 debiancluster2 kernel: drbd0: drbd0_receiver [3462]: cstate WFBitMapS --> SyncSource
Sep 13 00:11:32 debiancluster2 kernel: drbd0: Resync started as SyncSource (need to sync 828856 KB [207214 bits set]).
Sep 13 00:11:42 debiancluster2 heartbeat: [6088]: info: Heartbeat restart on node debiancluster1
Sep 13 00:11:42 debiancluster2 heartbeat: [6088]: info: Link debiancluster1:eth1 up.
Sep 13 00:11:42 debiancluster2 heartbeat: [6088]: info: Status update for node debiancluster1: status init
Sep 13 00:11:42 debiancluster2 heartbeat: [6088]: info: Status update for node debiancluster1: status up
Sep 13 00:11:42 debiancluster2 heartbeat: [6088]: debug: StartNextRemoteRscReq(): child count 1
Sep 13 00:11:42 debiancluster2 heartbeat: [6088]: debug: get_delnodelist: delnodelist=
Sep 13 00:11:42 debiancluster2 heartbeat: [7260]: debug: notify_world: setting SIGCHLD Handler to SIG_DFL
Sep 13 00:11:42 debiancluster2 harc[7260]: info: Running /etc/ha.d/rc.d/status status
Sep 13 00:11:42 debiancluster2 heartbeat: [7270]: debug: notify_world: setting SIGCHLD Handler to SIG_DFL
Sep 13 00:11:42 debiancluster2 harc[7270]: info: Running /etc/ha.d/rc.d/status status
Sep 13 00:11:43 debiancluster2 heartbeat: [6088]: info: Status update for node debiancluster1: status active
Sep 13 00:11:43 debiancluster2 heartbeat: [7280]: debug: notify_world: setting SIGCHLD Handler to SIG_DFL
Sep 13 00:11:43 debiancluster2 harc[7280]: info: Running /etc/ha.d/rc.d/status status
Sep 13 00:11:43 debiancluster2 heartbeat: [6088]: info: remote resource transition completed.
Sep 13 00:11:43 debiancluster2 heartbeat: [6088]: info: debiancluster2 wants to go standby [foreign]
Sep 13 00:11:44 debiancluster2 heartbeat: [6088]: info: standby: debiancluster1 can take our foreign resources
Sep 13 00:11:44 debiancluster2 heartbeat: [7290]: info: give up foreign HA resources (standby).
Sep 13 00:11:44 debiancluster2 ResourceManager[7300]: info: Releasing resource group: debiancluster1 drbddisk::r0 Filesystem::/dev/drbd0::/var/lib/mysql::ext3
Sep 13 00:11:44 debiancluster2 ResourceManager[7300]: info: Running /etc/ha.d/resource.d/Filesystem /dev/drbd0 /var/lib/mysql ext3 stop
Sep 13 00:11:44 debiancluster2 ResourceManager[7300]: debug: Starting /etc/ha.d/resource.d/Filesystem /dev/drbd0 /var/lib/mysql ext3 stop
Sep 13 00:11:45 debiancluster2 Filesystem[7399]: INFO: Running stop for /dev/drbd0 on /var/lib/mysql
Sep 13 00:11:45 debiancluster2 Filesystem[7399]: INFO: Trying to unmount /var/lib/mysql
Sep 13 00:11:45 debiancluster2 Filesystem[7399]: INFO: unmounted /var/lib/mysql successfully
Sep 13 00:11:45 debiancluster2 Filesystem[7335]: INFO: Filesystem Success
Sep 13 00:11:45 debiancluster2 ResourceManager[7300]: debug: /etc/ha.d/resource.d/Filesystem /dev/drbd0 /var/lib/mysql ext3 stop done. RC=0
Sep 13 00:11:45 debiancluster2 ResourceManager[7300]: info: Running /etc/ha.d/resource.d/drbddisk r0 stop
Sep 13 00:11:45 debiancluster2 ResourceManager[7300]: debug: Starting /etc/ha.d/resource.d/drbddisk r0 stop
Sep 13 00:11:45 debiancluster2 kernel: drbd0: Primary/Secondary --> Secondary/Secondary
Sep 13 00:11:46 debiancluster2 ResourceManager[7300]: debug: /etc/ha.d/resource.d/drbddisk r0 stop done. RC=0
Sep 13 00:11:46 debiancluster2 heartbeat: [7290]: info: foreign HA resource release completed (standby).
Sep 13 00:11:46 debiancluster2 heartbeat: [6088]: info: Local standby process completed [foreign].
Sep 13 00:11:46 debiancluster2 kernel: drbd0: Secondary/Secondary --> Secondary/Primary
Sep 13 00:11:49 debiancluster2 heartbeat: [6088]: WARN: 1 lost packet(s) for [debiancluster1] [17:19]
Sep 13 00:11:49 debiancluster2 heartbeat: [6088]: info: remote resource transition completed.
Sep 13 00:11:49 debiancluster2 heartbeat: [6088]: info: No pkts missing from debiancluster1!
Sep 13 00:11:49 debiancluster2 heartbeat: [6088]: info: Other node completed standby takeover of foreign resources.
Sep 13 00:13:32 debiancluster2 kernel: drbd0: [drbd0_worker/6924] sock_sendmsg time expired, ko = 4294967295
Sep 13 00:13:40 debiancluster2 kernel: drbd0: Resync done (total 127 sec; paused 0 sec; 6524 K/sec)
Sep 13 00:13:40 debiancluster2 kernel: drbd0: drbd0_worker [6924]: cstate SyncSource --> Connected
</pre>
]]></content:encoded>
			<wfw:commentRss>http://bougaidenpa.org/masakazu/archives/29/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>mixi clone on rails 04</title>
		<link>http://bougaidenpa.org/masakazu/archives/28</link>
		<comments>http://bougaidenpa.org/masakazu/archives/28#comments</comments>
		<pubDate>Sat, 08 Sep 2007 20:35:48 +0000</pubDate>
		<dc:creator>masakazu</dc:creator>
				<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://bougaidenpa.org/masakazu/?p=28</guid>
		<description><![CDATA[


本日の目標

<p>
とりあえずトップページだけ作ってみます(その 2)。
</p>
<p>
前回に引き続き今日は、
</p>

mixlone の Controller 機能を集約する Main Controller の作成
認証情報(ひとの情報)を格納する Person Model の作成
ログイン処理をする login Action の実装
ログイン済みか確認しログインしていなければログインページへリダイレクトする before Filter の実装と設定

<p>
の残り 3 と 4 を実装します。
</p>



login Action の実装

<p>
login Action では以下の処理を行うことにします。
</p>

ログインフォームの表示 &#8211; メールアドレスとパスワードを入力するフォームを表示します。下には“ログイン”ボタンがあり、これを押すと login Action 自身へ POST されるようにします。
ログイン処理の実施 &#8211; POST されたメールアドレスとパスワードに一致する Person が存在するか確認します。一致する Person が存在する場合は session[:person_id] に Person の id を格納し home Action へリダイレクトします。一致する Person が存在しない場合はエラーメッセージを表示します。

<p>
まずはログインフォームの準備から始めましょう。
</p>
<p>
http://(サーバの IP アドレス):3000/main/login へアクセスした際に表示されるのは app/views/main/login.rhtml でした。これを以下の通り変更します。
</p>

FILE: app/views/main/login.rhtml
1 [...]]]></description>
			<content:encoded><![CDATA[<div class="note">
<p/>
<div class="myh">
本日の目標
</div>
<p>
とりあえずトップページだけ作ってみます(その 2)。
</p>
<p>
前回に引き続き今日は、
</p>
<ol>
<li>mixlone の Controller 機能を集約する Main Controller の作成</li>
<li>認証情報(ひとの情報)を格納する Person Model の作成</li>
<li>ログイン処理をする login Action の実装</li>
<li>ログイン済みか確認しログインしていなければログインページへリダイレクトする before Filter の実装と設定</li>
</ol>
<p>
の残り 3 と 4 を実装します。
</p>
</div>
<p/>
<div class="myh">
login Action の実装
</div>
<p>
login Action では以下の処理を行うことにします。
</p>
<ul>
<li>ログインフォームの表示 &#8211; メールアドレスとパスワードを入力するフォームを表示します。下には“ログイン”ボタンがあり、これを押すと login Action 自身へ POST されるようにします。</li>
<li>ログイン処理の実施 &#8211; POST されたメールアドレスとパスワードに一致する Person が存在するか確認します。一致する Person が存在する場合は session[:person_id] に Person の id を格納し home Action へリダイレクトします。一致する Person が存在しない場合はエラーメッセージを表示します。</li>
</ul>
<p>
まずはログインフォームの準備から始めましょう。
</p>
<p>
http://(サーバの IP アドレス):3000/main/login へアクセスした際に表示されるのは app/views/main/login.rhtml でした。これを以下の通り変更します。
</p>
<pre class="sourcecode">
FILE: app/views/main/login.rhtml
1  &lt;h1&gt;Main#login&lt;/h1&gt;
2  &lt;p&gt;&lt;%= flash[:login] %&gt;&lt;/p&gt;
3  &lt;%= start_form_tag %&gt;
4  &lt;p&gt;&lt;label for="person_email_address"&gt;Email address&lt;/label&gt;&lt;br/&gt;
5  &lt;%= text_field 'person', 'email_address'  %&gt;&lt;/p&gt;
6  &lt;p&gt;&lt;label for="person_password"&gt;Password&lt;/label&gt;&lt;br/&gt;
7  &lt;%= password_field 'person', 'password'  %&gt;&lt;/p&gt;
8  &lt;%= submit_tag 'LOGIN' %&gt;
9  &lt;%= end_form_tag %&gt;
</pre>
<p>
続いて login Action の Action メソッドを修正します。
</p>
<p>
http://(サーバの IP アドレス):3000/main/login へアクセスした際に実行されるのは app/controllers/main_controller.rb で定義された login メソッドでした。これを以下の通り変更します。
</p>
<pre class="sourcecode">
FILE: app/controllers/main_controller.rb
1  class MainController &lt; ApplicationController
2    <b>model :person</b>
3
4    def home
5    end
6
7    def login
8  <b>    if request.post? then</b>
9  <b>      person = Person.find(:first, :conditions =&gt; [ 'email_address = :email_address and password = :password', params[:person]])</b>
10  <b>      if person then</b>
11  <b>        session[:person_id] = person[:id]</b>
12  <b>        redirect_to :action =&gt; :home</b>
13  <b>      else</b>
14  <b>        flash[:login] = 'LOGIN ERROR'</b>
15  <b>      end</b>
16  <b>    end</b>
17    end
18  end
</pre>
<p>
http request が POST かどうか調べています(8 行目)。もし POST であれば 9 行目から 15 行目までを実行します。
</p>
<p>
POST であれば Person モデルで email_address と password がフォームから入力されたものと一致するオブジェクトがないか探します(9 行目)。一致するものがあれば Person オブジェクトが返され、なければ nil が返されます。
</p>
<p>
person に値が入っているか(nil かどうか)確認します(10 行目)。もし値が入っていれば person オブジェクトの :id を session[:person_id] に代入し(11 行目) home Action へリダイレクトします(12 行目)。person が nil なら flash[:login] にエラーメッセージを代入します(14 行目)。
</p>
<div class="myh">
before Filter の実装と設定
</div>
<p>
Action メソッドを実行するまえに実行したい処理をメソッドとして定義し before Filter として設定することができます。同じように Action メソッド実行のあとに実行したい処理を after Filter として設定することができます。ついでに before と after をペアで around Filter として設定することもできます。
</p>
<p>
“session[:person_id] がセットされているかを確認しセットされていなかったら login Action へリダイレクトする”というメソッドを用意し before Filter に設定することでログインしないとコンテンツを閲覧できないように制限することが出来ます。
</p>
<p>
app/controllers/main_controller.rb を以下の通り修正します。
</p>
<pre class="sourcecode">
FILE: app/controllers/main_controller.rb
1  class MainController &lt; ApplicationController
2    model :person
3  <b>  before_filter :authorize, :except =&gt; :login</b>
4
5    def home
6    end
7
8    def login
...
18    end
19
20  <b>  private</b>
21  <b>  def authorize</b>
22  <b>    unless session[:person_id] then</b>
23  <b>      redirect_to :action =&gt; :login</b>
24  <b>    end</b>
25  <b>  end</b>
26  end
</pre>
<p>
authorize という private なメソッドを定義し(20 行目 〜 25 行目)、before_filter で Main Controller にアタッチしています(3 行目)。ただし login Action に関しては before_filter の対象から外さなければならないので :except オプションで対象外としています(そうしないと無限リダイレクトにはまってしまいます)。
</p>
<p>
<span class="command">script/server</span> を起動し意図した通り動作するか確認しましょう。
</p>
<p>
とりあえず、今日はここまで。</p>
]]></content:encoded>
			<wfw:commentRss>http://bougaidenpa.org/masakazu/archives/28/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>mixi clone on rails 03</title>
		<link>http://bougaidenpa.org/masakazu/archives/27</link>
		<comments>http://bougaidenpa.org/masakazu/archives/27#comments</comments>
		<pubDate>Sat, 08 Sep 2007 18:49:49 +0000</pubDate>
		<dc:creator>masakazu</dc:creator>
				<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://bougaidenpa.org/masakazu/?p=27</guid>
		<description><![CDATA[


本日の目標

<p>
とりあえずトップページだけ作ってみます(その 1)。
</p>
<p>
閉鎖的な mixlone ではアカウントを持った人がログインした状態でないといかなるコンテンツも閲覧出来ないようにします。そのためには、
</p>

mixlone の Controller 機能を集約する Main Controller の作成
認証情報(ひとの情報)を格納する Person Model の作成
ログイン処理をする login Action の実装
ログイン済みか確認しログインしていなければログインページへリダイレクトする before Filter の実装と設定

<p>
を実装しなければならないわけですが、今日は上記のうち 1 と 2 を実装します。
</p>



Main Controller の作成

<p>
Rails には Model や View/Controller のひな形を作成してくれる便利な script/generate というスクリプトが用意されています。
</p>
<p>
以下の通り script/generate を実行し Main Controller(と home Action と login Action) のひな形を作成します。
</p>

masakazu@debian:~/mixlone$ script/generate controller Main home login
exists  app/controllers/
exists  app/helpers/
create  app/views/main
exists  test/functional/
create  [...]]]></description>
			<content:encoded><![CDATA[<div class="note">
<p/>
<div class="myh">
本日の目標
</div>
<p>
とりあえずトップページだけ作ってみます(その 1)。
</p>
<p>
閉鎖的な mixlone ではアカウントを持った人がログインした状態でないといかなるコンテンツも閲覧出来ないようにします。そのためには、
</p>
<ol>
<li>mixlone の Controller 機能を集約する Main Controller の作成</li>
<li>認証情報(ひとの情報)を格納する Person Model の作成</li>
<li>ログイン処理をする login Action の実装</li>
<li>ログイン済みか確認しログインしていなければログインページへリダイレクトする before Filter の実装と設定</li>
</ol>
<p>
を実装しなければならないわけですが、今日は上記のうち 1 と 2 を実装します。
</p>
</div>
<p/>
<div class="myh">
Main Controller の作成
</div>
<p>
Rails には Model や View/Controller のひな形を作成してくれる便利な <span class="command">script/generate</span> というスクリプトが用意されています。
</p>
<p>
以下の通り <span class="command">script/generate</span> を実行し Main Controller(と home Action と login Action) のひな形を作成します。
</p>
<pre class="console">
masakazu@debian:~/mixlone$ script/generate controller Main home login
exists  app/controllers/
exists  app/helpers/
create  app/views/main
exists  test/functional/
create  app/controllers/main_controller.rb
create  test/functional/main_controller_test.rb
create  app/helpers/main_helper.rb
create  app/views/main/home.rhtml
create  app/views/main/login.rhtml
</pre>
<p>
app/controllers/main_controller.rb というのが Main Controller の本体です。なかみはこんな感じになっています。
</p>
<pre class="sourcecode">
FILE: app/controllers/main_controller.rb
1  class MainController &lt; ApplicationController
2
3    def home
4    end
5
6    def login
7    end
8  end
</pre>
<p>
app/views/main/home.rhtml と app/views/main/login.rhtml というファイルが作られていますが、これが View のテンプレートになります。なかみはこんな感じです(以下は home.rhtml ですが login.rhtml も基本的にいっしょです)。
</p>
<pre class="sourcecode">
FILE: app/views/main/home.rhtml
1  &lt;h1&gt;Main#home&lt;/h1&gt;
2  &lt;p&gt;Find me in app/views/main/home.rhtml&lt;/p&gt;
</pre>
<p>
この状態で <span class="command">script/server -b 0.0.0.0</span> を実行し http://(サーバの IP アドレス):3000/main/home へアクセスすると以下の処理が実行されます(Helper Module のこととかはとりあえず無視)。
</p>
<ol>
<li>main_controller.rb が読み込まれます</li>
<li>MainController のインスタンスが生成されます</li>
<li>MainController の home メソッドが実行されます</li>
<li>home.rhtml をテンプレートとして HTML が生成されクライアントへ返されます</li>
</ol>
<p>
home.rhtml のひな形には static は HTML 文しか書かれていませんがここには <span class="command">&lt;%= @variable %&gt;</span> のように変数を埋め込んだり <span class="command">&lt;% 1.upto(10) do |i| %&gt;&lt;%= &#8220;#{i}&lt;br&gt;&#8221; %&gt;&lt;% end %&gt;</span> のように Ruby code も埋め込めます。ただし .rhtml ファイルに Ruby code が埋め込めるからといってロジックを .rhtml ファイルに書くようなことは避けるべきです。Controller 内の Action メソッドでロジックを実行し .rhtml ファイルはそれを埋め込むだけ、というスタイルにしておくのが良い習慣と言えます。View と Controller を分離することで、ロジックのことを考えるときはロジックのことだけに集中でき、見栄えのことを考えるときは見栄えのことだけに集中できるようになるからです。
</p>
<p>
Rails では Controller を複数作ることができます。本当であれば機能のまとまりごとに Controller を複数用意し Action を分離すべきなのかもしれませんが、 mixlon では、そんなに複雑にはならないであろうことと、第一めんどくさいので、 Main という Controller をひとつ用意してすべての Action を Main に集約することにします。
</p>
<p>
ただしこの次の Person Model の作成で scaffold を作りますが、 Model の scaffold に関しては Model::XxxController という名前の Controller を作成することにします。これは管理目的で使うもので利用者へは見せないということにします。
</p>
<div class="myh">
Person Model の作成
</div>
<p>
以下の通り <span class="command">script/generate</span> で Person Model のテンプレートを作成します。
</p>
<pre class="console">
masakazu@debian:~/mixlone$ script/generate model Person
exists  app/models/
exists  test/unit/
exists  test/fixtures/
create  app/models/person.rb
create  test/unit/person_test.rb
create  test/fixtures/people.yml
create  db/migrate
create  db/migrate/001_create_people.rb
</pre>
<p>
Person という名前の Model をつくっているのに最後の行で 001_create_people.rb というファイルが生成されていますが&#8230; Rails では Model のインスタンスを格納するデータベースのテーブル名は Model の“英語での”複数形にするという暗黙のルールが設けられています。このルールは必ず守らなければならないというわけではないですが、このルールに従っておくと Model とテーブルの対応付けを Rails が勝手にやってくれます。逆にルールを破るときは Rails に“この Model のテーブルは xxx ですよ”と教えてあげなければなりません。
</p>
<p>
app/models/person.rb というのが Person Model の本体です。なかみはこんな感じになってます。
</p>
<pre class="sourcecode">
FILE: app/models/person.rb
1  class Person &lt; ActiveRecord::Base
2  end
</pre>
<p>
ご覧の通り、 script/generate が生成する Model のひな形は Class の外枠があるだけです。
</p>
<p>
Person Model のインスタンスの保存先としてデータベースに people テーブルを作らなきゃならないわけですが、ふつうにデータベースに接続して CREATE TABLE &#8230; としてもいいんですが、 Rails には SQL 文をかかずに Ruby code だけでテーブルを作るための migration という機能があるので、使ってみます。
</p>
<p>
db/migrate/001_create_people.rb というファイルが生成されていますが、これを以下のように修正します(修正箇所を太字にしています)。
</p>
<pre class="sourcecode">
FILE: db/migrate/001_create_people.rb
1  class CreatePeople &lt; ActiveRecord::Migration
2    def self.up
3      create_table :people do |t|
4        # t.column :name, :string
5        <b>t.column :last_name, :string</b>
6        <b>t.column :first_name, :string</b>
7        <b>t.column :nickname, :string</b>
8        <b>t.column :password, :string</b>
9        <b>t.column :address_prefecture, :integer</b>
10        <b>t.column :address_city, :integer</b>
11        <b>t.column :sex, :integer</b>
12        <b>t.column :birth_year, :integer</b>
13        <b>t.column :birth_month, :integer</b>
14        <b>t.column :birth_day, :integer</b>
15        <b>t.column :blood_group, :integer</b>
16        <b>t.column :birthplace_prefecture, :integer</b>
17        <b>t.column :birthplace_city, :integer</b>
18  <b>#      t.column :hobies, :integer</b>
19        <b>t.column <img src='http://bougaidenpa.org/masakazu/wp-includes/images/smilies/icon_surprised.gif' alt=':o' class='wp-smiley' /> ccupatioo, :integer</b>
20        <b>t.column :belonging, :string</b>
21        <b>t.column :self_introduction, :text</b>
22        <b>t.column :favorite1, :integer</b>
23        <b>t.column :favorite2, :integer</b>
24        <b>t.column :favorite3, :integer</b>
25      end
26    end
27
28    def self.down
29      drop_table :people
30    end
31  end
</pre>
<p>
以下の通り <span class="command">rake db:migrate</span> を実行すると 001_create_people.rb に書いた通り CREATE TABLE が実行されます。
</p>
<pre class="console">
masakazu@debian:~/mixlone$ rake db:migrate
(in /home/masakazu/mixlone)
== CreatePeople: migrating ====================================================
-- create_table(:people)
NOTICE:  CREATE TABLE will create implicit sequence "people_id_seq" for serial column "people.id"
NOTICE:  CREATE TABLE / PRIMARY KEY will create implicit index "people_pkey" for table "people"
-> 0.0490s
== CreatePeople: migrated (0.0494s) ===========================================
</pre>
<p>
ためしに psql で確認してみるとちゃんと people というテーブルが出来ています。
</p>
<pre class="console">
postgres@debian:~$ psql -d mixlone_development
Welcome to psql 8.1.9, the PostgreSQL interactive terminal.
Type:  \copyright for distribution terms
\h for help with SQL commands
\? for help with psql commands
\g or terminate with semicolon to execute query
\q to quit
mixlone_development=# \d
List of relations
Schema |     Name      |   Type   |  Owner
--------+---------------+----------+---------
public | people        | table    | mixlone
public | people_id_seq | sequence | mixlone
public | schema_info   | table    | mixlone
(3 rows)
mixlone_development=# \d people
Table "public.people"
Column         |          Type          |                      Modifiers
-----------------------+------------------------+-----------------------------------------------------
id                    | integer                | not null default nextval('people_id_seq'::regclass)
email_address         | character varying(255) |
password              | character varying(255) |
last_name             | character varying(255) |
first_name            | character varying(255) |
nickname              | character varying(255) |
address_prefecture    | integer                |
address_city          | integer                |
sex                   | integer                |
birth_year            | integer                |
birth_month           | integer                |
birth_day             | integer                |
blood_group           | integer                |
birthplace_prefecture | integer                |
birthplace_city       | integer                |
occupatioo            | integer                |
belonging             | character varying(255) |
self_introduction     | text                   |
favorite1             | integer                |
favorite2             | integer                |
favorite3             | integer                |
Indexes:
"people_pkey" PRIMARY KEY, btree (id)
</pre>
<p>
people のほかに schema_info というテーブルができてますが、これは migration で管理するバージョン情報のようです。 migration 用のファイルは 001_create_people.rb のように数字 3 文字で始まるのですが、この 3 文字の数字が migration のバージョン番号になります。 migration を何個も作っていくとこの部分が 002, 003, &#8230; と増えていき rake db:migrate を実行するたびに schema_info の version よりも新しい migration 用のファイルが実行されていきます。 rake db:migrate には VERSION=xxx というオプションも指定でき、現在よりも古い状態まで戻すことが出来ます。そのときはすでに実行された migration 用ファイルの down クラスメソッドが逆順で実行されていきます。
</p>
<p>
Person Model も出来たしデータベースには people テーブルもできたのであとはひとの情報を入力していくわけですが、いちいち INSERT, UPDATE を実行していたのでは面倒です。Rails にはおなじみの scaffold という Model の情報を一覧表示したり新規追加したり削除したりするための View/Controller を用意してくれる機能があるのでこれを使って Person オブジェクトを管理するようにします。
</p>
<p>
以下の通り <span class="command">script/generate</span> を実行します。
</p>
<pre class="console">
masakazu@debian:~/mixlone$ script/generate scaffold Person Model::Person
create  app/controllers/model
create  app/helpers/model
create  app/views/model/person
create  test/functional/model
dependency  model
exists    app/models/
exists    test/unit/
exists    test/fixtures/
identical    app/models/person.rb
identical    test/unit/person_test.rb
identical    test/fixtures/people.yml
create  app/views/model/person/_form.rhtml
create  app/views/model/person/list.rhtml
create  app/views/model/person/show.rhtml
create  app/views/model/person/new.rhtml
create  app/views/model/person/edit.rhtml
create  app/controllers/model/person_controller.rb
create  test/functional/model/person_controller_test.rb
create  app/helpers/model/person_helper.rb
create  app/views/layouts/person.rhtml
create  public/stylesheets/scaffold.css
</pre>
<p>
上記では Person Model に対する scaffold を Model::Person という Controller に作成しています。
</p>
<p>
<span class="command">script/server -b 0.0.0.0</span> を実行し http://(サーバの IP アドレス):3000/model/person へアクセスするとこんな画面が表示されます。
</p>
<p><img src="http://bougaidenpa.org/masakazu/resource/mixlone/listing_people.png" alt=""/></p>
<p>
New person をクリックすると新しい Person を登録するためのフォームが表示されるので適当に入力して自分のアカウントを作りましょう。アカウントとパスワードだけは直近で使う予定があるので空白だと困りますけど、それ以外はとりあえずは空白でもかまいません。追々 UNIQUE 制約とか NOT NULL 制約とかつけてきましょう。ひょっとしたら DB 側はそのままで Rails 側の Validation のみでいくかもしれないけど&#8230;
</p>
<p>
とりあえず今日はここまで。</p>
]]></content:encoded>
			<wfw:commentRss>http://bougaidenpa.org/masakazu/archives/27/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
