<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-2550436420816136794</id><updated>2011-11-28T08:38:51.868+09:00</updated><category term='Service'/><category term='Performance'/><category term='Ruby'/><category term='感想'/><category term='Ext'/><category term='Rails'/><category term='Selenium'/><category term='Debugging'/><category term='UML'/><category term='Perl'/><category term='Book'/><category term='JavaScript'/><category term='Blog'/><category term='Programming'/><category term='Testing'/><title type='text'>usuilog-プログラミングメモ</title><subtitle type='html'>プログラミングを中心としたIT技術系のメモ書きです</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://usuilog.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2550436420816136794/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://usuilog.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>usuihiro</name><uri>http://www.blogger.com/profile/18033487413398851661</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>22</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-2550436420816136794.post-3723119761592480537</id><published>2007-08-09T14:24:00.000+09:00</published><updated>2008-12-09T15:54:25.523+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programming'/><category scheme='http://www.blogger.com/atom/ns#' term='Ruby'/><category scheme='http://www.blogger.com/atom/ns#' term='Rails'/><title type='text'>[Ruby][Rails]InputDrawとrailsで作る手書き掲示板</title><content type='html'>InputDrawとrailsを使って手書き掲示板を作成してみました。InputDrawとは手書き可能なフォームを簡単に作成できるライブラリです。下記のような手書きキャンバスを作成できます。&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_sX6CD3lBq0Q/RrqvmB8XOgI/AAAAAAAAABg/Vt4-cN_MawE/s1600-h/inputdraw.jpg"&gt;&lt;img style="margin:0 10px 10px 0;cursor:pointer; cursor:hand;" src="http://4.bp.blogspot.com/_sX6CD3lBq0Q/RrqvmB8XOgI/AAAAAAAAABg/Vt4-cN_MawE/s320/inputdraw.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5096578996214643202" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;scaffoldで雛型作成&lt;/h4&gt;&lt;br /&gt;まずはscaffoldで雛型を作成します。&lt;br /&gt;&lt;pre class="console"&gt;&lt;code&gt;&lt;br /&gt;rails inputdraw&lt;br /&gt;cd inputdraw&lt;br /&gt;./script/generate scaffold_resource post title:string nickname:string comment:text image:string svg:text created_at:datetime updated_at:datetime&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;データベース準備&lt;/h4&gt;&lt;br /&gt;inputdraw_developmentというデータベースを作成しておき、マイグレーションを実行します。&lt;br /&gt;&lt;pre class="console"&gt;&lt;code&gt;&lt;br /&gt;rake db:migrate&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;file_columnプラグインのインストール&lt;/h4&gt;&lt;br /&gt;画像アップロード処理にはfile_columnプラグインを利用します。これを使うとアップロード処理と、レコードとファイルパスの関連付けを自動でおこなってくれます&lt;br /&gt;&lt;br /&gt;&lt;pre class="console"&gt;&lt;code&gt;./script/plugin install http://opensvn.csie.org/rails_file_column/plugins/file_column/trunk&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;InpudDrawのインストール&lt;/h4&gt;&lt;br /&gt;&lt;a href="http://www.mainada.net/inputdraw"&gt;サイト&lt;/a&gt;からファイルをダウンロードし、public/javascriptsディレトリに配置します。&lt;br /&gt;&lt;pre class="console"&gt;&lt;code&gt;|-- javascripts&lt;br /&gt;|   |-- inputdraw&lt;br /&gt;|   |   |-- inputdraw.free-non-commercial.1.2.swf&lt;br /&gt;|   |   |-- inputdraw.js&lt;br /&gt;|   |   `-- swfobject.js&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;ImageSizeのインストール&lt;/h4&gt;&lt;br /&gt;キャンバスのサイズは画像サイズから求めることにしました。&lt;br /&gt;file_columではRMagickを使って画像を簡単に加工できるようになっていますが、今回はサイズが欲しいだけだったのでImageSizeを利用しました。&lt;br /&gt;&lt;pre class="console"&gt;&lt;code&gt;gem install imagesize&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;テンプレートの編集&lt;/h4&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;app/view/layout/posts.rhtml&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;InputDrawに必要なファイルを読み込みます&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;span class="synSpecial"&gt;&amp;lt;%=&lt;/span&gt; javascript_include_tag &lt;span class="synSpecial"&gt;'&lt;/span&gt;&lt;span class="synConstant"&gt;inputdraw/swfobject&lt;/span&gt;&lt;span class="synSpecial"&gt;'&lt;/span&gt; &lt;span class="synSpecial"&gt;%&amp;gt;&lt;/span&gt;&lt;br /&gt;  &lt;span class="synSpecial"&gt;&amp;lt;%=&lt;/span&gt; javascript_include_tag &lt;span class="synSpecial"&gt;'&lt;/span&gt;&lt;span class="synConstant"&gt;inputdraw/inputdraw&lt;/span&gt;&lt;span class="synSpecial"&gt;'&lt;/span&gt; &lt;span class="synSpecial"&gt;%&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;app/view/layout/new.rhtml&lt;/span&gt;&lt;br /&gt;Imageをfile_fieldに変更し、フォームタイプをmultipartにします。&lt;br /&gt;svgとcreated_at,updated_atはとりあえず削除します。&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;span class="synSpecial"&gt;&amp;lt;%&lt;/span&gt; form_for(&lt;span class="synIdentifier"&gt;:post&lt;/span&gt;, &lt;span class="synIdentifier"&gt;:url&lt;/span&gt; =&amp;gt; posts_path, &lt;span class="synIdentifier"&gt;:html&lt;/span&gt; =&amp;gt; { &lt;span class="synIdentifier"&gt;:multipart&lt;/span&gt; =&amp;gt; &lt;span class="synConstant"&gt;true&lt;/span&gt; }) &lt;span class="synStatement"&gt;do&lt;/span&gt; |&lt;span class="synIdentifier"&gt;f&lt;/span&gt;| &lt;span class="synSpecial"&gt;%&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span class="synIdentifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="synStatement"&gt;b&lt;/span&gt;&lt;span class="synIdentifier"&gt;&amp;gt;&lt;/span&gt;Image&lt;span class="synIdentifier"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="synStatement"&gt;b&lt;/span&gt;&lt;span class="synIdentifier"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="synStatement"&gt;br&lt;/span&gt;&lt;span class="synIdentifier"&gt; /&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span class="synSpecial"&gt;&amp;lt;%=&lt;/span&gt; f.file_field &lt;span class="synIdentifier"&gt;:image&lt;/span&gt; &lt;span class="synSpecial"&gt;%&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;app/view/posts/index.rhtml&lt;/span&gt;&lt;br /&gt;イメージの部分をタグに置き換えます。svgは表示しないので削除します。&lt;br /&gt;&lt;pre&gt;&lt;code&gt; &lt;span class="synIdentifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="synStatement"&gt;td&lt;/span&gt;&lt;span class="synIdentifier"&gt;&amp;gt;&lt;/span&gt;&lt;span class="synSpecial"&gt;&amp;lt;%=&lt;/span&gt; image_tag url_for_file_column(post, &lt;span class="synSpecial"&gt;"&lt;/span&gt;&lt;span class="synConstant"&gt;image&lt;/span&gt;&lt;span class="synSpecial"&gt;"&lt;/span&gt;), &lt;span class="synIdentifier"&gt;:height&lt;/span&gt; =&amp;gt; &lt;span class="synConstant"&gt;150&lt;/span&gt; &lt;span class="synSpecial"&gt;%&amp;gt;&lt;/span&gt;&lt;span class="synIdentifier"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="synStatement"&gt;td&lt;/span&gt;&lt;span class="synIdentifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;app/view/posts/show.rhtml&lt;/span&gt;&lt;br /&gt;svgの部分をInputDrawのキャンバスにする要素で置き換えます。表示用に使用したいのでここではsrc要素を指定しています。&lt;br /&gt;imageタグの部分は削除します。&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;span class="synIdentifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="synStatement"&gt;p&lt;/span&gt;&lt;span class="synIdentifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;  &lt;span class="synIdentifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="synStatement"&gt;b&lt;/span&gt;&lt;span class="synIdentifier"&gt;&amp;gt;&lt;/span&gt;Svg:&lt;span class="synIdentifier"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="synStatement"&gt;b&lt;/span&gt;&lt;span class="synIdentifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;  &lt;span class="synIdentifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="synStatement"&gt;div&lt;/span&gt;&lt;span class="synIdentifier"&gt; &lt;/span&gt;&lt;span class="synType"&gt;id&lt;/span&gt;&lt;span class="synIdentifier"&gt;=&lt;/span&gt;&lt;span class="synConstant"&gt;"place"&lt;/span&gt;&lt;span class="synIdentifier"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="synStatement"&gt;div&lt;/span&gt;&lt;span class="synIdentifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="synIdentifier"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="synStatement"&gt;p&lt;/span&gt;&lt;span class="synIdentifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="synComment"&gt;&amp;lt;!-- 末尾に追加 --&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="synIdentifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="synStatement"&gt;script&lt;/span&gt;&lt;span class="synIdentifier"&gt; &lt;/span&gt;&lt;span class="synType"&gt;type&lt;/span&gt;&lt;span class="synIdentifier"&gt;=&lt;/span&gt;&lt;span class="synConstant"&gt;"text/javascript"&lt;/span&gt;&lt;span class="synIdentifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="synComment"&gt;//&amp;lt;[![CDATA&lt;/span&gt;&lt;br /&gt;&lt;span class="synSpecial"&gt;        &lt;/span&gt;&lt;span class="synStatement"&gt;new&lt;/span&gt;&lt;span class="synSpecial"&gt; InputDraw&lt;/span&gt;(&lt;span class="synConstant"&gt;"/javascripts/inputdraw/inputdraw.free-non-commercial.1.2.swf"&lt;/span&gt;&lt;span class="synSpecial"&gt;, &lt;/span&gt;&lt;span class="synConstant"&gt;"place"&lt;/span&gt;&lt;span class="synSpecial"&gt;,&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="synSpecial"&gt;        &lt;/span&gt;&lt;span class="synIdentifier"&gt;{&lt;/span&gt;&lt;span class="synSpecial"&gt;src_svg:&lt;/span&gt;&lt;span class="synConstant"&gt;"&amp;lt;%=h @post.svg %&amp;gt;"&lt;/span&gt;&lt;span class="synSpecial"&gt;,&lt;/span&gt;&lt;br /&gt;&lt;span class="synSpecial"&gt;                 width:&lt;/span&gt;&lt;span class="synConstant"&gt;"&amp;lt;%= @post.image_width %&amp;gt;"&lt;/span&gt;&lt;span class="synSpecial"&gt;,&lt;/span&gt;&lt;br /&gt;&lt;span class="synSpecial"&gt;                 height:&lt;/span&gt;&lt;span class="synConstant"&gt;"&amp;lt;%= @post.image_height %&amp;gt;"&lt;/span&gt;&lt;span class="synSpecial"&gt;,&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="synSpecial"&gt;                 animation:&lt;/span&gt;60&lt;span class="synSpecial"&gt;,&lt;/span&gt;&lt;br /&gt;&lt;span class="synSpecial"&gt;                 background_image: &lt;/span&gt;&lt;span class="synConstant"&gt;'&amp;lt;%= url_for_file_column(@post, "image") %&amp;gt;'&lt;/span&gt;&lt;span class="synIdentifier"&gt;}&lt;/span&gt;)&lt;span class="synSpecial"&gt;;&lt;/span&gt;&lt;br /&gt;&lt;span class="synComment"&gt;//]]&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="synIdentifier"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="synStatement"&gt;script&lt;/span&gt;&lt;span class="synIdentifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;app/view/posts/edit.rhml&lt;/span&gt;&lt;br /&gt;svgのテキストエリアは非表示にします。変わりにキャンバス用の要素とInputDrawのコードを追加します。編集用に使う場合はid要素でsvgデータを保持している入力コントロールのIDを指定します。&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;span class="synIdentifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="synStatement"&gt;div&lt;/span&gt;&lt;span class="synIdentifier"&gt; &lt;/span&gt;&lt;span class="synType"&gt;id&lt;/span&gt;&lt;span class="synIdentifier"&gt;=&lt;/span&gt;&lt;span class="synConstant"&gt;"place"&lt;/span&gt;&lt;span class="synIdentifier"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="synStatement"&gt;div&lt;/span&gt;&lt;span class="synIdentifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span class="synIdentifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="synStatement"&gt;div&lt;/span&gt;&lt;span class="synIdentifier"&gt; &lt;/span&gt;&lt;span class="synType"&gt;style&lt;/span&gt;&lt;span class="synIdentifier"&gt;=&lt;/span&gt;&lt;span class="synConstant"&gt;"visibility:hidden; display:none"&lt;/span&gt;&lt;span class="synIdentifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;      &lt;span class="synSpecial"&gt;&amp;lt;%=&lt;/span&gt; f.text_area &lt;span class="synIdentifier"&gt;:svg&lt;/span&gt; &lt;span class="synSpecial"&gt;%&amp;gt;&lt;/span&gt;&lt;br /&gt;    &lt;span class="synIdentifier"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="synStatement"&gt;div&lt;/span&gt;&lt;span class="synIdentifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="synComment"&gt;&amp;lt;!-- 末尾に追加 --&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="synIdentifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="synStatement"&gt;script&lt;/span&gt;&lt;span class="synIdentifier"&gt; &lt;/span&gt;&lt;span class="synType"&gt;type&lt;/span&gt;&lt;span class="synIdentifier"&gt;=&lt;/span&gt;&lt;span class="synConstant"&gt;"text/javascript"&lt;/span&gt;&lt;span class="synIdentifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="synComment"&gt;//&amp;lt;[![CDATA&lt;/span&gt;&lt;br /&gt;&lt;span class="synSpecial"&gt;        &lt;/span&gt;&lt;span class="synStatement"&gt;new&lt;/span&gt;&lt;span class="synSpecial"&gt; InputDraw&lt;/span&gt;(&lt;span class="synConstant"&gt;"/javascripts/inputdraw/inputdraw.free-non-commercial.1.2.swf"&lt;/span&gt;&lt;span class="synSpecial"&gt;, &lt;/span&gt;&lt;span class="synConstant"&gt;"place"&lt;/span&gt;&lt;span class="synSpecial"&gt;,&lt;/span&gt;&lt;br /&gt;&lt;span class="synSpecial"&gt;        &lt;/span&gt;&lt;span class="synIdentifier"&gt;{&lt;/span&gt;&lt;span class="synSpecial"&gt;id:&lt;/span&gt;&lt;span class="synConstant"&gt;"post_svg"&lt;/span&gt;&lt;span class="synSpecial"&gt;,&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="synSpecial"&gt;                 width:&lt;/span&gt;&lt;span class="synConstant"&gt;"&amp;lt;%= @post.image_width %&amp;gt;"&lt;/span&gt;&lt;span class="synSpecial"&gt;,&lt;/span&gt;&lt;br /&gt;&lt;span class="synSpecial"&gt;                 height:&lt;/span&gt;&lt;span class="synConstant"&gt;"&amp;lt;%= @post.image_height %&amp;gt;"&lt;/span&gt;&lt;span class="synSpecial"&gt;,&lt;/span&gt;&lt;br /&gt;&lt;span class="synSpecial"&gt;                 animation:&lt;/span&gt;60&lt;span class="synSpecial"&gt;,&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="synSpecial"&gt;                 background_image: &lt;/span&gt;&lt;span class="synConstant"&gt;'&amp;lt;%= url_for_file_column(@post, "image") %&amp;gt;'&lt;/span&gt;&lt;span class="synIdentifier"&gt;}&lt;/span&gt;)&lt;span class="synSpecial"&gt;;     &lt;/span&gt;&lt;br /&gt;&lt;span class="synComment"&gt;//]]&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="synIdentifier"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="synStatement"&gt;script&lt;/span&gt;&lt;span class="synIdentifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;モデルの編集&lt;/h4&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;app/models/post.rb&lt;/span&gt;&lt;br /&gt;file_columnと、ImageSizeのコードを追加します。&lt;br /&gt;&lt;br /&gt;&lt;pre class="syntax-highlight"&gt;&lt;span class="synPreProc"&gt;require&lt;/span&gt; &lt;span class="synSpecial"&gt;'&lt;/span&gt;&lt;span class="synConstant"&gt;rubygems&lt;/span&gt;&lt;span class="synSpecial"&gt;'&lt;/span&gt;&lt;br /&gt;&lt;span class="synPreProc"&gt;require&lt;/span&gt; &lt;span class="synSpecial"&gt;'&lt;/span&gt;&lt;span class="synConstant"&gt;image_size&lt;/span&gt;&lt;span class="synSpecial"&gt;'&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="synPreProc"&gt;class &lt;/span&gt;&lt;span class="synType"&gt;Post&lt;/span&gt; &amp;lt; &lt;span class="synIdentifier"&gt;ActiveRecord&lt;/span&gt;::&lt;span class="synIdentifier"&gt;Base&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  file_column &lt;span class="synIdentifier"&gt;:image&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  &lt;span class="synPreProc"&gt;def &lt;/span&gt;&lt;span class="synIdentifier"&gt;image_width&lt;/span&gt;&lt;br /&gt;    image_file ? image_file.get_width : &lt;span class="synConstant"&gt;0&lt;/span&gt;&lt;br /&gt;  &lt;span class="synPreProc"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  &lt;span class="synPreProc"&gt;def &lt;/span&gt;&lt;span class="synIdentifier"&gt;image_height&lt;/span&gt;&lt;br /&gt;    image_file ? image_file.get_height : &lt;span class="synConstant"&gt;0&lt;/span&gt;&lt;br /&gt;  &lt;span class="synPreProc"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;  &lt;span class="synPreProc"&gt;def &lt;/span&gt;&lt;span class="synIdentifier"&gt;image_file&lt;/span&gt;&lt;br /&gt;    &lt;span class="synStatement"&gt;if&lt;/span&gt; (image &amp;amp;&amp;amp; !&lt;span class="synIdentifier"&gt;@image_file&lt;/span&gt; )&lt;br /&gt;      open(image ,&lt;span class="synSpecial"&gt;"&lt;/span&gt;&lt;span class="synConstant"&gt;rb&lt;/span&gt;&lt;span class="synSpecial"&gt;"&lt;/span&gt;) &lt;span class="synStatement"&gt;do&lt;/span&gt; |&lt;span class="synIdentifier"&gt;img&lt;/span&gt;|&lt;br /&gt;        &lt;span class="synIdentifier"&gt;@image_file&lt;/span&gt; = &lt;span class="synIdentifier"&gt;ImageSize&lt;/span&gt;.new(img)&lt;br /&gt;      &lt;span class="synStatement"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;    &lt;span class="synStatement"&gt;end&lt;/span&gt;&lt;br /&gt;    &lt;span class="synIdentifier"&gt;@image_file&lt;/span&gt;&lt;br /&gt;  &lt;span class="synPreProc"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;span class="synPreProc"&gt;end&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;以上で完成です。あとはサーバを起動してhttp://localhost:3000/postsにアクセスするだけです。&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;参考書籍&lt;/h4&gt;&lt;br /&gt;&lt;iframe src="http://rcm-jp.amazon.co.jp/e/cm?t=usuilog-22&amp;o=9&amp;p=8&amp;l=as1&amp;asins=4274066967&amp;fc1=000000&amp;IS2=1&amp;lt1=_blank&amp;lc1=0000FF&amp;bc1=000000&amp;bg1=FFFFFF&amp;f=ifr" style="width:120px;height:240px;float:left" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"&gt;&lt;/iframe&gt;&lt;br /&gt;Railsを学ぶにはやはりRails開発者であるDavid Heinemeier Hanssonの著書がオススメです。前半はショッピングカートを題材にした実践的なＷｅｂアプリケーションのチュートリアル、後半はActiveRecordなど各コンポーネントの詳細説明とRailsの基本から詳細までが網羅された内容となっています。また、ところどころにある"David曰く"の囲みが面白く、例えば「テーブル名はなぜ複数形にするべきなのか？」といった内容に&lt;br /&gt;&lt;blockquote&gt;テーブル名を複数形にしておくことで、Select a Product from products.(商品テーブルから商品を一つ選択してください）という文章が違和感なく理解できるようになります。&lt;/blockquote&gt;と回答されていたりと、Railsがなぜそういった設計にいたったのかという経緯が解説されていたりします。&lt;br /&gt;&lt;br /&gt;&lt;iframe src="http://rcm-jp.amazon.co.jp/e/cm?t=usuilog-22&amp;o=9&amp;p=13&amp;l=st1&amp;mode=books-jp&amp;search=ruby%20rails&amp;fc1=000000&amp;lt1=&amp;lc1=3366FF&amp;bg1=FFFFFF&amp;f=ifr" marginwidth="0" marginheight="0" width="468" height="60" border="0" frameborder="0" style="border:none;" scrolling="no"&gt;&lt;/iframe&gt;&lt;br /&gt;&lt;br /&gt;&lt;h4&gt;参考&lt;/h4&gt;&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.mainada.net/inputdraw"&gt;&amp;lt;InputDraw/&amp;gt; - The simplest draw editor to your forms&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.popxpop.com/archives/2007/08/javascript_1.html"&gt;フォームで落書きを投稿できるようにするJavascriptライブラリ『&amp;lt;input type=&amp;quot;draw&amp;quot; /&amp;gt;』&lt;br /&gt;&lt;/a&gt;&lt;br /&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2550436420816136794-3723119761592480537?l=usuilog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://usuilog.blogspot.com/feeds/3723119761592480537/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2550436420816136794&amp;postID=3723119761592480537' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2550436420816136794/posts/default/3723119761592480537'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2550436420816136794/posts/default/3723119761592480537'/><link rel='alternate' type='text/html' href='http://usuilog.blogspot.com/2007/08/railsinputdrawrails.html' title='[Ruby][Rails]InputDrawとrailsで作る手書き掲示板'/><author><name>usuihiro</name><uri>http://www.blogger.com/profile/18033487413398851661</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_sX6CD3lBq0Q/RrqvmB8XOgI/AAAAAAAAABg/Vt4-cN_MawE/s72-c/inputdraw.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2550436420816136794.post-4046666085835105797</id><published>2007-06-25T16:07:00.000+09:00</published><updated>2008-12-09T15:54:26.058+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='Programming'/><category scheme='http://www.blogger.com/atom/ns#' term='Ext'/><title type='text'>[JavaScript][Ext]Ext.jsのフォームコンポーネントと入力チェック</title><content type='html'>既存のhtmlを元にJavaScriptでリッチコントロール機能の追加や入力チェックを行う方法を紹介します。Ext1.1 beta1を元にしています。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;基本構文&lt;/span&gt;&lt;br /&gt;&lt;code&gt;&lt;pre class="code"&gt;&lt;span class="synComment"&gt;// フォームオブジェクト生成&lt;/span&gt;&lt;br /&gt;&lt;span class="synIdentifier"&gt;var&lt;/span&gt; comp = &lt;span class="synStatement"&gt;new&lt;/span&gt; Ext.form.TextField();&lt;br /&gt;&lt;span class="synComment"&gt;// HTMLElementへフォームオブジェクトを適用&lt;/span&gt;&lt;br /&gt;comp.applyTo('elem-id');&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;入力エラー時のツールチップを有効にするには以下のコードを入れておく必要があります。&lt;br /&gt;&lt;code&gt;&lt;pre class="code"&gt;Ext.QuickTips.init();&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;DateField&lt;/span&gt;&lt;br /&gt;まずは何かと使い道の多そうなDateField。年/月/日形式にするためにはformatを指定する必要があります。&lt;br /&gt;&lt;code&gt;&lt;pre class="code"&gt;&lt;span class="synIdentifier"&gt;var&lt;/span&gt; &lt;span class="synType"&gt;date&lt;/span&gt; = &lt;span class="synStatement"&gt;new&lt;/span&gt; Ext.form.DateField(&lt;span class="synIdentifier"&gt;{&lt;/span&gt;&lt;br /&gt;    allowBlank:&lt;span class="synConstant"&gt;false&lt;/span&gt;,&lt;br /&gt;    format: &lt;span class="synConstant"&gt;'Y/m/d'&lt;/span&gt;&lt;br /&gt;&lt;span class="synIdentifier"&gt;}&lt;/span&gt;);&lt;br /&gt;&lt;span class="synType"&gt;date&lt;/span&gt;.applyTo(&lt;span class="synConstant"&gt;'birth-input'&lt;/span&gt;);&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;これだけで通常のテキストフィールドにカレンダー入力コントロールと日付チェックを追加できます。&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_sX6CD3lBq0Q/Rn9u_k50ciI/AAAAAAAAABY/XKt3tiu-n98/s1600-h/calendar.jpg"&gt;&lt;img style="margin:0 10px 10px 0;cursor:pointer; cursor:hand;" src="http://4.bp.blogspot.com/_sX6CD3lBq0Q/Rn9u_k50ciI/AAAAAAAAABY/XKt3tiu-n98/s320/calendar.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5079900943214211618" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;入力エラー時はツールチップでエラーメッセージが表示されます。デフォルトでは英語ですが、日本語リソースを読み込むとメッセージも日本語になります。&lt;br /&gt;&lt;code&gt;&lt;pre class="code"&gt;&lt;span class="synStatement"&gt;&amp;lt;script&lt;/span&gt;&lt;span class="synIdentifier"&gt; &lt;/span&gt;&lt;span class="synType"&gt;src&lt;/span&gt;&lt;span class="synIdentifier"&gt;=&lt;/span&gt;&lt;span class="synConstant"&gt;&amp;quot;ext-1.1-beta1/source/locale/ext-lang-ja.js&amp;quot;&lt;/span&gt;&lt;span class="synIdentifier"&gt; &lt;/span&gt;&lt;span class="synType"&gt;type&lt;/span&gt;&lt;span class="synIdentifier"&gt;=&lt;/span&gt;&lt;span class="synConstant"&gt;&amp;quot;text/javascript&amp;quot;&lt;/span&gt;&lt;span class="synIdentifier"&gt; &lt;/span&gt;&lt;span class="synType"&gt;charset&lt;/span&gt;&lt;span class="synIdentifier"&gt;=&lt;/span&gt;&lt;span class="synConstant"&gt;&amp;quot;utf-8&amp;quot;&lt;/span&gt;&lt;span class="synIdentifier"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="synStatement"&gt;script&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_sX6CD3lBq0Q/Rn9uIk50chI/AAAAAAAAABQ/65ckA1jRjYk/s1600-h/validation_error.jpg"&gt;&lt;img style="margin:0 0 10px 10px;cursor:pointer; cursor:hand;" src="http://4.bp.blogspot.com/_sX6CD3lBq0Q/Rn9uIk50chI/AAAAAAAAABQ/65ckA1jRjYk/s320/validation_error.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5079899998321406482" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Validation&lt;/span&gt;&lt;br /&gt;通常のテキストフィールド。フォーマットチェックを行いたい場合はvtypeでvalidation typeを指定します。例えばurlなら以下のような感じ。&lt;br /&gt;&lt;code&gt;&lt;pre class="code"&gt;&lt;span class="synIdentifier"&gt;var&lt;/span&gt; url = &lt;span class="synStatement"&gt;new&lt;/span&gt; Ext.form.TextField(&lt;span class="synIdentifier"&gt;{&lt;/span&gt;&lt;br /&gt;  allowBlank: &lt;span class="synConstant"&gt;false&lt;/span&gt;,&lt;br /&gt;  vtype: &lt;span class="synConstant"&gt;'url'&lt;/span&gt; &lt;span class="synComment"&gt;// SEE ALSO Ext.form.VTypes&lt;/span&gt;&lt;br /&gt;&lt;span class="synIdentifier"&gt;}&lt;/span&gt;);&lt;br /&gt;url.applyTo(&lt;span class="synConstant"&gt;'url-input'&lt;/span&gt;);&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Custom Validation&lt;/span&gt;&lt;br /&gt;続いてemail。vtype: 'email'もできますがDoCoMo式のアットマークの前にピリオドがあるアドレスは通らないのでカスタムバリデーションでやってみます。validationに値一つを受け取るfunctionオブジェクトを設定します。チェックＯＫの場合はtrueを、エラーの場合はエラー文字列を返すという仕様です。&lt;br /&gt;&lt;code&gt;&lt;pre class="code"&gt;&lt;span class="synIdentifier"&gt;var&lt;/span&gt; mail = &lt;span class="synStatement"&gt;new&lt;/span&gt; Ext.form.TextField(&lt;span class="synIdentifier"&gt;{&lt;/span&gt;&lt;br /&gt;  allowBlank: &lt;span class="synConstant"&gt;false&lt;/span&gt;,&lt;br /&gt;  &lt;span class="synComment"&gt;// Custom validation&lt;/span&gt;&lt;br /&gt;  validator: &lt;span class="synIdentifier"&gt;function&lt;/span&gt;(fvalue) &lt;span class="synIdentifier"&gt;{&lt;/span&gt;&lt;br /&gt;   &lt;span class="synComment"&gt;// Ext.form.VTypesより。@の前の.も許可&lt;/span&gt;&lt;br /&gt;   &lt;span class="synIdentifier"&gt;var&lt;/span&gt; email = &lt;span class="synConstant"&gt;/^([\w]+)(.[.\w]+)*@([\w-]+\.){1,5}([A-Za-z]){2,4}$/&lt;/span&gt;;&lt;br /&gt;   &lt;span class="synStatement"&gt;if&lt;/span&gt; (email.test(fvalue)) &lt;span class="synIdentifier"&gt;{&lt;/span&gt;&lt;br /&gt;    &lt;span class="synStatement"&gt;return&lt;/span&gt; &lt;span class="synConstant"&gt;true&lt;/span&gt;;&lt;br /&gt;   &lt;span class="synIdentifier"&gt;}&lt;/span&gt;&lt;br /&gt;   &lt;span class="synStatement"&gt;return&lt;/span&gt; &lt;span class="synType"&gt;String&lt;/span&gt;.format(&lt;span class="synConstant"&gt;'{0}はメールアドレスとして正しくありません。'&lt;/span&gt;, fvalue)&lt;br /&gt;      + Ext.form.VTypes.emailText;&lt;br /&gt;  &lt;span class="synIdentifier"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span class="synIdentifier"&gt;}&lt;/span&gt;);&lt;br /&gt;mail.applyTo(&lt;span class="synConstant"&gt;'mail-input'&lt;/span&gt;);&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Number Field&lt;/span&gt;&lt;br /&gt;数値のみ許可する入力フィールド。アルファベットが入力できなくなります(日本語は残念ながらOK)&lt;br /&gt;&lt;code&gt;&lt;pre class="code"&gt;&lt;span class="synIdentifier"&gt;var&lt;/span&gt; income = &lt;span class="synStatement"&gt;new&lt;/span&gt; Ext.form.NumberField(&lt;span class="synIdentifier"&gt;{&lt;/span&gt;&lt;br /&gt; allowBlank: &lt;span class="synConstant"&gt;false&lt;/span&gt;&lt;br /&gt;&lt;span class="synIdentifier"&gt;}&lt;/span&gt;);&lt;br /&gt;income.applyTo(&lt;span class="synConstant"&gt;'income-input'&lt;/span&gt;);&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Combo Box&lt;/span&gt;&lt;br /&gt;select要素からExt.form.Comboboxオブジェクトにするのは少し違う手順。applyToするのではなくtransformで元になるselect要素を指定します。&lt;br /&gt;&lt;code&gt;&lt;pre class="code"&gt;&lt;span class="synIdentifier"&gt;var&lt;/span&gt; combo = &lt;span class="synStatement"&gt;new&lt;/span&gt; Ext.form.ComboBox(&lt;span class="synIdentifier"&gt;{&lt;/span&gt;&lt;br /&gt;    typeAhead: &lt;span class="synConstant"&gt;true&lt;/span&gt;,&lt;br /&gt;    triggerAction: &lt;span class="synConstant"&gt;'all'&lt;/span&gt;,&lt;br /&gt;    width:135,&lt;br /&gt;    forceSelection:&lt;span class="synConstant"&gt;true&lt;/span&gt;,&lt;br /&gt;    transform: &lt;span class="synConstant"&gt;'blood-select'&lt;/span&gt;&lt;br /&gt;&lt;span class="synIdentifier"&gt;}&lt;/span&gt;);&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Textarea&lt;/span&gt;&lt;br /&gt;&lt;code&gt;&lt;pre class="code"&gt;テキストエリアも同様です。growを設定しておくと入力量に応じてエリアが自動的に拡張されます。&lt;br /&gt;&lt;span class="synIdentifier"&gt;var&lt;/span&gt; carrier = &lt;span class="synStatement"&gt;new&lt;/span&gt; Ext.form.TextArea(&lt;span class="synIdentifier"&gt;{&lt;/span&gt;&lt;br /&gt;    grow: &lt;span class="synConstant"&gt;true&lt;/span&gt;, &lt;span class="synComment"&gt;// 入力量に応じてテキストエリアが拡張される&lt;/span&gt;&lt;br /&gt;    growMax: 200&lt;br /&gt;&lt;span class="synIdentifier"&gt;}&lt;/span&gt;);&lt;br /&gt;carrier.applyTo(&lt;span class="synConstant"&gt;'carrier-area'&lt;/span&gt;)&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Html Editor&lt;/span&gt;&lt;br /&gt;Ext1.1からWYSIWYGなhtmlエディターコンポーネントが追加になっています。これも使い方は同様。&lt;br /&gt;&lt;code&gt;&lt;pre class="code"&gt;&lt;span class="synIdentifier"&gt;var&lt;/span&gt; promo = &lt;span class="synStatement"&gt;new&lt;/span&gt; Ext.form.HtmlEditor(&lt;span class="synIdentifier"&gt;{&lt;/span&gt;&lt;br /&gt;    width: 600,&lt;br /&gt;    height: 300&lt;br /&gt;&lt;span class="synIdentifier"&gt;}&lt;/span&gt;);&lt;br /&gt;promo.applyTo(&lt;span class="synConstant"&gt;'promotion-area'&lt;/span&gt;);&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;JavaScriptでフォームをデザインするサンプルは以下にあります。個人的にはデザインとロジックの分離ができる後からコントロールを追加するパターンの方が好みです。(サンプルでform.htmlが有りますがまだ作りかけなようです）&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;参考&lt;/span&gt;&lt;br /&gt;&lt;ul id="references"&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://extjs.com/deploy/ext/examples/form/dynamic.html"&gt;Dynamic Forms built with JavaScript&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://d.hatena.ne.jp/usuihiro1978/20070625#1182755251"&gt;[JavaScript][Ext]フォームコントロールと入力チェック・・・全ソースはこちら&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://usuilog.blogspot.com/2007/06/javascriptext.html"&gt;[JavaScript][Ext]ソート可能なテーブルを実装する&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://usuilog.blogspot.com/2007/05/javascriptextextjscore.html"&gt;[JavaScript][Ext]Ext.jsの使い方メモ(Core機能)&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.saturn.dti.ne.jp/~npaka/ajax/ext/index.html"&gt;Ext JSメモ&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://journal.mycom.co.jp/articles/2007/04/21/ext/"&gt;【ハウツー】Apolloのサンプルで使われた、美しきJavaScriptフレームワーク「Ext 1.0」 | エンタープライズ | マイコミジャーナル&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;iframe src="http://rcm-jp.amazon.co.jp/e/cm?t=usuilog-22&amp;o=9&amp;p=13&amp;l=st1&amp;mode=books-jp&amp;search=javascript&amp;fc1=000000&amp;lt1=&amp;lc1=3366FF&amp;bg1=FFFFFF&amp;f=ifr" marginwidth="0" marginheight="0" width="468" height="60" border="0" frameborder="0" style="border:none;" scrolling="no"&gt;&lt;/iframe&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2550436420816136794-4046666085835105797?l=usuilog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://usuilog.blogspot.com/feeds/4046666085835105797/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2550436420816136794&amp;postID=4046666085835105797' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2550436420816136794/posts/default/4046666085835105797'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2550436420816136794/posts/default/4046666085835105797'/><link rel='alternate' type='text/html' href='http://usuilog.blogspot.com/2007/06/javascriptextextjs.html' title='[JavaScript][Ext]Ext.jsのフォームコンポーネントと入力チェック'/><author><name>usuihiro</name><uri>http://www.blogger.com/profile/18033487413398851661</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_sX6CD3lBq0Q/Rn9u_k50ciI/AAAAAAAAABY/XKt3tiu-n98/s72-c/calendar.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2550436420816136794.post-8832486160936455753</id><published>2007-06-12T20:15:00.000+09:00</published><updated>2008-12-09T15:54:26.183+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='Programming'/><category scheme='http://www.blogger.com/atom/ns#' term='Ext'/><title type='text'>[JavaScript][Ext]ソート可能なテーブルを実装する</title><content type='html'>&lt;a href="http://www.moongift.jp/2007/06/table_sorter/"&gt;絶対お勧め！JavaScriptでテーブルソート「Table Sorter」&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;blockquote cite="http://www.moongift.jp/2007/06/table_sorter/"&gt;&lt;br /&gt;普通のテーブルタグに対して、ヘッダ部分はtheadタグとthタグで作るだけでいい。データ部分は全体をtbodyタグで囲んで、tdタグで記述するだけだ。&lt;br /&gt;&lt;/blockquote&gt;&lt;br /&gt;&lt;br /&gt;Extを使っても同様の方法でソート可能なテーブルを実装できます。&lt;br /&gt;以下のサンプルからExt.grid.TableGridクラスをもらってきて使うだけです。&lt;br /&gt;&lt;br /&gt;&lt;a href="http://extjs.com/deploy/ext/examples/grid/from-markup.html"&gt;From Markup Grid Example&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Script&lt;/span&gt;&lt;br /&gt;&lt;code&gt;&lt;pre&gt;&lt;span class="synType"&gt;var&lt;/span&gt; grid = &lt;span class="synStatement"&gt;new&lt;/span&gt; Ext.grid.TableGrid('the-table');&lt;br /&gt;grid.render();&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;ロード時にページ内のテーブル全てに適用したければ下記のような感じでＯＫです。&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;pre&gt;Ext.onReady(function() &lt;span class="synIdentifier"&gt;{&lt;/span&gt;&lt;br /&gt;    Ext.select(&lt;span class="synConstant"&gt;'table'&lt;/span&gt;).each(function (e) &lt;span class="synIdentifier"&gt;{&lt;/span&gt;&lt;br /&gt;        var grid = new Ext.grid.TableGrid(e);&lt;br /&gt;        grid.render();&lt;br /&gt;    &lt;span class="synIdentifier"&gt;}&lt;/span&gt; )&lt;br /&gt;&lt;span class="synIdentifier"&gt;}&lt;/span&gt;);&lt;br /&gt;&lt;/pre&gt;&lt;/code&gt;&lt;br /&gt;&lt;br /&gt;このGridはかなり高機能で、列クリックによるソートだけではなく、ドラッグによる列の入れ替えや、&lt;br /&gt;ポップアップメニューでの表示列の切り替え、列の固定なども行えます。&lt;br /&gt;インクルードファイルの数やリソースの数など設置は若干大変ですが、それさえ乗り越えればかなり手軽でよいと思います。&lt;br /&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_sX6CD3lBq0Q/Rm6CmU50cfI/AAAAAAAAABA/a5I5ciMro_I/s1600-h/ext_table_grid.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://2.bp.blogspot.com/_sX6CD3lBq0Q/Rm6CmU50cfI/AAAAAAAAABA/a5I5ciMro_I/s320/ext_table_grid.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5075137425050989042" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;参考&lt;/span&gt;&lt;br /&gt;&lt;ul id="references"&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://usuilog.blogspot.com/2007/05/javascriptextextjscore.html"&gt;[JavaScript][Ext]Ext.jsの使い方メモ(Core機能)&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://usuilog.blogspot.com/2007/04/javascriptextjs-10.html"&gt;[JavaScript]Ext.js 1.0が正式リリース&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.saturn.dti.ne.jp/~npaka/ajax/ext/index.html"&gt;Ext JSメモ&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://journal.mycom.co.jp/articles/2007/04/21/ext/"&gt;【ハウツー】Apolloのサンプルで使われた、美しきJavaScriptフレームワーク「Ext 1.0」 | エンタープライズ | マイコミジャーナル&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;iframe src="http://rcm-jp.amazon.co.jp/e/cm?t=usuilog-22&amp;o=9&amp;p=13&amp;l=st1&amp;mode=books-jp&amp;search=javascript&amp;fc1=000000&amp;lt1=&amp;lc1=3366FF&amp;bg1=FFFFFF&amp;f=ifr" marginwidth="0" marginheight="0" width="468" height="60" border="0" frameborder="0" style="border:none;" scrolling="no"&gt;&lt;/iframe&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2550436420816136794-8832486160936455753?l=usuilog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://usuilog.blogspot.com/feeds/8832486160936455753/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2550436420816136794&amp;postID=8832486160936455753' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2550436420816136794/posts/default/8832486160936455753'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2550436420816136794/posts/default/8832486160936455753'/><link rel='alternate' type='text/html' href='http://usuilog.blogspot.com/2007/06/javascriptext.html' title='[JavaScript][Ext]ソート可能なテーブルを実装する'/><author><name>usuihiro</name><uri>http://www.blogger.com/profile/18033487413398851661</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_sX6CD3lBq0Q/Rm6CmU50cfI/AAAAAAAAABA/a5I5ciMro_I/s72-c/ext_table_grid.jpg' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2550436420816136794.post-1407939413029513479</id><published>2007-05-22T19:38:00.000+09:00</published><updated>2007-05-25T14:27:13.020+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='Programming'/><category scheme='http://www.blogger.com/atom/ns#' term='Ext'/><title type='text'>[JavaScript][Ext]Ext.jsの使い方メモ(Core機能)</title><content type='html'>Ext.jsの使い方メモです。Core機能をまとめてみようと思います。&lt;br /&gt;&lt;br /&gt;最初に必要なライブラリを読み込みます。(ext-1.0に展開されたソースがある前提)&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;span class="synIdentifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="synStatement"&gt;script&lt;/span&gt;&lt;span class="synIdentifier"&gt; &lt;/span&gt;&lt;span class="synType"&gt;src&lt;/span&gt;&lt;span class="synIdentifier"&gt;=&lt;/span&gt;&lt;span class="synConstant"&gt;&amp;quot;ext-1.0/adapter/yui/yui-utilities.js&amp;quot;&lt;/span&gt;&lt;span class="synIdentifier"&gt; &lt;/span&gt;&lt;span class="synType"&gt;type&lt;/span&gt;&lt;span class="synIdentifier"&gt;=&lt;/span&gt;&lt;span class="synConstant"&gt;&amp;quot;text/javascript&amp;quot;&lt;/span&gt;&lt;span class="synIdentifier"&gt; &lt;/span&gt;&lt;span class="synType"&gt;charset&lt;/span&gt;&lt;span class="synIdentifier"&gt;=&lt;/span&gt;&lt;span class="synConstant"&gt;&amp;quot;utf-8&amp;quot;&lt;/span&gt;&lt;span class="synIdentifier"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="synStatement"&gt;script&lt;/span&gt;&lt;span class="synIdentifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="synIdentifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="synStatement"&gt;script&lt;/span&gt;&lt;span class="synIdentifier"&gt; &lt;/span&gt;&lt;span class="synType"&gt;src&lt;/span&gt;&lt;span class="synIdentifier"&gt;=&lt;/span&gt;&lt;span class="synConstant"&gt;&amp;quot;ext-1.0/adapter/yui/ext-yui-adapter.js&amp;quot;&lt;/span&gt;&lt;span class="synIdentifier"&gt; &lt;/span&gt;&lt;span class="synType"&gt;type&lt;/span&gt;&lt;span class="synIdentifier"&gt;=&lt;/span&gt;&lt;span class="synConstant"&gt;&amp;quot;text/javascript&amp;quot;&lt;/span&gt;&lt;span class="synIdentifier"&gt; &lt;/span&gt;&lt;span class="synType"&gt;charset&lt;/span&gt;&lt;span class="synIdentifier"&gt;=&lt;/span&gt;&lt;span class="synConstant"&gt;&amp;quot;utf-8&amp;quot;&lt;/span&gt;&lt;span class="synIdentifier"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="synStatement"&gt;script&lt;/span&gt;&lt;span class="synIdentifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="synIdentifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="synStatement"&gt;script&lt;/span&gt;&lt;span class="synIdentifier"&gt; &lt;/span&gt;&lt;span class="synType"&gt;src&lt;/span&gt;&lt;span class="synIdentifier"&gt;=&lt;/span&gt;&lt;span class="synConstant"&gt;&amp;quot;ext-1.0/ext-all-debug.js&amp;quot;&lt;/span&gt;&lt;span class="synIdentifier"&gt; &lt;/span&gt;&lt;span class="synType"&gt;type&lt;/span&gt;&lt;span class="synIdentifier"&gt;=&lt;/span&gt;&lt;span class="synConstant"&gt;&amp;quot;text/javascript&amp;quot;&lt;/span&gt;&lt;span class="synIdentifier"&gt; &lt;/span&gt;&lt;span class="synType"&gt;charset&lt;/span&gt;&lt;span class="synIdentifier"&gt;=&lt;/span&gt;&lt;span class="synConstant"&gt;&amp;quot;utf-8&amp;quot;&lt;/span&gt;&lt;span class="synIdentifier"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="synStatement"&gt;script&lt;/span&gt;&lt;span class="synIdentifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;スタイルシートの読み込みます。&lt;br /&gt;自分で全部定義するのは大変なので付属のものを使います。&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;span class="synIdentifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="synStatement"&gt;link&lt;/span&gt;&lt;span class="synIdentifier"&gt; &lt;/span&gt;&lt;span class="synType"&gt;rel&lt;/span&gt;&lt;span class="synIdentifier"&gt;=&lt;/span&gt;&lt;span class="synConstant"&gt;&amp;quot;stylesheet&amp;quot;&lt;/span&gt;&lt;span class="synIdentifier"&gt; &lt;/span&gt;&lt;span class="synType"&gt;href&lt;/span&gt;&lt;span class="synIdentifier"&gt;=&lt;/span&gt;&lt;span class="synConstant"&gt;&amp;quot;ext-1.0/resources/css/ext-all.css&amp;quot;&lt;/span&gt;&lt;span class="synIdentifier"&gt; &lt;/span&gt;&lt;span class="synType"&gt;type&lt;/span&gt;&lt;span class="synIdentifier"&gt;=&lt;/span&gt;&lt;span class="synConstant"&gt;&amp;quot;text/css&amp;quot;&lt;/span&gt;&lt;span class="synIdentifier"&gt; &lt;/span&gt;&lt;span class="synType"&gt;media&lt;/span&gt;&lt;span class="synIdentifier"&gt;=&lt;/span&gt;&lt;span class="synConstant"&gt;&amp;quot;screen&amp;quot;&lt;/span&gt;&lt;span class="synIdentifier"&gt; &lt;/span&gt;&lt;span class="synType"&gt;charset&lt;/span&gt;&lt;span class="synIdentifier"&gt;=&lt;/span&gt;&lt;span class="synConstant"&gt;&amp;quot;utf-8&amp;quot;&lt;/span&gt;&lt;span class="synIdentifier"&gt; /&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;テーマを変更したい場合は上に加えてythema-xxx.cssを読み込むだけです。&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;span class="synIdentifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="synStatement"&gt;link&lt;/span&gt;&lt;span class="synIdentifier"&gt; &lt;/span&gt;&lt;span class="synType"&gt;rel&lt;/span&gt;&lt;span class="synIdentifier"&gt;=&lt;/span&gt;&lt;span class="synConstant"&gt;&amp;quot;stylesheet&amp;quot;&lt;/span&gt;&lt;span class="synIdentifier"&gt; &lt;/span&gt;&lt;span class="synType"&gt;href&lt;/span&gt;&lt;span class="synIdentifier"&gt;=&lt;/span&gt;&lt;span class="synConstant"&gt;&amp;quot;ext-1.0/resources/css/ythema-aero.css&amp;quot;&lt;/span&gt;&lt;span class="synIdentifier"&gt; &lt;/span&gt;&lt;span class="synType"&gt;type&lt;/span&gt;&lt;span class="synIdentifier"&gt;=&lt;/span&gt;&lt;span class="synConstant"&gt;&amp;quot;text/css&amp;quot;&lt;/span&gt;&lt;span class="synIdentifier"&gt; &lt;/span&gt;&lt;span class="synType"&gt;media&lt;/span&gt;&lt;span class="synIdentifier"&gt;=&lt;/span&gt;&lt;span class="synConstant"&gt;&amp;quot;screen&amp;quot;&lt;/span&gt;&lt;span class="synIdentifier"&gt; &lt;/span&gt;&lt;span class="synType"&gt;charset&lt;/span&gt;&lt;span class="synIdentifier"&gt;=&lt;/span&gt;&lt;span class="synConstant"&gt;&amp;quot;utf-8&amp;quot;&lt;/span&gt;&lt;span class="synIdentifier"&gt; /&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;基本はExt.Elementオブジェクトです。&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;span class="synType"&gt;var&lt;/span&gt; elem = Ext.get(&lt;span class="synConstant"&gt;'my-div'&lt;/span&gt;);&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;でExt.Elementオブジェクトが返ってきます。これはHTMLElementオブジェクトをラップしたオブジェクトで、各種プロパティの設定／取得や、アニメーション、AJAX機能が利用できます。&lt;br /&gt;&lt;br /&gt;表示非表示の切り替えは、show(), hide()メソッドでそれぞれ行います。&lt;br /&gt;&lt;pre&gt;&lt;code&gt;elem.show();&lt;br /&gt;elem.hide();&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;デフォルトではvisibilityプロパティを変更して表示／非表示を制御します。&lt;br /&gt;要素ブロックごと消したい場合はenableDisplayMode()としてからそれぞれのメソッドを呼び出すとdisplayプロパティで表示／非表示を切り替えてくれます。&lt;br /&gt;&lt;pre&gt;&lt;code&gt;elem.enableDisplayMode();&lt;br /&gt;elem.hide();&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;イベントハンドラの設定&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;イベントハンドラの設定はExt.Element.onメソッドで行います。これはxt.Element.addListnerのaliasになっています。&lt;br /&gt;&lt;pre&gt;&lt;code&gt;elem.on(&lt;span class="synConstant"&gt;'click'&lt;/span&gt;, function(event, target) &lt;span class="synIdentifier"&gt;{&lt;/span&gt;&lt;br /&gt;    // 処理&lt;br /&gt;&lt;span class="synIdentifier"&gt;}&lt;/span&gt;);&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;ハンドラの第一引数はExt.EventObject、第２引数はイベントソースのHTMLElementオブジェクトとなります。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;アニメーションエフェクト&lt;/span&gt;&lt;br /&gt;エフェクト系はExt.Fxで定義されています。&lt;br /&gt;Ext.FxのメソッドはExt.Elementのprototypeにコピー(Ext.apply)されているので、Ext.Elementオブジェクト経由なら特に意識することなく利用できます。&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;code&gt;elem.highlight();&lt;br /&gt;elem.fadeOut();&lt;br /&gt;elem.fadeIn();&lt;br /&gt;elem.switchOff();&lt;br /&gt;elem.switchOn();&lt;br /&gt;&lt;span class="synComment"&gt;// etc...&lt;/span&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;またFx系のメソッドはElementが返ってくるので、でつないでアニメーションチェーンにすることができます。&lt;br /&gt;&lt;pre&gt;&lt;code&gt;elem.highlight().fadeOut().fadeIn().switchOff().switchOn();&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;セレクター&lt;/span&gt;&lt;br /&gt;CSSセレクターで要素を選択するにはExt.selectメソッドを使用します。&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;span class="synType"&gt;var&lt;/span&gt; elems = Ext.select(&lt;span class="synConstant"&gt;'.myclass'&lt;/span&gt;);&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;戻り値はExt.CompositeElementオブジェクトです。こちらは名前のとおりCompositeパターンに&lt;br /&gt;なっているので、Ext.Elementのメソッドを呼び出すと透過的に全てのオブジェクトに対して&lt;br /&gt;メソッドが呼び出されます。&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;span class="synComment"&gt;// myclassクラスが設定されている全ての要素に対してclickイベントハンドラを設定&lt;/span&gt;&lt;br /&gt;elems.on(&lt;span class="synConstant"&gt;'click'&lt;/span&gt;, function() &lt;span class="synIdentifier"&gt;{&lt;/span&gt; ... &lt;span class="synIdentifier"&gt;}&lt;/span&gt; );&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;要素を一つずつ処理する場合はeachを使います。途中でbreakしたい場合はfalseを返します。&lt;br /&gt;continueは単にreturnです。&lt;br /&gt;&lt;pre&gt;&lt;code&gt;elems.each(function (elem) &lt;span class="synIdentifier"&gt;{&lt;/span&gt;&lt;br /&gt;    if ( condition ) &lt;span class="synIdentifier"&gt;{&lt;/span&gt;&lt;br /&gt;        // ... なんらかの処理&lt;br /&gt;        return &lt;span class="synConstant"&gt;false&lt;/span&gt;; // breakする&lt;br /&gt;    &lt;span class="synIdentifier"&gt;}&lt;/span&gt; else &lt;span class="synIdentifier"&gt;{&lt;/span&gt;&lt;br /&gt;        // ... なんらかの処理&lt;br /&gt;        return; // continueする&lt;br /&gt;    &lt;span class="synIdentifier"&gt;}&lt;/span&gt;;&lt;br /&gt;    // ...&lt;br /&gt;&lt;span class="synIdentifier"&gt;}&lt;/span&gt;);&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;&lt;br /&gt;XPathセレクター&lt;/span&gt;&lt;br /&gt;XPathで要素を選択するにはExt.queryメソッドを使います。こちらはDomQuery.selectのaliasです。&lt;br /&gt;こちらの戻り値はExt.CompositeElementではなくHTMLElementのArrayオブジェクトとなります。&lt;br /&gt;おそらくExt.queryの実装であるDomQueryクラスがExtに依存しないようにするためだと思われます。&lt;br /&gt;&lt;br /&gt;Ext.Elementオブジェクトに対してselect, queryを行うと、その要素の子要素以下に限定して&lt;br /&gt;要素を選択します。&lt;br /&gt;&lt;pre&gt;&lt;code&gt;elem.select(&lt;span class="synConstant"&gt;'.myclass'&lt;/span&gt;) &lt;span class="synComment"&gt;// same as '#' + elem.dom.id + ' .myclass';&lt;/span&gt;&lt;br /&gt;elem.query(&lt;span class="synConstant"&gt;'.myclass'&lt;/span&gt;) &lt;span class="synComment"&gt;// same as '#' + elem.dom.id + ' .myclass';&lt;/span&gt;&lt;br /&gt;&lt;/code&gt;&lt;/pre&gt;&lt;br /&gt;ただselectの方はグループ化に対応していない(1.0.1a)らしく最初のセレクターにしかidを追加して&lt;br /&gt;くれないようです。(queryの方は上手くいく）&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.mindomo.com/main.php"&gt;Mindomo&lt;/a&gt;で&lt;a href="http://www.mindomo.com/view.php?m=66f72c96c2a37b1392447d255830631b"&gt;マインドマップ&lt;/a&gt;にしてみました。&lt;br /&gt;&lt;br /&gt;次はAJAX周りで遊んで見る予定。&lt;br /&gt;&lt;br /&gt;参考&lt;br /&gt;&lt;ul id="references"&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://usuilog.blogspot.com/2007/04/javascriptextjs-10.html"&gt;[JavaScript]Ext.js 1.0が正式リリース&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://www.saturn.dti.ne.jp/~npaka/ajax/ext/index.html"&gt;Ext JSメモ&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;li&gt;&lt;a href="http://journal.mycom.co.jp/articles/2007/04/21/ext/"&gt;【ハウツー】Apolloのサンプルで使われた、美しきJavaScriptフレームワーク「Ext 1.0」 | エンタープライズ | マイコミジャーナル&lt;/a&gt;&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;&lt;br /&gt;&lt;iframe src="http://rcm-jp.amazon.co.jp/e/cm?t=usuilog-22&amp;o=9&amp;p=13&amp;l=st1&amp;mode=books-jp&amp;search=javascript&amp;fc1=000000&amp;lt1=&amp;lc1=3366FF&amp;bg1=FFFFFF&amp;f=ifr" marginwidth="0" marginheight="0" width="468" height="60" border="0" frameborder="0" style="border:none;" scrolling="no"&gt;&lt;/iframe&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2550436420816136794-1407939413029513479?l=usuilog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://usuilog.blogspot.com/feeds/1407939413029513479/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2550436420816136794&amp;postID=1407939413029513479' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2550436420816136794/posts/default/1407939413029513479'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2550436420816136794/posts/default/1407939413029513479'/><link rel='alternate' type='text/html' href='http://usuilog.blogspot.com/2007/05/javascriptextextjscore.html' title='[JavaScript][Ext]Ext.jsの使い方メモ(Core機能)'/><author><name>usuihiro</name><uri>http://www.blogger.com/profile/18033487413398851661</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2550436420816136794.post-5237275601637185427</id><published>2007-04-19T10:35:00.000+09:00</published><updated>2007-04-19T12:47:45.590+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='Ext'/><title type='text'>[JavaScript]Ext.js 1.0が正式リリース</title><content type='html'>リッチなJavaScriptライブラリのExt.jsが正式リリースされたようです。&lt;br /&gt;&lt;br /&gt;&lt;a href="http://extjs.com/deploy/ext/docs/index.html"&gt;サンプル&lt;/a&gt;のようにかなりカッコイイコンポーネントが用意されています。&lt;a href="http://extjs.com/learn-about-ext-javascript-library"&gt;ドキュメント&lt;/a&gt;も充実していて結構使いやすい印象です。&lt;br /&gt;&lt;br /&gt;最近話題のApolloでも、サンプルアプリケーションで使われていたりします。&lt;br /&gt;&lt;a href="http://labs.adobe.com/wiki/index.php/Apollo:Applications:Samples"&gt;Fresh Reader&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;また&lt;a href="http://phpspot.org/blog/archives/2007/03/javascriptextpr.html"&gt;超リッチJavaScriptコンポーネント集「Ext」がprototype.jsに対応&lt;/a&gt;にもあるようにCoreとなるライブラリを切り替えられるというのもユニークな点かと思います。&lt;br /&gt;&lt;br /&gt;さらに全てをダウンロードしなくても、必要な部分だけをbuildしてダウンロードさせてくれる&lt;a href="http://extjs.com/download/build"&gt;サービス&lt;/a&gt;も公開されています。&lt;br /&gt;コアライブラリを選択し必要なコンポーネントを選択すると、その分だけのコードをまとめてダウンロードできます。ただしcssや画像などは別途ダウンロードしておく必要があるようです。（zip中のresourcesを使う）&lt;br /&gt;&lt;br /&gt;UIコンポーネント以外でも&lt;a href="http://www.jackslocum.com/blog/2007/01/11/domquery-css-selector-basic-xpath-implementation-with-benchmarks/"&gt;DomQuery&lt;/a&gt;も便利そうです。XPath、CSSセレクターで、CSS3レベルのセレクターをほぼサポートしていて、しかもかなり高速とのこと。CSSセレクターの実装はブラウザによって結構差がありますが、これを使えばそういった心配もいらないので助かりそうです。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2550436420816136794-5237275601637185427?l=usuilog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://usuilog.blogspot.com/feeds/5237275601637185427/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2550436420816136794&amp;postID=5237275601637185427' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2550436420816136794/posts/default/5237275601637185427'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2550436420816136794/posts/default/5237275601637185427'/><link rel='alternate' type='text/html' href='http://usuilog.blogspot.com/2007/04/javascriptextjs-10.html' title='[JavaScript]Ext.js 1.0が正式リリース'/><author><name>usuihiro</name><uri>http://www.blogger.com/profile/18033487413398851661</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2550436420816136794.post-5808227550406506249</id><published>2007-01-29T17:57:00.000+09:00</published><updated>2007-02-06T11:07:38.664+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programming'/><category scheme='http://www.blogger.com/atom/ns#' term='Testing'/><category scheme='http://www.blogger.com/atom/ns#' term='Perl'/><category scheme='http://www.blogger.com/atom/ns#' term='Selenium'/><title type='text'>[Testing][Perl]Test::WWW::SeleniumでPerlからSelenium RCを操作する</title><content type='html'>Selenium IDEを使うとhtmlの各種プログラミング言語用のテストコードも出力してくれます。&lt;br /&gt;Perlの場合は&lt;a href="http://search.cpan.org/~lukec/Test-WWW-Selenium/"&gt;Test::WWW::Selenium&lt;/a&gt;モジュールを利用します。&lt;br /&gt;&lt;br /&gt;前記事「&lt;a href="http://usuilog.blogspot.com/2007/01/testingselenium-rcselenium-idewebui.html"&gt;Selenium RCとSelenium IDEでWEBアプリのUIテストを簡単自動化&lt;/a&gt;」の操作で出力されるPerlコードは以下のようになります。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;Selenium IDEによって出力されるコード&lt;/span&gt;&lt;br /&gt;&lt;pre&gt;&lt;span class="synStatement"&gt;use strict&lt;/span&gt;;&lt;br /&gt;&lt;span class="synStatement"&gt;use warnings&lt;/span&gt;;&lt;br /&gt;&lt;span class="synStatement"&gt;use &lt;/span&gt;Time::HiRes &lt;span class="synConstant"&gt;qw(sleep)&lt;/span&gt;;&lt;br /&gt;&lt;span class="synStatement"&gt;use &lt;/span&gt;Test::WWW::Selenium;&lt;br /&gt;&lt;span class="synStatement"&gt;use &lt;/span&gt;Test::More &lt;span class="synConstant"&gt;&amp;quot;no_plan&amp;quot;&lt;/span&gt;;&lt;br /&gt;&lt;span class="synStatement"&gt;use &lt;/span&gt;Test::Exception;&lt;br /&gt;&lt;br /&gt;&lt;span class="synStatement"&gt;my&lt;/span&gt; &lt;span class="synIdentifier"&gt;$sel&lt;/span&gt; = Test::WWW::Selenium-&amp;gt;&lt;span class="synStatement"&gt;new&lt;/span&gt;( &lt;span class="synConstant"&gt;host &lt;/span&gt;=&amp;gt; &lt;span class="synConstant"&gt;&amp;quot;localhost&amp;quot;&lt;/span&gt;, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="synConstant"&gt;port &lt;/span&gt;=&amp;gt; &lt;span class="synConstant"&gt;4444&lt;/span&gt;, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="synConstant"&gt;browser &lt;/span&gt;=&amp;gt; &lt;span class="synConstant"&gt;&amp;quot;*firefox&amp;quot;&lt;/span&gt;, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="synConstant"&gt;browser_url &lt;/span&gt;=&amp;gt; &lt;span class="synConstant"&gt;&amp;quot;http://localhost:4444&amp;quot;&lt;/span&gt; );&lt;br /&gt;&lt;br /&gt;&lt;span class="synIdentifier"&gt;$sel&lt;/span&gt;-&amp;gt;open_ok(&lt;span class="synConstant"&gt;&amp;quot;/&amp;quot;&lt;/span&gt;);&lt;br /&gt;&lt;span class="synIdentifier"&gt;$sel&lt;/span&gt;-&amp;gt;type_ok(&lt;span class="synConstant"&gt;&amp;quot;q&amp;quot;&lt;/span&gt;, &lt;span class="synConstant"&gt;&amp;quot;Perl&amp;quot;&lt;/span&gt;);&lt;br /&gt;&lt;span class="synIdentifier"&gt;$sel&lt;/span&gt;-&amp;gt;click_ok(&lt;span class="synConstant"&gt;&amp;quot;btnG&amp;quot;&lt;/span&gt;);&lt;br /&gt;&lt;span class="synIdentifier"&gt;$sel&lt;/span&gt;-&amp;gt;wait_for_page_to_load_ok(&lt;span class="synConstant"&gt;&amp;quot;30000&amp;quot;&lt;/span&gt;);&lt;br /&gt;&lt;span class="synIdentifier"&gt;$sel&lt;/span&gt;-&amp;gt;is_text_present_ok(&lt;span class="synConstant"&gt;&amp;quot;Perl の検索結果&amp;quot;&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;スクリプトはutf8で保存します。browser_urlがlocalhostになってしまうようなのでwww.google.co.jpに変更します。&lt;br /&gt;&lt;br /&gt;スクリプト実行前にSelenium RCを起動しておきます。&lt;br /&gt;&lt;pre class="console"&gt;java -jar selenium-server.jar&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;続いてテストスクリプトを実行します。&lt;br /&gt;&lt;pre class="console"&gt;ok 1 - open, /&lt;br /&gt;ok 2 - type, q, Perl&lt;br /&gt;ok 3 - click, btnG&lt;br /&gt;ok 4 - wait_for_page_to_load, 30000&lt;br /&gt;not ok 5 - is_text_present, Perl の検索結果&lt;br /&gt;#   Failed test 'is_text_present, Perl の検索結果'&lt;br /&gt;#   at test_utf8.t line 19.&lt;br /&gt;1..5&lt;br /&gt;# Looks like you failed 1 test of 5.&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;最後のテストで失敗してしまいました。verboseモードを使って実行手順をトレースしてみまると以下のようなコードを送信しているようでした。&lt;br /&gt;&lt;pre class="console"&gt;---&gt; Requesting http://localhost:4444/selenium-server/driver/?cmd=isTextPresent&amp;1=Perl%20%C3%A3%C2%81%C2%AE%C3%A6%C2%A4%C2%9C%C3%A7%C2%B4%C2%A2%C3%A7%C2%B5%C2%90%C3%A6%C2%9E%C2%9C&amp;sessionId=1170055300866&lt;br /&gt;Got result: OK,false&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;日本語の部分がおかしいようなのでコードを追ってみると以下のようにutf8フラグ付を前提としているようです。&lt;br /&gt;&lt;pre&gt;URI::Escape::uri_escape_utf8(&lt;span class="synStatement"&gt;shift&lt;/span&gt; &lt;span class="synIdentifier"&gt;@args&lt;/span&gt;);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;テストスクリプトにuse utf8をつけて再度実行してみます。&lt;br /&gt;&lt;pre class="console"&gt;ok 1 - open, /&lt;br /&gt;ok 2 - type, q, Perl&lt;br /&gt;ok 3 - click, btnG&lt;br /&gt;ok 4 - wait_for_page_to_load, 30000&lt;br /&gt;ok 5 - is_text_present, Perl の検索結果&lt;br /&gt;1..5&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;上手く実行できました。&lt;br /&gt;&lt;br /&gt;このようにプログラムからテストを実行すると、テストに必要なデータの準備から後始末までを自動化できます。例えばユーザーの新規登録フローをテストするといったケースでは登録しようとするユーザーのデータがないことが前提になりますので、まずテストユーザのデータを削除してからブラウザを起動して登録フローのテストを実行することで繰り返しテストすることが可能です。DBがトランザクションをサポートしているものであれば最後にrollbackしてしまえば不要なデータも残らず快適です。&lt;br /&gt;&lt;br /&gt;このあたりのノウハウは前項でも紹介したWEB+DB Pressで詳しく紹介されています。Perlは無いですが。。。&lt;br /&gt;&lt;iframe src="http://rcm-jp.amazon.co.jp/e/cm?t=usuilog-22&amp;o=9&amp;p=8&amp;l=as1&amp;asins=4774130036&amp;fc1=000000&amp;IS2=1&amp;lt1=_blank&amp;lc1=0000FF&amp;bc1=000000&amp;bg1=FFFFFF&amp;f=ifr" style="width:120px;height:240px;" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"&gt;&lt;/iframe&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;最終的なコード&lt;/span&gt;&lt;br /&gt;&lt;pre&gt;&lt;span class="synStatement"&gt;use strict&lt;/span&gt;;&lt;br /&gt;&lt;span class="synStatement"&gt;use warnings&lt;/span&gt;;&lt;br /&gt;&lt;span class="synStatement"&gt;use &lt;/span&gt;Time::HiRes &lt;span class="synConstant"&gt;qw(sleep)&lt;/span&gt;;&lt;br /&gt;&lt;span class="synStatement"&gt;use &lt;/span&gt;Test::WWW::Selenium;&lt;br /&gt;&lt;span class="synStatement"&gt;use &lt;/span&gt;Test::More &lt;span class="synConstant"&gt;&amp;quot;no_plan&amp;quot;&lt;/span&gt;;&lt;br /&gt;&lt;span class="synStatement"&gt;use &lt;/span&gt;Test::Exception;&lt;br /&gt;&lt;span class="synStatement"&gt;use utf8&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;&lt;span class="synStatement"&gt;my&lt;/span&gt; &lt;span class="synIdentifier"&gt;$sel&lt;/span&gt; = Test::WWW::Selenium-&amp;gt;&lt;span class="synStatement"&gt;new&lt;/span&gt;( &lt;span class="synConstant"&gt;host &lt;/span&gt;=&amp;gt; &lt;span class="synConstant"&gt;&amp;quot;localhost&amp;quot;&lt;/span&gt;, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="synConstant"&gt;port &lt;/span&gt;=&amp;gt; &lt;span class="synConstant"&gt;4444&lt;/span&gt;, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="synConstant"&gt;browser &lt;/span&gt;=&amp;gt; &lt;span class="synConstant"&gt;&amp;quot;*firefox&amp;quot;&lt;/span&gt;, &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="synConstant"&gt;browser_url &lt;/span&gt;=&amp;gt; &lt;span class="synConstant"&gt;&amp;quot;http://www.google.co.jp&amp;quot;&lt;/span&gt;,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;);&lt;br /&gt;&lt;br /&gt;&lt;span class="synIdentifier"&gt;$sel&lt;/span&gt;-&amp;gt;open_ok(&lt;span class="synConstant"&gt;&amp;quot;/&amp;quot;&lt;/span&gt;);&lt;br /&gt;&lt;span class="synIdentifier"&gt;$sel&lt;/span&gt;-&amp;gt;type_ok(&lt;span class="synConstant"&gt;&amp;quot;q&amp;quot;&lt;/span&gt;, &lt;span class="synConstant"&gt;&amp;quot;Perl&amp;quot;&lt;/span&gt;);&lt;br /&gt;&lt;span class="synIdentifier"&gt;$sel&lt;/span&gt;-&amp;gt;click_ok(&lt;span class="synConstant"&gt;&amp;quot;btnG&amp;quot;&lt;/span&gt;);&lt;br /&gt;&lt;span class="synIdentifier"&gt;$sel&lt;/span&gt;-&amp;gt;wait_for_page_to_load_ok(&lt;span class="synConstant"&gt;&amp;quot;30000&amp;quot;&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;&lt;span class="synIdentifier"&gt;$sel&lt;/span&gt;-&amp;gt;is_text_present_ok(&lt;span class="synConstant"&gt;&amp;quot;Perl の検索結果&amp;quot;&lt;/span&gt;);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;iframe src="http://rcm-jp.amazon.co.jp/e/cm?t=usuilog-22&amp;o=9&amp;p=13&amp;l=st1&amp;mode=books-jp&amp;search=%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E3%80%80%E3%83%86%E3%82%B9%E3%83%88&amp;fc1=&amp;lt1=&amp;lc1=&amp;bg1=&amp;f=ifr" marginwidth="0" marginheight="0" width="468" height="60" border="0" frameborder="0" style="border:none;" scrolling="no"&gt;&lt;/iframe&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2550436420816136794-5808227550406506249?l=usuilog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://usuilog.blogspot.com/feeds/5808227550406506249/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2550436420816136794&amp;postID=5808227550406506249' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2550436420816136794/posts/default/5808227550406506249'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2550436420816136794/posts/default/5808227550406506249'/><link rel='alternate' type='text/html' href='http://usuilog.blogspot.com/2007/01/testingperltestwwwseleniumperlselenium.html' title='[Testing][Perl]Test::WWW::SeleniumでPerlからSelenium RCを操作する'/><author><name>usuihiro</name><uri>http://www.blogger.com/profile/18033487413398851661</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2550436420816136794.post-7743841452366304546</id><published>2007-01-18T18:56:00.000+09:00</published><updated>2007-01-19T11:14:57.886+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programming'/><category scheme='http://www.blogger.com/atom/ns#' term='Perl'/><category scheme='http://www.blogger.com/atom/ns#' term='Performance'/><title type='text'>[Perl]Benchmarkモジュールの小ネタ</title><content type='html'>&lt;a href="http://search.cpan.org/~msergeant/PPerl/"&gt;PPerl&lt;/a&gt;のベンチを取りたくて、timeコマンドとかでも充分差は出るのですが、繰り返し実行される際の差を取りたかったのでBenchmarkモジュールでやろうとしたら少しおかしな結果になりました。&lt;br /&gt;&lt;br /&gt;ちなみにPPerlとはスクリプトをコンパイルしてデーモンとして常駐させることで、起動時のオーバーヘッドをなくして高速化するというモジュールです。これも&lt;a href="http://usuilog.blogspot.com/2007/01/perlperl-hacks.html"&gt;Perl Hacks&lt;/a&gt;に載ってます。&lt;br /&gt;&lt;br /&gt;ベンチ対象(hello.pl)&lt;br /&gt;&lt;pre&gt;&lt;span class="synStatement"&gt;use strict&lt;/span&gt;;&lt;br /&gt;&lt;span class="synStatement"&gt;use &lt;/span&gt;Template;&lt;br /&gt;&lt;br /&gt;&lt;span class="synStatement"&gt;my&lt;/span&gt; &lt;span class="synIdentifier"&gt;$tmpl&lt;/span&gt; = &lt;span class="synConstant"&gt;&amp;lt;&amp;lt;__TMPL__;&lt;/span&gt;&lt;br /&gt;&lt;span class="synConstant"&gt;str = [% str %]&lt;/span&gt;&lt;br /&gt;&lt;span class="synConstant"&gt;__TMPL__&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="synStatement"&gt;my&lt;/span&gt; &lt;span class="synIdentifier"&gt;$tt&lt;/span&gt; = Template-&amp;gt;&lt;span class="synStatement"&gt;new&lt;/span&gt;();&lt;br /&gt;&lt;span class="synIdentifier"&gt;$tt&lt;/span&gt;-&amp;gt;process(&lt;span class="synIdentifier"&gt;\$tmpl&lt;/span&gt;, { &lt;span class="synConstant"&gt;str &lt;/span&gt;=&amp;gt; &lt;span class="synConstant"&gt;'hello'&lt;/span&gt; });&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;print "hello\n"だけでやるとプロセス間通信のオーバーヘッドの方が大きいのかかえって遅くなったので、適当に大きめなモジュールを使えということでTemplateを使用。&lt;br /&gt;&lt;br /&gt;で、ベンチのプログラムですが、以下のようにSYNOPSISどおりに実行すると&lt;br /&gt;&lt;pre&gt;&lt;span class="synPreProc"&gt;#!/usr/local/bin/perl&lt;/span&gt;&lt;br /&gt;&lt;span class="synStatement"&gt;use strict&lt;/span&gt;;&lt;br /&gt;&lt;span class="synStatement"&gt;use &lt;/span&gt;Benchmark &lt;span class="synConstant"&gt;qw(timethese)&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;timethese(&lt;span class="synConstant"&gt;100&lt;/span&gt;, {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="synConstant"&gt;pperl &lt;/span&gt;=&amp;gt;&lt;span class="synIdentifier"&gt; &lt;/span&gt;&lt;span class="synStatement"&gt;sub&lt;/span&gt;&lt;span class="synIdentifier"&gt; &lt;/span&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="synStatement"&gt;my&lt;/span&gt; &lt;span class="synIdentifier"&gt;$ret&lt;/span&gt; = &lt;span class="synStatement"&gt;`&lt;/span&gt;&lt;span class="synConstant"&gt;/usr/bin/pperl -w --no-cleanup hello.pl&lt;/span&gt;&lt;span class="synStatement"&gt;`&lt;/span&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="synStatement"&gt;die&lt;/span&gt; &lt;span class="synConstant"&gt;&amp;quot;error&amp;quot;&lt;/span&gt; &lt;span class="synStatement"&gt;unless&lt;/span&gt; (&lt;span class="synIdentifier"&gt;$ret&lt;/span&gt; =~ m|hello|);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;},&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="synConstant"&gt;perl &lt;/span&gt;=&amp;gt;&lt;span class="synIdentifier"&gt; &lt;/span&gt;&lt;span class="synStatement"&gt;sub&lt;/span&gt;&lt;span class="synIdentifier"&gt; &lt;/span&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="synStatement"&gt;my&lt;/span&gt; &lt;span class="synIdentifier"&gt;$ret&lt;/span&gt; = &lt;span class="synStatement"&gt;`&lt;/span&gt;&lt;span class="synConstant"&gt;/usr/bin/perl -w hello.pl&lt;/span&gt;&lt;span class="synStatement"&gt;`&lt;/span&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="synStatement"&gt;die&lt;/span&gt; &lt;span class="synConstant"&gt;&amp;quot;error&amp;quot;&lt;/span&gt; &lt;span class="synStatement"&gt;unless&lt;/span&gt; (&lt;span class="synIdentifier"&gt;$ret&lt;/span&gt; =~ m|hello|);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;},&lt;br /&gt;});&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;こんな感じになります。&lt;br /&gt;&lt;pre class="console"&gt;Benchmark: timing 100 iterations of perl, pperl...&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;perl: 42 wallclock secs ( 0.01 usr  0.03 sys + 38.64 cusr  2.56 csys = 41.24 CPU) @ 2500.00/s (n=100)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;pperl:  6 wallclock secs ( 0.01 usr  0.03 sys +  0.34 cusr  0.38 csys =  0.76 CPU) @ 2500.00/s (n=100)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;wallclockとかはちゃんと出ているんですがRateがおかしい。これでも結果はわかるといえばわかるのですが気にいらないのでいろいろ調べていると、第３引数にstyleを指定することができるというのを見つけました。これを使うと親プロセスだけの時間とか子プロセスだけの時間とか計ってくれるようです。今回は子プロセスの実行時間が欲しいので'nop'としました。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;スタイルの指定&lt;/span&gt;&lt;br /&gt;&lt;pre&gt;&lt;span class="synPreProc"&gt;#!/usr/local/bin/perl&lt;/span&gt;&lt;br /&gt;&lt;span class="synStatement"&gt;use strict&lt;/span&gt;;&lt;br /&gt;&lt;span class="synStatement"&gt;use &lt;/span&gt;Benchmark &lt;span class="synConstant"&gt;qw(timethese :hireswallclock)&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;timethese(&lt;span class="synConstant"&gt;100&lt;/span&gt;, {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="synConstant"&gt;pperl &lt;/span&gt;=&amp;gt;&lt;span class="synIdentifier"&gt; &lt;/span&gt;&lt;span class="synStatement"&gt;sub&lt;/span&gt;&lt;span class="synIdentifier"&gt; &lt;/span&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="synStatement"&gt;my&lt;/span&gt; &lt;span class="synIdentifier"&gt;$ret&lt;/span&gt; = &lt;span class="synStatement"&gt;`&lt;/span&gt;&lt;span class="synConstant"&gt;/usr/bin/pperl -w --no-cleanup hello.pl&lt;/span&gt;&lt;span class="synStatement"&gt;`&lt;/span&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="synStatement"&gt;die&lt;/span&gt; &lt;span class="synConstant"&gt;&amp;quot;error&amp;quot;&lt;/span&gt; &lt;span class="synStatement"&gt;unless&lt;/span&gt; (&lt;span class="synIdentifier"&gt;$ret&lt;/span&gt; =~ m|hello|);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;},&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="synConstant"&gt;perl &lt;/span&gt;=&amp;gt;&lt;span class="synIdentifier"&gt; &lt;/span&gt;&lt;span class="synStatement"&gt;sub&lt;/span&gt;&lt;span class="synIdentifier"&gt; &lt;/span&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="synStatement"&gt;my&lt;/span&gt; &lt;span class="synIdentifier"&gt;$ret&lt;/span&gt; = &lt;span class="synStatement"&gt;`&lt;/span&gt;&lt;span class="synConstant"&gt;/usr/bin/perl -w hello.pl&lt;/span&gt;&lt;span class="synStatement"&gt;`&lt;/span&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="synStatement"&gt;die&lt;/span&gt; &lt;span class="synConstant"&gt;&amp;quot;error&amp;quot;&lt;/span&gt; &lt;span class="synStatement"&gt;unless&lt;/span&gt; (&lt;span class="synIdentifier"&gt;$ret&lt;/span&gt; =~ m|hello|);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;},&lt;br /&gt;}, &lt;span class="synConstant"&gt;'nop'&lt;/span&gt;);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;実行結果&lt;/span&gt;&lt;br /&gt;&lt;pre class="console"&gt;Benchmark: timing 100 iterations of perl, pperl...&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;perl: 47.9732 wallclock secs (44.66 cusr +  3.14 csys = 47.80 CPU) @  2.09/s (n=100)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;pperl: 7.10064 wallclock secs ( 0.35 cusr +  0.47 csys =  0.82 CPU) @ 121.95/s (n=100)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;うまく出ました。それにしてもallのとき（デフォルト）は親子の合計で/sも出してくれればいいのにと思うのは私だけでしょうか？&lt;br /&gt;&lt;br /&gt;ちなみにこれを調べている過程で':hireswallclock'を見つけました。これをuseのときに指定しておけばwallclockもTime::HiResで出してくれます。ちょっと便利。&lt;br /&gt;&lt;br /&gt;&lt;iframe src="http://rcm-jp.amazon.co.jp/e/cm?t=usuilog-22&amp;o=9&amp;p=8&amp;l=as1&amp;asins=4873113148&amp;fc1=000000&amp;IS2=1&amp;lt1=_blank&amp;lc1=0000FF&amp;bc1=000000&amp;bg1=FFFFFF&amp;f=ifr" style="width:120px;height:240px;" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"&gt;&lt;/iframe&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;iframe src="http://rcm-jp.amazon.co.jp/e/cm?t=usuilog-22&amp;o=9&amp;p=13&amp;l=st1&amp;mode=books-jp&amp;search=Perl&amp;fc1=&amp;lt1=&amp;lc1=&amp;bg1=&amp;f=ifr" marginwidth="0" marginheight="0" width="468" height="60" border="0" frameborder="0" style="border:none;" scrolling="no"&gt;&lt;/iframe&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2550436420816136794-7743841452366304546?l=usuilog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://usuilog.blogspot.com/feeds/7743841452366304546/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2550436420816136794&amp;postID=7743841452366304546' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2550436420816136794/posts/default/7743841452366304546'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2550436420816136794/posts/default/7743841452366304546'/><link rel='alternate' type='text/html' href='http://usuilog.blogspot.com/2007/01/perlbenchmark.html' title='[Perl]Benchmarkモジュールの小ネタ'/><author><name>usuihiro</name><uri>http://www.blogger.com/profile/18033487413398851661</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2550436420816136794.post-5173877157486604528</id><published>2007-01-18T10:20:00.000+09:00</published><updated>2007-01-18T10:34:53.681+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programming'/><category scheme='http://www.blogger.com/atom/ns#' term='Perl'/><category scheme='http://www.blogger.com/atom/ns#' term='Book'/><title type='text'>[Book][Perl]Perl Hacks日本語版</title><content type='html'>ついに日本語版が出るようです。&lt;br /&gt;&lt;br /&gt;&lt;iframe src="http://rcm-jp.amazon.co.jp/e/cm?t=usuilog-22&amp;o=9&amp;p=8&amp;l=as1&amp;asins=4873113148&amp;fc1=000000&amp;IS2=1&amp;lt1=_blank&amp;lc1=0000FF&amp;bc1=000000&amp;bg1=FFFFFF&amp;f=ifr" style="width:120px;height:240px;" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"&gt;&lt;/iframe&gt;&lt;br /&gt;&lt;br /&gt;すぐに使えるものから、ちょっとマニアックなものまで、Perlプログラミングに関する１０１のTIPSが集められています。英語版を買って全部は読みきれていないのですが印象に残ったハックを紹介。&lt;br /&gt;&lt;br /&gt;Hack 3　Perlドキュメントをオンラインでブラウズしよう&lt;br /&gt; &lt;a href="http://search.cpan.org/~arandal/Pod-Webserver/"&gt;Pod::Webserver&lt;/a&gt;モジュールが紹介されています。&lt;br /&gt;&lt;a href="http://search.cpan.org/~cwest/Pod-Webserver-Source/"&gt;Pod::Webserver::Source&lt;/a&gt;も組み込むとソースコードも閲覧できて便利です。ただいずれも日本語が上手く表示できないのが難点。&lt;br /&gt;&lt;br /&gt;Hack 27　反復子から複数の値を引き出そう&lt;br /&gt; wantarrayよりも豊富なcontext情報を提供する&lt;a href="http://search.cpan.org/~robin/Want/"&gt;Wan&lt;/a&gt;tモジュールが紹介されています。&lt;br /&gt;リストの数や、HASHかどうかまで判定できたりまします。&lt;br /&gt;&lt;br /&gt;Hack 47　メソッド引数の自動宣言&lt;br /&gt;&lt;a href="http://search.cpan.org/~nwclark/perl-5.8.8/ext/B/B/Deparse.pm"&gt;B::Deparse&lt;/a&gt;モジュールの応用例です。CODEREFからCODEテキストを取得してそれを置換処理して$selfを自動宣言するという力技です。&lt;br /&gt;&lt;br /&gt;Hack 74　使われているすべてのモジュールをトレースしよう&lt;br /&gt;&lt;a href="http://search.cpan.org/~chromatic/Devel-TraceUse/"&gt;Devel::TraceUse&lt;/a&gt;&lt;br /&gt;モジュールのuse順をトレースしてくれます。&lt;br /&gt;当ブログの&lt;a href="http://usuilog.blogspot.com/2006/12/usedumpinc.html"&gt;[Perl]useなしでどこでもDump(@INCにオブジェクトを格納するパターン）&lt;/a&gt;はここで知った知識を使っています。&lt;br /&gt;でもこのTraceUseモジュール、じつはrequireのところでエラーになっていて本当にrequireするのにかかった時間を計っているわけではないようです。バグな気がしたので直そうとしたのですがrequireのネストが上手く処理できず直そうとしても上手くいきませんでした。。。&lt;br /&gt;&lt;br /&gt;Hack 78　サブルーチンの中身を覗こう&lt;br /&gt;Bモジュールのsvref_2objectを使うとCODEREFからシンボル名などさまざまな情報が取得できます。Bモジュール面白いですね。&lt;br /&gt;&lt;br /&gt;そのほかにもvimでパッケージ名(::も含めて）をコード補完したりだとかデバッガをカスタマイズしたりなど使えるマニアックなハックが満載です。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;原著&lt;/span&gt;&lt;br /&gt;&lt;iframe src="http://rcm-jp.amazon.co.jp/e/cm?t=usuilog-22&amp;o=9&amp;amp;p=8&amp;l=as1&amp;amp;asins=0596526741&amp;fc1=000000&amp;amp;IS2=1&amp;lt1=_blank&amp;amp;amp;amp;lc1=0000FF&amp;bc1=000000&amp;amp;bg1=FFFFFF&amp;f=ifr" style="width: 120px; height: 240px;" marginwidth="0" marginheight="0" frameborder="0" scrolling="no"&gt;&lt;/iframe&gt;&lt;br /&gt;&lt;br /&gt;&lt;iframe src="http://rcm-jp.amazon.co.jp/e/cm?t=usuilog-22&amp;o=9&amp;p=13&amp;l=st1&amp;mode=books-jp&amp;search=Perl&amp;fc1=&amp;lt1=&amp;lc1=&amp;bg1=&amp;f=ifr" marginwidth="0" marginheight="0" width="468" height="60" border="0" frameborder="0" style="border:none;" scrolling="no"&gt;&lt;/iframe&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2550436420816136794-5173877157486604528?l=usuilog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://usuilog.blogspot.com/feeds/5173877157486604528/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2550436420816136794&amp;postID=5173877157486604528' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2550436420816136794/posts/default/5173877157486604528'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2550436420816136794/posts/default/5173877157486604528'/><link rel='alternate' type='text/html' href='http://usuilog.blogspot.com/2007/01/perlperl-hacks.html' title='[Book][Perl]Perl Hacks日本語版'/><author><name>usuihiro</name><uri>http://www.blogger.com/profile/18033487413398851661</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2550436420816136794.post-3145337723603993651</id><published>2007-01-10T11:35:00.000+09:00</published><updated>2008-12-09T15:54:26.322+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Testing'/><category scheme='http://www.blogger.com/atom/ns#' term='Selenium'/><title type='text'>[Testing]Selenium RCとSelenium IDEでWEBアプリのUIテストを簡単自動化</title><content type='html'>WEB+DB PressでSelenium特集が掲載されていたので試してみました。&lt;br /&gt;&lt;br /&gt;&lt;iframe src="http://rcm-jp.amazon.co.jp/e/cm?t=usuilog-22&amp;o=9&amp;p=8&amp;l=as1&amp;asins=4774130036&amp;fc1=000000&amp;IS2=1&amp;lt1=_blank&amp;lc1=0000FF&amp;bc1=000000&amp;bg1=FFFFFF&amp;f=ifr" style="width:120px;height:240px;" scrolling="no" marginwidth="0" marginheight="0" frameborder="0"&gt;&lt;/iframe&gt;&lt;br /&gt;&lt;br /&gt;Seleniumとはブラウザからのテストを自動化するツールです。テストケースをHTMLのtableタグで記述するため、比較的簡単にテストケースを作成できます。Selenium-Coreのみではテストケースをテスト対象アプリケーションがあるサーバと同じ場所に置かなければならない為若干面倒ですが、Selenium RCを使うとアップロードが不要になる為非常に便利です。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;インストール&lt;/span&gt;&lt;br /&gt;&lt;a href="http://www.openqa.org/selenium-rc/"&gt;Selenium Remote Control&lt;/a&gt;&lt;br /&gt;現時点での最新バージョンは0.90ですが-htmlSuiteオプションが使えないとのことなのでバージョン0.81を使用します。解凍して適当なところに置いてください。&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.openqa.org/selenium-ide/"&gt;Selenium IDE&lt;/a&gt;&lt;br /&gt;Firefoxエクステンションです。バージョン0.86を使用しました。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;テストに必要なファイル&lt;/span&gt;&lt;br /&gt;作成するファイルは以下のとおりになります。&lt;br /&gt;TestCase.html ・・・　個々のテストケース&lt;br /&gt;TestSuite.html ・・・　テストケース一式をまとめたファイル。個々のテストケースへのリンクを貼る&lt;br /&gt;&lt;br /&gt;少量のテストであればテキストエディタでも作成できますが、Selenium IDEを使うとブラウザの操作を記録してテストケースとなるhtmlファイルを作成してくれます。使い方はIDEを起動して記録ボタンを押した後、テスト対象となるアプリケーションを操作するだけです。&lt;br /&gt;&lt;br /&gt;&lt;a href="http://www.wht.mmtr.or.jp/~usuihiro/blog/selenium/selenium_ide.htm"&gt;サンプル動画(Flash)&lt;/a&gt;&lt;br /&gt;のように操作すると以下のようなhtmlファイルが生成できます。&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;span class="synIdentifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="synStatement"&gt;html&lt;/span&gt;&lt;span class="synIdentifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="synIdentifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="synStatement"&gt;head&lt;/span&gt;&lt;span class="synIdentifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="synIdentifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="synStatement"&gt;meta&lt;/span&gt;&lt;span class="synIdentifier"&gt; &lt;/span&gt;&lt;span class="synType"&gt;http-equiv&lt;/span&gt;&lt;span class="synIdentifier"&gt;=&lt;/span&gt;&lt;span class="synConstant"&gt;&amp;quot;Content-Type&amp;quot;&lt;/span&gt;&lt;span class="synIdentifier"&gt; &lt;/span&gt;&lt;span class="synType"&gt;content&lt;/span&gt;&lt;span class="synIdentifier"&gt;=&lt;/span&gt;&lt;span class="synConstant"&gt;&amp;quot;text/html; charset=UTF-8&amp;quot;&lt;/span&gt;&lt;span class="synIdentifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="synIdentifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="synStatement"&gt;title&lt;/span&gt;&lt;span class="synIdentifier"&gt;&amp;gt;&lt;/span&gt;TestCase1&lt;span class="synIdentifier"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="synStatement"&gt;title&lt;/span&gt;&lt;span class="synIdentifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="synIdentifier"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="synStatement"&gt;head&lt;/span&gt;&lt;span class="synIdentifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="synIdentifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="synStatement"&gt;body&lt;/span&gt;&lt;span class="synIdentifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="synIdentifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="synStatement"&gt;table&lt;/span&gt;&lt;span class="synIdentifier"&gt; &lt;/span&gt;&lt;span class="synType"&gt;cellpadding&lt;/span&gt;&lt;span class="synIdentifier"&gt;=&lt;/span&gt;&lt;span class="synConstant"&gt;&amp;quot;1&amp;quot;&lt;/span&gt;&lt;span class="synIdentifier"&gt; &lt;/span&gt;&lt;span class="synType"&gt;cellspacing&lt;/span&gt;&lt;span class="synIdentifier"&gt;=&lt;/span&gt;&lt;span class="synConstant"&gt;&amp;quot;1&amp;quot;&lt;/span&gt;&lt;span class="synIdentifier"&gt; &lt;/span&gt;&lt;span class="synType"&gt;border&lt;/span&gt;&lt;span class="synIdentifier"&gt;=&lt;/span&gt;&lt;span class="synConstant"&gt;&amp;quot;1&amp;quot;&lt;/span&gt;&lt;span class="synIdentifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="synIdentifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="synStatement"&gt;thead&lt;/span&gt;&lt;span class="synIdentifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="synIdentifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="synStatement"&gt;tr&lt;/span&gt;&lt;span class="synIdentifier"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="synStatement"&gt;td&lt;/span&gt;&lt;span class="synIdentifier"&gt; &lt;/span&gt;&lt;span class="synType"&gt;rowspan&lt;/span&gt;&lt;span class="synIdentifier"&gt;=&lt;/span&gt;&lt;span class="synConstant"&gt;&amp;quot;1&amp;quot;&lt;/span&gt;&lt;span class="synIdentifier"&gt; &lt;/span&gt;&lt;span class="synType"&gt;colspan&lt;/span&gt;&lt;span class="synIdentifier"&gt;=&lt;/span&gt;&lt;span class="synConstant"&gt;&amp;quot;3&amp;quot;&lt;/span&gt;&lt;span class="synIdentifier"&gt;&amp;gt;&lt;/span&gt;TestCase1&lt;span class="synIdentifier"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="synStatement"&gt;td&lt;/span&gt;&lt;span class="synIdentifier"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="synStatement"&gt;tr&lt;/span&gt;&lt;span class="synIdentifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="synIdentifier"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="synStatement"&gt;thead&lt;/span&gt;&lt;span class="synIdentifier"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="synStatement"&gt;tbody&lt;/span&gt;&lt;span class="synIdentifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="synIdentifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="synStatement"&gt;tr&lt;/span&gt;&lt;span class="synIdentifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="synIdentifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="synStatement"&gt;td&lt;/span&gt;&lt;span class="synIdentifier"&gt;&amp;gt;&lt;/span&gt;open&lt;span class="synIdentifier"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="synStatement"&gt;td&lt;/span&gt;&lt;span class="synIdentifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="synIdentifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="synStatement"&gt;td&lt;/span&gt;&lt;span class="synIdentifier"&gt;&amp;gt;&lt;/span&gt;/&lt;span class="synIdentifier"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="synStatement"&gt;td&lt;/span&gt;&lt;span class="synIdentifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="synIdentifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="synStatement"&gt;td&lt;/span&gt;&lt;span class="synIdentifier"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="synStatement"&gt;td&lt;/span&gt;&lt;span class="synIdentifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="synIdentifier"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="synStatement"&gt;tr&lt;/span&gt;&lt;span class="synIdentifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="synIdentifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="synStatement"&gt;tr&lt;/span&gt;&lt;span class="synIdentifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="synIdentifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="synStatement"&gt;td&lt;/span&gt;&lt;span class="synIdentifier"&gt;&amp;gt;&lt;/span&gt;type&lt;span class="synIdentifier"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="synStatement"&gt;td&lt;/span&gt;&lt;span class="synIdentifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="synIdentifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="synStatement"&gt;td&lt;/span&gt;&lt;span class="synIdentifier"&gt;&amp;gt;&lt;/span&gt;q&lt;span class="synIdentifier"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="synStatement"&gt;td&lt;/span&gt;&lt;span class="synIdentifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="synIdentifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="synStatement"&gt;td&lt;/span&gt;&lt;span class="synIdentifier"&gt;&amp;gt;&lt;/span&gt;Perl&lt;span class="synIdentifier"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="synStatement"&gt;td&lt;/span&gt;&lt;span class="synIdentifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="synIdentifier"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="synStatement"&gt;tr&lt;/span&gt;&lt;span class="synIdentifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="synIdentifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="synStatement"&gt;tr&lt;/span&gt;&lt;span class="synIdentifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="synIdentifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="synStatement"&gt;td&lt;/span&gt;&lt;span class="synIdentifier"&gt;&amp;gt;&lt;/span&gt;clickAndWait&lt;span class="synIdentifier"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="synStatement"&gt;td&lt;/span&gt;&lt;span class="synIdentifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="synIdentifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="synStatement"&gt;td&lt;/span&gt;&lt;span class="synIdentifier"&gt;&amp;gt;&lt;/span&gt;btnG&lt;span class="synIdentifier"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="synStatement"&gt;td&lt;/span&gt;&lt;span class="synIdentifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="synIdentifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="synStatement"&gt;td&lt;/span&gt;&lt;span class="synIdentifier"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="synStatement"&gt;td&lt;/span&gt;&lt;span class="synIdentifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="synIdentifier"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="synStatement"&gt;tr&lt;/span&gt;&lt;span class="synIdentifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="synIdentifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="synStatement"&gt;tr&lt;/span&gt;&lt;span class="synIdentifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="synIdentifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="synStatement"&gt;td&lt;/span&gt;&lt;span class="synIdentifier"&gt;&amp;gt;&lt;/span&gt;assertTextPresent&lt;span class="synIdentifier"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="synStatement"&gt;td&lt;/span&gt;&lt;span class="synIdentifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="synIdentifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="synStatement"&gt;td&lt;/span&gt;&lt;span class="synIdentifier"&gt;&amp;gt;&lt;/span&gt;Perl の検索結果&lt;span class="synIdentifier"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="synStatement"&gt;td&lt;/span&gt;&lt;span class="synIdentifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="synIdentifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="synStatement"&gt;td&lt;/span&gt;&lt;span class="synIdentifier"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="synStatement"&gt;td&lt;/span&gt;&lt;span class="synIdentifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="synIdentifier"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="synStatement"&gt;tr&lt;/span&gt;&lt;span class="synIdentifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="synIdentifier"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="synStatement"&gt;tbody&lt;/span&gt;&lt;span class="synIdentifier"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="synStatement"&gt;table&lt;/span&gt;&lt;span class="synIdentifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="synIdentifier"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="synStatement"&gt;body&lt;/span&gt;&lt;span class="synIdentifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="synIdentifier"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="synStatement"&gt;html&lt;/span&gt;&lt;span class="synIdentifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;続いてTestSuiteファイルを作成します。こちらはテストケースを一覧したhtmlとなります。&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;span class="synIdentifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="synStatement"&gt;html&lt;/span&gt;&lt;span class="synIdentifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="synIdentifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="synStatement"&gt;head&lt;/span&gt;&lt;span class="synIdentifier"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="synStatement"&gt;title&lt;/span&gt;&lt;span class="synIdentifier"&gt;&amp;gt;&lt;/span&gt;Test Suite&lt;span class="synIdentifier"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="synStatement"&gt;title&lt;/span&gt;&lt;span class="synIdentifier"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="synStatement"&gt;head&lt;/span&gt;&lt;span class="synIdentifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="synIdentifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="synStatement"&gt;body&lt;/span&gt;&lt;span class="synIdentifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span class="synIdentifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="synStatement"&gt;table&lt;/span&gt;&lt;span class="synIdentifier"&gt; &lt;/span&gt;&lt;span class="synType"&gt;cellpadding&lt;/span&gt;&lt;span class="synIdentifier"&gt;=&lt;/span&gt;&lt;span class="synConstant"&gt;&amp;quot;1&amp;quot;&lt;/span&gt;&lt;span class="synIdentifier"&gt; &lt;/span&gt;&lt;span class="synType"&gt;cellspacing&lt;/span&gt;&lt;span class="synIdentifier"&gt;=&lt;/span&gt;&lt;span class="synConstant"&gt;&amp;quot;1&amp;quot;&lt;/span&gt;&lt;span class="synIdentifier"&gt; &lt;/span&gt;&lt;span class="synType"&gt;border&lt;/span&gt;&lt;span class="synIdentifier"&gt;=&lt;/span&gt;&lt;span class="synConstant"&gt;&amp;quot;1&amp;quot;&lt;/span&gt;&lt;span class="synIdentifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="synIdentifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="synStatement"&gt;tbody&lt;/span&gt;&lt;span class="synIdentifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="synIdentifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="synStatement"&gt;tr&lt;/span&gt;&lt;span class="synIdentifier"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="synStatement"&gt;td&lt;/span&gt;&lt;span class="synIdentifier"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="synStatement"&gt;b&lt;/span&gt;&lt;span class="synIdentifier"&gt;&amp;gt;&lt;/span&gt;Test Suite&lt;span class="synIdentifier"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="synStatement"&gt;b&lt;/span&gt;&lt;span class="synIdentifier"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="synStatement"&gt;td&lt;/span&gt;&lt;span class="synIdentifier"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="synStatement"&gt;tr&lt;/span&gt;&lt;span class="synIdentifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="synIdentifier"&gt;&amp;lt;&lt;/span&gt;&lt;span class="synStatement"&gt;tr&lt;/span&gt;&lt;span class="synIdentifier"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="synStatement"&gt;td&lt;/span&gt;&lt;span class="synIdentifier"&gt;&amp;gt;&amp;lt;&lt;/span&gt;&lt;span class="synStatement"&gt;a&lt;/span&gt;&lt;span class="synIdentifier"&gt; &lt;/span&gt;&lt;span class="synType"&gt;href&lt;/span&gt;&lt;span class="synIdentifier"&gt;=&lt;/span&gt;&lt;span class="synConstant"&gt;&amp;quot;./TestCase1.html&amp;quot;&lt;/span&gt;&lt;span class="synIdentifier"&gt;&amp;gt;&lt;/span&gt;&lt;span class="synUnderlined"&gt;TestCase1&lt;/span&gt;&lt;span class="synIdentifier"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="synStatement"&gt;a&lt;/span&gt;&lt;span class="synIdentifier"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="synStatement"&gt;td&lt;/span&gt;&lt;span class="synIdentifier"&gt;&amp;gt;&amp;lt;/&lt;/span&gt;&lt;span class="synStatement"&gt;tr&lt;/span&gt;&lt;span class="synIdentifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="synIdentifier"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="synStatement"&gt;tbody&lt;/span&gt;&lt;span class="synIdentifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span class="synIdentifier"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="synStatement"&gt;table&lt;/span&gt;&lt;span class="synIdentifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="synIdentifier"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="synStatement"&gt;body&lt;/span&gt;&lt;span class="synIdentifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="synIdentifier"&gt;&amp;lt;/&lt;/span&gt;&lt;span class="synStatement"&gt;html&lt;/span&gt;&lt;span class="synIdentifier"&gt;&amp;gt;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;テストの実行&lt;/span&gt;&lt;br /&gt;Selenuim RCを起動してテストを実行します。&lt;br /&gt;コマンドの構文は&lt;br /&gt;&lt;pre&gt;java -jar selenium-server.jar -htmlSuite &lt;ブラウザ&gt; &lt;テスト対象サイトURL&gt; &lt;テストスイートファイル&gt; &lt;テスト結果ファイル&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;です。&lt;br /&gt;&lt;br /&gt;上記TestSuiteの場合は以下のようにします。&lt;br /&gt;&lt;pre class="console"&gt;java -jar selenium-server.jar -htmlSuite "*firefox" "http://www.google.co.jp" tests/TestSuite.html tests/result.html&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;とします。&lt;br /&gt;&lt;br /&gt;以上で自動的にブラウザが起動してテストが実行され、結果がresult.htmlファイルに出力されます。&lt;br /&gt;&lt;br /&gt;ただこのままですテストが終わると即ブラウザが終了してしまうため、いちいちresult.htmlを開いて見ないと結果がわからないのが面倒です。そこで&lt;br /&gt;&lt;a href="http://d.hatena.ne.jp/onozaty/20070103/p1"&gt;[Selenium]assertEvalの活用方法(ブレイクポイント、終了通知)&lt;/a&gt;&lt;br /&gt;を参考にJavaScriptが使えることを利用してalertするテストケースを用意しておき、TestSuite.htmlの最後に追加してやると、テストの最後にalertが出るので即結果が確認できます。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;テスト実行結果&lt;/span&gt;&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_sX6CD3lBq0Q/RaQ8XGMhszI/AAAAAAAAAAw/3aB7jDRzKjc/s1600-h/TestEnd.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://4.bp.blogspot.com/_sX6CD3lBq0Q/RaQ8XGMhszI/AAAAAAAAAAw/3aB7jDRzKjc/s320/TestEnd.jpg" border="0" alt=""id="BLOGGER_PHOTO_ID_5018202252295385906" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;Seleniumではブラウザを会してテストを行う為JavaScriptの実行結果もテストできます。Selenium RCを使うとコマンド一つでブラウザの起動からテスト結果の保存までが行えるので回帰テストが非常に楽になると思います。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight:bold;"&gt;参考URL&lt;/span&gt;&lt;br /&gt;&lt;a href="http://codezine.jp/a/article.aspx?aid=436"&gt;Selenium 0.7利用手順書（前編）&lt;/a&gt;&lt;br /&gt;&lt;a href="http://journal.mycom.co.jp/articles/2006/09/29/selenium/"&gt;これはすごい! Web案件必須 Selenium - 人気急上昇中自動テストツール&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;iframe src="http://rcm-jp.amazon.co.jp/e/cm?t=usuilog-22&amp;o=9&amp;p=13&amp;l=st1&amp;mode=books-jp&amp;search=%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0%E3%80%80%E3%83%86%E3%82%B9%E3%83%88&amp;fc1=&amp;lt1=&amp;lc1=&amp;bg1=&amp;f=ifr" marginwidth="0" marginheight="0" width="468" height="60" border="0" frameborder="0" style="border:none;" scrolling="no"&gt;&lt;/iframe&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2550436420816136794-3145337723603993651?l=usuilog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://usuilog.blogspot.com/feeds/3145337723603993651/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2550436420816136794&amp;postID=3145337723603993651' title='1 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2550436420816136794/posts/default/3145337723603993651'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2550436420816136794/posts/default/3145337723603993651'/><link rel='alternate' type='text/html' href='http://usuilog.blogspot.com/2007/01/testingselenium-rcselenium-idewebui.html' title='[Testing]Selenium RCとSelenium IDEでWEBアプリのUIテストを簡単自動化'/><author><name>usuihiro</name><uri>http://www.blogger.com/profile/18033487413398851661</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_sX6CD3lBq0Q/RaQ8XGMhszI/AAAAAAAAAAw/3aB7jDRzKjc/s72-c/TestEnd.jpg' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2550436420816136794.post-8068726171230707474</id><published>2006-12-22T13:01:00.000+09:00</published><updated>2006-12-25T16:55:20.098+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programming'/><category scheme='http://www.blogger.com/atom/ns#' term='Perl'/><title type='text'>[Perl]Exporter::Global-任意の関数をグローバルにエクスポートする</title><content type='html'>&lt;a href="http://usuilog.blogspot.com/2006/12/usedumpinc.html"&gt;[Perl]useなしでどこでもDump(@INCにオブジェクトを格納するパターン）&lt;/a&gt;でやった@INCにオブジェクトを格納するコードを使って任意関数をグローバルにエクスポートするモジュールを作ってみました。名づけて&lt;span style="font-weight:bold;"&gt;Exporter::Global&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;例えばErrorモジュールのtry catchを使いたいけどuse Error qw(:try)するのが面倒だとか、アプリケーション内で標準で使うことにしているようなケースで以下のようにしておくとどこでもtry - catch構文が使えるようになります。&lt;br /&gt;&lt;pre&gt;&lt;span class="synComment"&gt;# まずはエクスポートしたい関数を定義（またはインポート）する&lt;/span&gt;&lt;br /&gt;use Error qw(:try)&lt;br /&gt;&lt;span class="synComment"&gt;# Exporter::Globalにエクスポートしたい関数を渡す&lt;/span&gt;&lt;br /&gt;use Exporter::Global qw(try finally with);&lt;br /&gt;&lt;span class="synComment"&gt;# これ以降ロードされるモジュールではすべてtry catchが使える&lt;/span&gt;&lt;br /&gt;no Exporter::Global; &lt;span class="synComment"&gt;# Exporter::Globalをオフにする&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;また、;で区切ってエイリアスをつけられるようにしているので&lt;br /&gt;&lt;pre class="console"&gt;perl -MYAML -MExporter::Global=YAML::Dump;p&lt;/pre&gt;&lt;br /&gt;や&lt;br /&gt;&lt;pre class="console"&gt;perl -MData::Dumper -MExporter::Global=Data::Dumper::Dump;p&lt;/pre&gt;&lt;br /&gt;といった感じで任意のDump関数を指定することができます。また、前記事では想定されていなかった１ファイル内に複数のパッケージがあるケースにも対応しています。&lt;br /&gt;&lt;br /&gt;ソース&lt;br /&gt;&lt;pre&gt;&lt;span class="synStatement"&gt;package&lt;/span&gt;&lt;span class="synType"&gt; Exporter::Global;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="synStatement"&gt;use warnings&lt;/span&gt;;&lt;br /&gt;&lt;span class="synStatement"&gt;use strict&lt;/span&gt;;&lt;br /&gt;&lt;span class="synStatement"&gt;use &lt;/span&gt;Carp;&lt;br /&gt;&lt;span class="synStatement"&gt;use &lt;/span&gt;Fatal &lt;span class="synConstant"&gt;qw(open close)&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;&lt;span class="synStatement"&gt;sub&lt;/span&gt;&lt;span class="synIdentifier"&gt; import &lt;/span&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="synStatement"&gt;my&lt;/span&gt; &lt;span class="synIdentifier"&gt;$class&lt;/span&gt; = &lt;span class="synStatement"&gt;shift&lt;/span&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="synStatement"&gt;my&lt;/span&gt; &lt;span class="synIdentifier"&gt;$args&lt;/span&gt; = &lt;span class="synStatement"&gt;ref&lt;/span&gt; &lt;span class="synIdentifier"&gt;$_&lt;/span&gt;[&lt;span class="synConstant"&gt;0&lt;/span&gt;] &lt;span class="synStatement"&gt;eq&lt;/span&gt; &lt;span class="synConstant"&gt;'HASH'&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;         ? &lt;span class="synIdentifier"&gt;$_&lt;/span&gt;[&lt;span class="synConstant"&gt;0&lt;/span&gt;] : { &lt;span class="synConstant"&gt;subroutines &lt;/span&gt;=&amp;gt; [ &lt;span class="synIdentifier"&gt;@_&lt;/span&gt; ] };&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="synStatement"&gt;local&lt;/span&gt; &lt;span class="synIdentifier"&gt;$Carp::CarpLevel&lt;/span&gt; = &lt;span class="synIdentifier"&gt;$Carp::CarpLevel&lt;/span&gt; + &lt;span class="synConstant"&gt;1&lt;/span&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="synStatement"&gt;unshift&lt;/span&gt; &lt;span class="synIdentifier"&gt;@INC&lt;/span&gt;, &lt;span class="synIdentifier"&gt;$class&lt;/span&gt;-&amp;gt;&lt;span class="synStatement"&gt;new&lt;/span&gt;(&lt;span class="synIdentifier"&gt;$args&lt;/span&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;    &lt;span class="synStatement"&gt;unless&lt;/span&gt; (&lt;span class="synStatement"&gt;grep&lt;/span&gt; {&lt;span class="synStatement"&gt;ref&lt;/span&gt; &lt;span class="synIdentifier"&gt;$_&lt;/span&gt; &lt;span class="synStatement"&gt;eq&lt;/span&gt; &lt;span class="synIdentifier"&gt;$class&lt;/span&gt; } &lt;span class="synIdentifier"&gt;@INC&lt;/span&gt;);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span class="synStatement"&gt;sub&lt;/span&gt;&lt;span class="synIdentifier"&gt; unimport &lt;/span&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="synStatement"&gt;my&lt;/span&gt; &lt;span class="synIdentifier"&gt;$class&lt;/span&gt; = &lt;span class="synStatement"&gt;shift&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="synIdentifier"&gt;@INC&lt;/span&gt; = &lt;span class="synStatement"&gt;grep&lt;/span&gt; { &lt;span class="synStatement"&gt;ref&lt;/span&gt; &lt;span class="synIdentifier"&gt;$_&lt;/span&gt; &lt;span class="synStatement"&gt;ne&lt;/span&gt; &lt;span class="synIdentifier"&gt;$class&lt;/span&gt; } &lt;span class="synIdentifier"&gt;@INC&lt;/span&gt;;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span class="synStatement"&gt;sub&lt;/span&gt;&lt;span class="synIdentifier"&gt; new &lt;/span&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="synStatement"&gt;my&lt;/span&gt; &lt;span class="synIdentifier"&gt;$class&lt;/span&gt; = &lt;span class="synStatement"&gt;shift&lt;/span&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="synStatement"&gt;my&lt;/span&gt; &lt;span class="synIdentifier"&gt;$self&lt;/span&gt; = { %{ _parse_arguments(&lt;span class="synIdentifier"&gt;@_&lt;/span&gt;) } };&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="synStatement"&gt;croak&lt;/span&gt; &lt;span class="synConstant"&gt;&amp;quot;Pass the export subroutines&amp;quot;&lt;/span&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;    &lt;span class="synStatement"&gt;unless&lt;/span&gt; (@ { &lt;span class="synIdentifier"&gt;$self&lt;/span&gt;-&amp;gt;{subroutines} });&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="synStatement"&gt;bless&lt;/span&gt; &lt;span class="synIdentifier"&gt;$self&lt;/span&gt;, &lt;span class="synIdentifier"&gt;$class&lt;/span&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="synIdentifier"&gt;$self&lt;/span&gt;-&amp;gt;{modules} ||= [];&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="synIdentifier"&gt;$self&lt;/span&gt;-&amp;gt;{caller_pkg} ||= &lt;span class="synStatement"&gt;caller&lt;/span&gt;(&lt;span class="synIdentifier"&gt;$Carp::CarpLevel&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="synStatement"&gt;return&lt;/span&gt; &lt;span class="synIdentifier"&gt;$self&lt;/span&gt;;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span class="synStatement"&gt;sub&lt;/span&gt;&lt;span class="synIdentifier"&gt; _parse_arguments &lt;/span&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="synStatement"&gt;my&lt;/span&gt; (&lt;span class="synIdentifier"&gt;@args&lt;/span&gt;) = &lt;span class="synIdentifier"&gt;@_&lt;/span&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="synStatement"&gt;my&lt;/span&gt; &lt;span class="synIdentifier"&gt;$h&lt;/span&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="synStatement"&gt;if&lt;/span&gt; (&lt;span class="synStatement"&gt;ref&lt;/span&gt; &lt;span class="synIdentifier"&gt;$args&lt;/span&gt;[&lt;span class="synConstant"&gt;0&lt;/span&gt;] &lt;span class="synStatement"&gt;eq&lt;/span&gt; &lt;span class="synConstant"&gt;'HASH'&lt;/span&gt;) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;    &lt;span class="synIdentifier"&gt;$h&lt;/span&gt; = &lt;span class="synIdentifier"&gt;$args&lt;/span&gt;[&lt;span class="synConstant"&gt;0&lt;/span&gt;];&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;} &lt;span class="synStatement"&gt;else&lt;/span&gt; {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;    &lt;span class="synStatement"&gt;my&lt;/span&gt; &lt;span class="synIdentifier"&gt;@subrutines&lt;/span&gt; = &lt;span class="synStatement"&gt;map&lt;/span&gt; { &lt;span class="synStatement"&gt;split /&lt;/span&gt;&lt;span class="synConstant"&gt;[&lt;/span&gt;&lt;span class="synSpecial"&gt;\s&lt;/span&gt;&lt;span class="synConstant"&gt;,]&lt;/span&gt;&lt;span class="synSpecial"&gt;+&lt;/span&gt;&lt;span class="synStatement"&gt;/&lt;/span&gt;, &lt;span class="synIdentifier"&gt;$_&lt;/span&gt; } &lt;span class="synIdentifier"&gt;@args&lt;/span&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;    &lt;span class="synIdentifier"&gt;$h&lt;/span&gt; = {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;        &lt;span class="synConstant"&gt;subroutines &lt;/span&gt;=&amp;gt; &lt;span class="synIdentifier"&gt;\@subrutines&lt;/span&gt;,&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;    };&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="synStatement"&gt;return&lt;/span&gt; &lt;span class="synIdentifier"&gt;$h&lt;/span&gt;;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span class="synStatement"&gt;sub&lt;/span&gt;&lt;span class="synIdentifier"&gt; Exporter::Global::INC &lt;/span&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="synStatement"&gt;my&lt;/span&gt; &lt;span class="synIdentifier"&gt;$self&lt;/span&gt; = &lt;span class="synStatement"&gt;shift&lt;/span&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="synStatement"&gt;my&lt;/span&gt; &lt;span class="synIdentifier"&gt;$module&lt;/span&gt; = &lt;span class="synStatement"&gt;shift&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="synStatement"&gt;my&lt;/span&gt; &lt;span class="synIdentifier"&gt;$mod_name&lt;/span&gt; = _mod_name(&lt;span class="synIdentifier"&gt;$module&lt;/span&gt;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="synStatement"&gt;return&lt;/span&gt; &lt;span class="synStatement"&gt;unless&lt;/span&gt; (&lt;span class="synIdentifier"&gt;$self&lt;/span&gt;-&amp;gt;_is_export_target(&lt;span class="synIdentifier"&gt;$mod_name&lt;/span&gt;));&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="synStatement"&gt;my&lt;/span&gt; &lt;span class="synIdentifier"&gt;@pkgs&lt;/span&gt; = (&lt;span class="synIdentifier"&gt;$mod_name&lt;/span&gt;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="synStatement"&gt;push&lt;/span&gt; &lt;span class="synIdentifier"&gt;@pkgs&lt;/span&gt;, &lt;span class="synIdentifier"&gt;$self&lt;/span&gt;-&amp;gt;_find_inner_packages(&lt;span class="synIdentifier"&gt;$module&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="synStatement"&gt;for&lt;/span&gt; &lt;span class="synStatement"&gt;my&lt;/span&gt; &lt;span class="synIdentifier"&gt;$export_sub&lt;/span&gt; ( @{ &lt;span class="synIdentifier"&gt;$self&lt;/span&gt;-&amp;gt;{subroutines} } ){&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;    &lt;span class="synStatement"&gt;my&lt;/span&gt; (&lt;span class="synIdentifier"&gt;$import_sym_name&lt;/span&gt;, &lt;span class="synIdentifier"&gt;$export_alias&lt;/span&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;        = &lt;span class="synIdentifier"&gt;$self&lt;/span&gt;-&amp;gt;_extract_sym_name(&lt;span class="synIdentifier"&gt;$export_sub&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;    &lt;span class="synStatement"&gt;for&lt;/span&gt; &lt;span class="synStatement"&gt;my&lt;/span&gt; &lt;span class="synIdentifier"&gt;$pkg&lt;/span&gt; (&lt;span class="synIdentifier"&gt;@pkgs&lt;/span&gt;) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;        &lt;span class="synStatement"&gt;no strict&lt;/span&gt; &lt;span class="synConstant"&gt;'refs'&lt;/span&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;        *{&lt;span class="synConstant"&gt;&amp;quot;&lt;/span&gt;&lt;span class="synIdentifier"&gt;$pkg&lt;/span&gt;&lt;span class="synSpecial"&gt;\:&lt;/span&gt;&lt;span class="synConstant"&gt;:&lt;/span&gt;&lt;span class="synIdentifier"&gt;$export_alias&lt;/span&gt;&lt;span class="synConstant"&gt;&amp;quot;&lt;/span&gt;} = \&amp;amp;{&lt;span class="synConstant"&gt;&amp;quot;&lt;/span&gt;&lt;span class="synIdentifier"&gt;$import_sym_name&lt;/span&gt;&lt;span class="synConstant"&gt;&amp;quot;&lt;/span&gt;};&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;    }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="synStatement"&gt;return&lt;/span&gt;;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span class="synStatement"&gt;sub&lt;/span&gt;&lt;span class="synIdentifier"&gt; _is_export_target &lt;/span&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="synStatement"&gt;my&lt;/span&gt; &lt;span class="synIdentifier"&gt;$self&lt;/span&gt; = &lt;span class="synStatement"&gt;shift&lt;/span&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="synStatement"&gt;my&lt;/span&gt; &lt;span class="synIdentifier"&gt;$mod_name&lt;/span&gt; = &lt;span class="synStatement"&gt;shift&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="synStatement"&gt;if&lt;/span&gt; (&lt;span class="synStatement"&gt;my&lt;/span&gt; &lt;span class="synIdentifier"&gt;@modules&lt;/span&gt; = @{ &lt;span class="synIdentifier"&gt;$self&lt;/span&gt;-&amp;gt;{modules} }) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;    &lt;span class="synStatement"&gt;return&lt;/span&gt; &lt;span class="synStatement"&gt;unless&lt;/span&gt; ( &lt;span class="synStatement"&gt;grep&lt;/span&gt; { &lt;span class="synIdentifier"&gt;$mod_name&lt;/span&gt; =~ &lt;span class="synConstant"&gt;qr(&lt;/span&gt;&lt;span class="synIdentifier"&gt;$_&lt;/span&gt;&lt;span class="synConstant"&gt;)&lt;/span&gt; } &lt;span class="synIdentifier"&gt;@modules&lt;/span&gt;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="synStatement"&gt;return&lt;/span&gt; &lt;span class="synConstant"&gt;1&lt;/span&gt;;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span class="synStatement"&gt;sub&lt;/span&gt;&lt;span class="synIdentifier"&gt; _mod_name &lt;/span&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;(&lt;span class="synStatement"&gt;my&lt;/span&gt; &lt;span class="synIdentifier"&gt;$mod_name&lt;/span&gt; = &lt;span class="synStatement"&gt;shift&lt;/span&gt;) =~ s|/|::|g;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="synIdentifier"&gt;$mod_name&lt;/span&gt; =~ s|\.pm&lt;span class="synIdentifier"&gt;$|&lt;/span&gt;|;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="synStatement"&gt;return&lt;/span&gt; &lt;span class="synIdentifier"&gt;$mod_name&lt;/span&gt;;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span class="synStatement"&gt;sub&lt;/span&gt;&lt;span class="synIdentifier"&gt; _extract_sym_name &lt;/span&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="synStatement"&gt;my&lt;/span&gt; &lt;span class="synIdentifier"&gt;$self&lt;/span&gt; = &lt;span class="synStatement"&gt;shift&lt;/span&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="synStatement"&gt;my&lt;/span&gt; &lt;span class="synIdentifier"&gt;$export_sub&lt;/span&gt; = &lt;span class="synStatement"&gt;shift&lt;/span&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="synStatement"&gt;my&lt;/span&gt; (&lt;span class="synIdentifier"&gt;$sub_name&lt;/span&gt;, &lt;span class="synIdentifier"&gt;$alias&lt;/span&gt;) = &lt;span class="synStatement"&gt;split /&lt;/span&gt;&lt;span class="synConstant"&gt;;&lt;/span&gt;&lt;span class="synStatement"&gt;/&lt;/span&gt;, &lt;span class="synIdentifier"&gt;$export_sub&lt;/span&gt;, &lt;span class="synConstant"&gt;2&lt;/span&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="synStatement"&gt;die&lt;/span&gt; &lt;span class="synConstant"&gt;&amp;quot;Can't extract subroutine name&amp;quot;&lt;/span&gt; &lt;span class="synStatement"&gt;unless&lt;/span&gt; (&lt;span class="synIdentifier"&gt;$sub_name&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="synIdentifier"&gt;$alias&lt;/span&gt; ||= &lt;span class="synIdentifier"&gt;$sub_name&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="synStatement"&gt;my&lt;/span&gt; &lt;span class="synIdentifier"&gt;$import_sym_name&lt;/span&gt; &lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;    = &lt;span class="synIdentifier"&gt;$sub_name&lt;/span&gt; =~&lt;span class="synStatement"&gt; /&lt;/span&gt;&lt;span class="synConstant"&gt;::&lt;/span&gt;&lt;span class="synStatement"&gt;/&lt;/span&gt; ? &lt;span class="synIdentifier"&gt;$sub_name&lt;/span&gt; : &lt;span class="synConstant"&gt;&amp;quot;&lt;/span&gt;&lt;span class="synIdentifier"&gt;$self&lt;/span&gt;&lt;span class="synConstant"&gt;-&amp;gt;{caller_pkg}::&lt;/span&gt;&lt;span class="synIdentifier"&gt;$sub_name&lt;/span&gt;&lt;span class="synConstant"&gt;&amp;quot;&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="synStatement"&gt;return&lt;/span&gt; (&lt;span class="synIdentifier"&gt;$import_sym_name&lt;/span&gt;, &lt;span class="synIdentifier"&gt;$alias&lt;/span&gt;);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span class="synStatement"&gt;sub&lt;/span&gt;&lt;span class="synIdentifier"&gt; _find_inner_packages &lt;/span&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="synStatement"&gt;my&lt;/span&gt; &lt;span class="synIdentifier"&gt;$self&lt;/span&gt; = &lt;span class="synStatement"&gt;shift&lt;/span&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="synStatement"&gt;my&lt;/span&gt; &lt;span class="synIdentifier"&gt;$module&lt;/span&gt; = &lt;span class="synStatement"&gt;shift&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="synStatement"&gt;my&lt;/span&gt; &lt;span class="synIdentifier"&gt;$mod_name&lt;/span&gt; = _mod_name(&lt;span class="synIdentifier"&gt;$module&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="synStatement"&gt;my&lt;/span&gt; &lt;span class="synIdentifier"&gt;@pkg&lt;/span&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="synStatement"&gt;for&lt;/span&gt; &lt;span class="synStatement"&gt;my&lt;/span&gt; &lt;span class="synIdentifier"&gt;$inc&lt;/span&gt; (&lt;span class="synIdentifier"&gt;@INC&lt;/span&gt;) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;    &lt;span class="synStatement"&gt;next&lt;/span&gt; &lt;span class="synStatement"&gt;if&lt;/span&gt; (&lt;span class="synStatement"&gt;ref&lt;/span&gt; &lt;span class="synIdentifier"&gt;$inc&lt;/span&gt;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;    &lt;span class="synStatement"&gt;my&lt;/span&gt; &lt;span class="synIdentifier"&gt;$path&lt;/span&gt; = &lt;span class="synIdentifier"&gt;$inc&lt;/span&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;    &lt;span class="synIdentifier"&gt;$path&lt;/span&gt; .= &lt;span class="synConstant"&gt;'/'&lt;/span&gt; &lt;span class="synStatement"&gt;unless&lt;/span&gt; (&lt;span class="synIdentifier"&gt;$path&lt;/span&gt; =~ m|/&lt;span class="synIdentifier"&gt;$|&lt;/span&gt;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;    &lt;span class="synIdentifier"&gt;$path&lt;/span&gt; .= &lt;span class="synIdentifier"&gt;$module&lt;/span&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;    &lt;span class="synStatement"&gt;next&lt;/span&gt; &lt;span class="synStatement"&gt;unless&lt;/span&gt; (&lt;span class="synStatement"&gt;-e&lt;/span&gt; &lt;span class="synIdentifier"&gt;$path&lt;/span&gt;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;    &lt;span class="synStatement"&gt;open&lt;/span&gt; (&lt;span class="synStatement"&gt;my&lt;/span&gt; &lt;span class="synIdentifier"&gt;$fh&lt;/span&gt;, &lt;span class="synIdentifier"&gt;$path&lt;/span&gt;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;    &lt;span class="synStatement"&gt;while&lt;/span&gt; (&amp;lt;&lt;span class="synIdentifier"&gt;$fh&lt;/span&gt;&amp;gt;) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;        &lt;span class="synStatement"&gt;next&lt;/span&gt; &lt;span class="synStatement"&gt;if&lt;/span&gt; (&lt;span class="synStatement"&gt;/&lt;/span&gt;&lt;span class="synConstant"&gt;^=&lt;/span&gt;&lt;span class="synSpecial"&gt;(?!&lt;/span&gt;&lt;span class="synConstant"&gt;cut&lt;/span&gt;&lt;span class="synSpecial"&gt;)&lt;/span&gt;&lt;span class="synStatement"&gt;/&lt;/span&gt; .. &lt;span class="synStatement"&gt;/&lt;/span&gt;&lt;span class="synConstant"&gt;^=cut&lt;/span&gt;&lt;span class="synStatement"&gt;/&lt;/span&gt;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;        &lt;span class="synStatement"&gt;last&lt;/span&gt; &lt;span class="synStatement"&gt;if&lt;/span&gt; (&lt;span class="synStatement"&gt;/&lt;/span&gt;&lt;span class="synConstant"&gt;^__END__$&lt;/span&gt;&lt;span class="synStatement"&gt;/&lt;/span&gt;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;        &lt;span class="synStatement"&gt;if&lt;/span&gt; (&lt;span class="synStatement"&gt;my&lt;/span&gt; (&lt;span class="synIdentifier"&gt;$pkg&lt;/span&gt;) = m|^package\s+(.+?);|) {&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;            &lt;span class="synStatement"&gt;next&lt;/span&gt; &lt;span class="synStatement"&gt;unless&lt;/span&gt; (&lt;span class="synIdentifier"&gt;$self&lt;/span&gt;-&amp;gt;_is_export_target(&lt;span class="synIdentifier"&gt;$pkg&lt;/span&gt;));&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;            &lt;span class="synStatement"&gt;next&lt;/span&gt; &lt;span class="synStatement"&gt;if&lt;/span&gt; (&lt;span class="synIdentifier"&gt;$mod_name&lt;/span&gt; &lt;span class="synStatement"&gt;eq&lt;/span&gt; &lt;span class="synIdentifier"&gt;$pkg&lt;/span&gt;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;            &lt;span class="synStatement"&gt;push&lt;/span&gt; &lt;span class="synIdentifier"&gt;@pkg&lt;/span&gt;, &lt;span class="synIdentifier"&gt;$pkg&lt;/span&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;        }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;    }&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;    &lt;span class="synStatement"&gt;close&lt;/span&gt; &lt;span class="synIdentifier"&gt;$fh&lt;/span&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="synStatement"&gt;return&lt;/span&gt; &lt;span class="synIdentifier"&gt;@pkg&lt;/span&gt;;&lt;br /&gt;}&lt;br /&gt;&lt;span class="synConstant"&gt;1&lt;/span&gt;; &lt;span class="synComment"&gt;# End of Exporter::Global&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;iframe src="http://rcm-jp.amazon.co.jp/e/cm?t=usuilog-22&amp;o=9&amp;p=13&amp;l=st1&amp;mode=books-jp&amp;search=Perl&amp;fc1=&amp;lt1=&amp;lc1=&amp;bg1=&amp;f=ifr" marginwidth="0" marginheight="0" width="468" height="60" border="0" frameborder="0" style="border:none;" scrolling="no"&gt;&lt;/iframe&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2550436420816136794-8068726171230707474?l=usuilog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://usuilog.blogspot.com/feeds/8068726171230707474/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2550436420816136794&amp;postID=8068726171230707474' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2550436420816136794/posts/default/8068726171230707474'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2550436420816136794/posts/default/8068726171230707474'/><link rel='alternate' type='text/html' href='http://usuilog.blogspot.com/2006/12/perlexporterglobal.html' title='[Perl]Exporter::Global-任意の関数をグローバルにエクスポートする'/><author><name>usuihiro</name><uri>http://www.blogger.com/profile/18033487413398851661</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2550436420816136794.post-8143344229230591171</id><published>2006-12-19T01:42:00.000+09:00</published><updated>2006-12-19T03:14:03.127+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Service'/><category scheme='http://www.blogger.com/atom/ns#' term='Blog'/><title type='text'>[Service]ブログバトラー</title><content type='html'>ブログバトラーなるサービスがリリースされたそうです。&lt;br /&gt;&lt;br /&gt;&lt;a href="http://d.hatena.ne.jp/ZIGOROu/20061218/1166437596"&gt;ブログバトラーβオープン&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;ブログに貼り付けて使うタイプのサービスで、ブログのフィードからキーワードを抽出してブログに会ったキャラクターの特性を作ってくれるとのこと。面白そうなので早速貼り付けて見ました＞右下参照&lt;br /&gt;&lt;br /&gt;そして対戦してみたら見事に勝利！！ｗ&lt;br /&gt;&lt;br /&gt;というわけで勝ち逃げにて失礼しますm(_ _)m&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2550436420816136794-8143344229230591171?l=usuilog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://usuilog.blogspot.com/feeds/8143344229230591171/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2550436420816136794&amp;postID=8143344229230591171' title='6 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2550436420816136794/posts/default/8143344229230591171'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2550436420816136794/posts/default/8143344229230591171'/><link rel='alternate' type='text/html' href='http://usuilog.blogspot.com/2006/12/service.html' title='[Service]ブログバトラー'/><author><name>usuihiro</name><uri>http://www.blogger.com/profile/18033487413398851661</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>6</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2550436420816136794.post-811769901128751258</id><published>2006-12-15T10:58:00.000+09:00</published><updated>2006-12-15T11:33:11.455+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='感想'/><title type='text'>[感想]はてなの開発体制</title><content type='html'>ライブドアでやってるセミナーは一度行ってみたいのですがいつも気付いたときには締め切られているのでこうやって資料をアップしてもらえるのは非常にありがたい。&lt;br /&gt;&lt;br /&gt;&lt;a href="http://d.hatena.ne.jp/naoya/20061214/1166063145"&gt;ライブドアのテクノロジーセミナーでしゃべってきました。&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;技術的な点もLVSとか興味深くて試してみたいことはたくさんあるのですが、特に気になったのが開発体制のところの話。以下いくつか抜粋してみますと。。。&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;開発者が企画/運用&lt;br /&gt;新しいことの正しさは本人にしか分からない&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;まさにそうですよね。&lt;br /&gt;うちの会社の場合は企画者も開発者も運用者も全部別の人なので、新しい技術でサービスをといっても距離を感じてしまいます。自分の力量不足もあるんでしょうが。別の人でもいいんですがもうちょっと見通しがよくなるようにしていけたらなぁと。&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;デュアルモニタ購入サポート&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;これ羨ましいｗ&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;休日選択制 (水 or 土)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;平日休めるのいいなぁ。&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;半年続けると流行るの法則。継続は力。&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;流行ってるサービスを真似するんじゃなくて流行るサービスを生み出したい。&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;プログラマのモチベーションは会社の原動力です。&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;すばらしい。開発者主導で楽しんでサービスを作っていっている感じが伝わってきます。&lt;br /&gt;うちもそういう部分を出していきたいなぁ。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2550436420816136794-811769901128751258?l=usuilog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://usuilog.blogspot.com/feeds/811769901128751258/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2550436420816136794&amp;postID=811769901128751258' title='2 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2550436420816136794/posts/default/811769901128751258'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2550436420816136794/posts/default/811769901128751258'/><link rel='alternate' type='text/html' href='http://usuilog.blogspot.com/2006/12/blog-post.html' title='[感想]はてなの開発体制'/><author><name>usuihiro</name><uri>http://www.blogger.com/profile/18033487413398851661</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2550436420816136794.post-94763244635766292</id><published>2006-12-14T20:11:00.000+09:00</published><updated>2008-12-09T15:54:59.830+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='UML'/><category scheme='http://www.blogger.com/atom/ns#' term='Perl'/><title type='text'>[Perl]UMLクラス図の自動生成(UML::Class::Simple)</title><content type='html'>&lt;a href="http://usuilog.blogspot.com/2006/12/perluml.html"&gt;UML続き&lt;/a&gt;でこんどはこれを試してみました。&lt;br /&gt;&lt;br /&gt;&lt;a href="http://search.cpan.org/~agent/UML-Class-Simple/"&gt;http://search.cpan.org/~agent/UML-Class-Simple/&lt;br /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;まず&lt;a href="http://www.graphviz.org/"&gt;Graphviz&lt;/a&gt;をインストールしておく必要があります。&lt;br /&gt;&lt;br /&gt;私はソースからインストールしました。(Graphviz version 2.12)&lt;br /&gt;&lt;pre class="console"&gt;./configure&lt;br /&gt;make&lt;br /&gt;make install&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;で問題なくインストールできました。&lt;br /&gt;つづいてcpanコマンドでUML::Class::Simple(0.07)をインストール。&lt;br /&gt;大量のモジュールをインストールした後最後にこれをインストールしようとするがテストでこけまくる。&lt;br /&gt;とりあえずforceでインストールしてみてだめだったら考えようということでインストールしてしまいました。&lt;br /&gt;&lt;br /&gt;とりあえず以下のような簡単なクラス構成で実行してみます。&lt;br /&gt;&lt;pre&gt;&lt;span class="synStatement"&gt;package&lt;/span&gt;&lt;span class="synType"&gt; Base;&lt;/span&gt;&lt;br /&gt;&lt;span class="synStatement"&gt;sub&lt;/span&gt;&lt;span class="synIdentifier"&gt; new &lt;/span&gt;{ &lt;span class="synStatement"&gt;bless&lt;/span&gt; {}, &lt;span class="synStatement"&gt;shift&lt;/span&gt; }&lt;br /&gt;&lt;span class="synStatement"&gt;sub&lt;/span&gt;&lt;span class="synIdentifier"&gt; base_method &lt;/span&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="synStatement"&gt;print&lt;/span&gt; &lt;span class="synConstant"&gt;&amp;quot;I am base&lt;/span&gt;&lt;span class="synSpecial"&gt;\n&lt;/span&gt;&lt;span class="synConstant"&gt;&amp;quot;&lt;/span&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="synStatement"&gt;shift&lt;/span&gt;-&amp;gt;protected_method();&lt;br /&gt;}&lt;br /&gt;&lt;span class="synConstant"&gt;1&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;&lt;span class="synStatement"&gt;package&lt;/span&gt;&lt;span class="synType"&gt; Foo;&lt;/span&gt;&lt;br /&gt;&lt;span class="synStatement"&gt;use strict&lt;/span&gt;;&lt;br /&gt;&lt;span class="synStatement"&gt;use &lt;/span&gt;base &lt;span class="synConstant"&gt;'Base'&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;&lt;span class="synStatement"&gt;sub&lt;/span&gt;&lt;span class="synIdentifier"&gt; new &lt;/span&gt;{ &lt;span class="synStatement"&gt;bless&lt;/span&gt; {} };&lt;br /&gt;&lt;span class="synStatement"&gt;sub&lt;/span&gt;&lt;span class="synIdentifier"&gt; method_foo &lt;/span&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="synStatement"&gt;print&lt;/span&gt; &lt;span class="synConstant"&gt;&amp;quot;method_foo called&lt;/span&gt;&lt;span class="synSpecial"&gt;\n&lt;/span&gt;&lt;span class="synConstant"&gt;&amp;quot;&lt;/span&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="synStatement"&gt;shift&lt;/span&gt;-&amp;gt;base_method;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;&lt;span class="synStatement"&gt;sub&lt;/span&gt;&lt;span class="synIdentifier"&gt; protected_method &lt;/span&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="synStatement"&gt;print&lt;/span&gt; &lt;span class="synConstant"&gt;&amp;quot;overrided&lt;/span&gt;&lt;span class="synSpecial"&gt;\n&lt;/span&gt;&lt;span class="synConstant"&gt;&amp;quot;&lt;/span&gt;;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span class="synConstant"&gt;1&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;&lt;span class="synStatement"&gt;package&lt;/span&gt;&lt;span class="synType"&gt; Hoge;&lt;/span&gt;&lt;br /&gt;&lt;span class="synStatement"&gt;use &lt;/span&gt;Foo;&lt;br /&gt;&lt;span class="synStatement"&gt;sub&lt;/span&gt;&lt;span class="synIdentifier"&gt; foo &lt;/span&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="synStatement"&gt;my&lt;/span&gt; &lt;span class="synIdentifier"&gt;$self&lt;/span&gt; = &lt;span class="synStatement"&gt;shift&lt;/span&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="synStatement"&gt;return&lt;/span&gt; &lt;span class="synIdentifier"&gt;$self&lt;/span&gt;-&amp;gt;{foo} ||= Foo-&amp;gt;&lt;span class="synStatement"&gt;new&lt;/span&gt;();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span class="synConstant"&gt;1&lt;/span&gt;;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre class="console"&gt;# umlclass.pl -M Hoge -o hoge.png -p "^(Hoge|Foo|Base)$"&lt;br /&gt;Error: syntax error in line 8 &lt;br /&gt;... &lt;font color="red"&gt;&lt;/font&gt; ...&lt;br /&gt;in label of node class_1&lt;br /&gt; at /usr/bin/umlclass.pl line 102&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;del&gt;となりエラー。。。&lt;/del&gt;&lt;span style="font-weight:bold;"&gt;追記(2007/04/11)&lt;/span&gt;作者の方が上記内容をパッチとしてアップデートしてくださいました(コメント参照)。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;どうもfontタグの中身が空だからエラーを出しているんじゃないかと思い、&lt;br /&gt;仕方ないのでデバッガでソースを追っていると、Graphvizのdotコマンドに渡すファイルをTTで作っていることがわかったので、その結果を一時ファイルに保存するようにコードを変えて見てみると、属性にあたるところだということが分かりました。そこで属性が無いときはfontタグを出さないように変更してやると上手く動きました。（その後操作の部分も同様に修正）&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;span class="synComment"&gt;# diff Simple.pm Simple.org &lt;/span&gt;&lt;br /&gt;&lt;span class="synConstant"&gt;327&lt;/span&gt;,329d326&lt;br /&gt;&amp;lt;       &lt;span class="synStatement"&gt;open&lt;/span&gt; (&lt;span class="synStatement"&gt;my&lt;/span&gt; &lt;span class="synIdentifier"&gt;$fh&lt;/span&gt;, &lt;span class="synConstant"&gt;'&amp;gt;'&lt;/span&gt;, &lt;span class="synConstant"&gt;'dotresult.txt'&lt;/span&gt;);&lt;br /&gt;&amp;lt;       &lt;span class="synStatement"&gt;print&lt;/span&gt; &lt;span class="synIdentifier"&gt;$fh&lt;/span&gt; &lt;span class="synIdentifier"&gt;$dot&lt;/span&gt;;&lt;br /&gt;&amp;lt;       &lt;span class="synStatement"&gt;close&lt;/span&gt; &lt;span class="synIdentifier"&gt;$fh&lt;/span&gt;;&lt;br /&gt;359c356&lt;br /&gt;&amp;lt;     &lt;span class="synIdentifier"&gt;&amp;lt;td&amp;gt;&lt;/span&gt;[% IF class.properties.size &amp;gt; &lt;span class="synConstant"&gt;0&lt;/span&gt; %]&amp;lt;font color=&lt;span class="synConstant"&gt;&amp;quot;red&amp;quot;&lt;/span&gt;&amp;gt;&lt;br /&gt;---&lt;br /&gt;&amp;gt;     &lt;span class="synIdentifier"&gt;&amp;lt;td&amp;gt;&lt;/span&gt;&amp;lt;font color=&lt;span class="synConstant"&gt;&amp;quot;red&amp;quot;&lt;/span&gt;&amp;gt;&lt;br /&gt;363c360&lt;br /&gt;&amp;lt;     [%- &lt;span class="synPreProc"&gt;END&lt;/span&gt; %]&amp;lt;/font&amp;gt;[% &lt;span class="synPreProc"&gt;END&lt;/span&gt; %]&amp;lt;/td&amp;gt;&lt;br /&gt;---&lt;br /&gt;&amp;gt;     [%- &lt;span class="synPreProc"&gt;END&lt;/span&gt; %]&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;377c374&lt;br /&gt;&amp;lt;     &lt;span class="synIdentifier"&gt;&amp;lt;td&amp;gt;&lt;/span&gt;[% IF class.methods.size &amp;gt; &lt;span class="synConstant"&gt;0&lt;/span&gt; %]&amp;lt;font color=&lt;span class="synConstant"&gt;&amp;quot;red&amp;quot;&lt;/span&gt;&amp;gt;&lt;br /&gt;---&lt;br /&gt;&amp;gt;     &lt;span class="synIdentifier"&gt;&amp;lt;td&amp;gt;&lt;/span&gt;&amp;lt;font color=&lt;span class="synConstant"&gt;&amp;quot;red&amp;quot;&lt;/span&gt;&amp;gt;&lt;br /&gt;381c378&lt;br /&gt;&amp;lt;     [%- &lt;span class="synPreProc"&gt;END&lt;/span&gt; %]&amp;lt;/font&amp;gt;[% &lt;span class="synPreProc"&gt;END&lt;/span&gt; %]&amp;lt;/td&amp;gt;&lt;br /&gt;---&lt;br /&gt;&amp;gt;     [%- &lt;span class="synPreProc"&gt;END&lt;/span&gt; %]&amp;lt;/font&amp;gt;&amp;lt;/td&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;結果&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://2.bp.blogspot.com/_sX6CD3lBq0Q/RYE36JTS68I/AAAAAAAAAAk/rdekCTJleJg/s1600-h/hoge.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://2.bp.blogspot.com/_sX6CD3lBq0Q/RYE36JTS68I/AAAAAAAAAAk/rdekCTJleJg/s320/hoge.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5008345732681493442" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;わりといい感じに見えますがメソッドと継承関係しか出してくれないことと、pngとかで出されても修正できないのであまりうれしくないかもしれません。&lt;br /&gt;UML::Sequenceとあわせてこの辺がXMIで出力してくれたら便利なんですけどね。&lt;br /&gt;誰か作ってくれないですかね。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;iframe src="http://rcm-jp.amazon.co.jp/e/cm?t=usuilog-22&amp;o=9&amp;p=13&amp;l=st1&amp;mode=books-jp&amp;search=UML&amp;fc1=&amp;lt1=&amp;lc1=&amp;bg1=&amp;f=ifr" marginwidth="0" marginheight="0" width="468" height="60" border="0" frameborder="0" style="border:none;" scrolling="no"&gt;&lt;/iframe&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2550436420816136794-94763244635766292?l=usuilog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://usuilog.blogspot.com/feeds/94763244635766292/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2550436420816136794&amp;postID=94763244635766292' title='4 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2550436420816136794/posts/default/94763244635766292'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2550436420816136794/posts/default/94763244635766292'/><link rel='alternate' type='text/html' href='http://usuilog.blogspot.com/2006/12/perlumlumlclasssimple.html' title='[Perl]UMLクラス図の自動生成(UML::Class::Simple)'/><author><name>usuihiro</name><uri>http://www.blogger.com/profile/18033487413398851661</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_sX6CD3lBq0Q/RYE36JTS68I/AAAAAAAAAAk/rdekCTJleJg/s72-c/hoge.png' height='72' width='72'/><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2550436420816136794.post-713909683906894832</id><published>2006-12-14T17:07:00.000+09:00</published><updated>2008-12-09T15:54:59.975+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='UML'/><category scheme='http://www.blogger.com/atom/ns#' term='Perl'/><title type='text'>[Perl]UMLシーケンス図の自動生成(UML::Sequence)</title><content type='html'>UMLのシーケンス図を出力してくれるというので試してみました。&lt;br /&gt;&lt;br /&gt;&lt;a href="http://search.cpan.org/~philcrow/UML-Sequence/"&gt;http://search.cpan.org/~philcrow/UML-Sequence/&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;インストールした環境は以下のとおりです。&lt;br /&gt;&lt;ul&gt;&lt;br /&gt;&lt;li&gt;CentOS 4.3&lt;/li&gt;&lt;br /&gt;&lt;li&gt;Perl 5.8.5（CentOS 4.3のデフォルト）&lt;/li&gt;&lt;br /&gt;&lt;/ul&gt;&lt;br /&gt;svgで出力するだけならGDが無くても大丈夫ですが、イメージにしたい場合はGDをインストールしておく必要があります。&lt;br /&gt;&lt;br /&gt;まずこんなパッケージを作ってみます。&lt;br /&gt;&lt;pre&gt;&lt;span class="synStatement"&gt;package&lt;/span&gt;&lt;span class="synType"&gt; Base;&lt;/span&gt;&lt;br /&gt;&lt;span class="synStatement"&gt;sub&lt;/span&gt;&lt;span class="synIdentifier"&gt; new &lt;/span&gt;{ &lt;span class="synStatement"&gt;bless&lt;/span&gt; {}, &lt;span class="synStatement"&gt;shift&lt;/span&gt; }&lt;br /&gt;&lt;span class="synStatement"&gt;sub&lt;/span&gt;&lt;span class="synIdentifier"&gt; base_method &lt;/span&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="synStatement"&gt;print&lt;/span&gt; &lt;span class="synConstant"&gt;&amp;quot;I am base&lt;/span&gt;&lt;span class="synSpecial"&gt;\n&lt;/span&gt;&lt;span class="synConstant"&gt;&amp;quot;&lt;/span&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="synStatement"&gt;shift&lt;/span&gt;-&amp;gt;protected_method();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span class="synStatement"&gt;package&lt;/span&gt;&lt;span class="synType"&gt; Foo;&lt;/span&gt;&lt;br /&gt;&lt;span class="synStatement"&gt;our&lt;/span&gt; &lt;span class="synIdentifier"&gt;@ISA&lt;/span&gt; = &lt;span class="synConstant"&gt;qw(Base)&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;&lt;span class="synStatement"&gt;sub&lt;/span&gt;&lt;span class="synIdentifier"&gt; method_foo &lt;/span&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="synStatement"&gt;print&lt;/span&gt; &lt;span class="synConstant"&gt;&amp;quot;method_foo called&lt;/span&gt;&lt;span class="synSpecial"&gt;\n&lt;/span&gt;&lt;span class="synConstant"&gt;&amp;quot;&lt;/span&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="synStatement"&gt;shift&lt;/span&gt;-&amp;gt;base_method;&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;&lt;span class="synStatement"&gt;sub&lt;/span&gt;&lt;span class="synIdentifier"&gt; protected_method &lt;/span&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="synStatement"&gt;print&lt;/span&gt; &lt;span class="synConstant"&gt;&amp;quot;overrided&lt;/span&gt;&lt;span class="synSpecial"&gt;\n&lt;/span&gt;&lt;span class="synConstant"&gt;&amp;quot;&lt;/span&gt;;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span class="synStatement"&gt;package&lt;/span&gt;&lt;span class="synType"&gt; Hoge;&lt;/span&gt;&lt;br /&gt;&lt;span class="synStatement"&gt;sub&lt;/span&gt;&lt;span class="synIdentifier"&gt; new &lt;/span&gt;{ &lt;span class="synStatement"&gt;bless&lt;/span&gt; {} };&lt;br /&gt;&lt;br /&gt;&lt;span class="synStatement"&gt;sub&lt;/span&gt;&lt;span class="synIdentifier"&gt; call_foo &lt;/span&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="synStatement"&gt;my&lt;/span&gt; &lt;span class="synIdentifier"&gt;$foo&lt;/span&gt; = Foo-&amp;gt;&lt;span class="synStatement"&gt;new&lt;/span&gt;();&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&lt;span class="synIdentifier"&gt;$foo&lt;/span&gt;-&amp;gt;method_foo();&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span class="synConstant"&gt;1&lt;/span&gt;;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;つづいて起動ファイル&lt;br /&gt;&lt;pre&gt;&lt;span class="synStatement"&gt;use &lt;/span&gt;Hoge;&lt;br /&gt;&lt;br /&gt;&lt;span class="synStatement"&gt;my&lt;/span&gt; &lt;span class="synIdentifier"&gt;$h&lt;/span&gt; = Hoge-&amp;gt;&lt;span class="synStatement"&gt;new&lt;/span&gt;();&lt;br /&gt;&lt;span class="synIdentifier"&gt;$h&lt;/span&gt;-&amp;gt;call_foo;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;シーケンスを出力するためには、監視するメソッドの名前をパッケージ名つきでリストアップしておく必要があります。&lt;br /&gt;listとしてこんな感じで作っておきます。&lt;br /&gt;&lt;pre&gt;Base::new&lt;br /&gt;Base::base_method&lt;br /&gt;Foo::new&lt;br /&gt;Foo::method_foo&lt;br /&gt;Foo::protected_method&lt;br /&gt;Hoge::new&lt;br /&gt;Hoge::call_foo&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;これらを使ってシーケンス図を生成してみます。&lt;br /&gt;&lt;br /&gt;まずはgenericseq.plコマンドでコールシーケンスをXMLファイル化します。&lt;br /&gt;&lt;pre class="console"&gt;genericseq.pl UML::Sequence::PerlSeq list main.pl &gt;sequence.xml&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;あとはこれをグラフィック形式に変換します。&lt;br /&gt;SVGの場合はseq2svgを、jpegやpngの場合はseq2rast.plを使用します。&lt;br /&gt;&lt;pre class="console"&gt;seq2svg.pl sequence.xml &gt; sequence.svg&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;PNGに変換&lt;br /&gt;&lt;pre class="console"&gt;seq2rast.pl -o sequence.png sequence.xml&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;画像タイプは拡張子で判断してくれるようです。&lt;br /&gt;&lt;br /&gt;サンプル画像&lt;br /&gt;&lt;a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://4.bp.blogspot.com/_sX6CD3lBq0Q/RYEIipTS67I/AAAAAAAAAAY/t7yxl0fdKVw/s1600-h/sequence.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://4.bp.blogspot.com/_sX6CD3lBq0Q/RYEIipTS67I/AAAAAAAAAAY/t7yxl0fdKVw/s320/sequence.png" border="0" alt=""id="BLOGGER_PHOTO_ID_5008293651908062130" /&gt;&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;とりあえずいい感じに出てはいますがリストを作らないといけないのが若干面倒な感じです。想像ですがこのリストからサブルーチンを置き換えてトレースできるようにしているためだと思われます。&lt;br /&gt;パッケージが多くなってくると手動でリストを作るのはきついのでワンライナーあたりで生成するのが現実的でしょう。&lt;br /&gt;サブルーチン呼び出しのグローバルフックみたいなのってないんですかね。&lt;/p&gt;&lt;br /&gt;&lt;br /&gt;&lt;iframe src="http://rcm-jp.amazon.co.jp/e/cm?t=usuilog-22&amp;o=9&amp;p=13&amp;l=st1&amp;mode=books-jp&amp;search=UML&amp;fc1=&amp;lt1=&amp;lc1=&amp;bg1=&amp;f=ifr" marginwidth="0" marginheight="0" width="468" height="60" border="0" frameborder="0" style="border:none;" scrolling="no"&gt;&lt;/iframe&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2550436420816136794-713909683906894832?l=usuilog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://usuilog.blogspot.com/feeds/713909683906894832/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2550436420816136794&amp;postID=713909683906894832' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2550436420816136794/posts/default/713909683906894832'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2550436420816136794/posts/default/713909683906894832'/><link rel='alternate' type='text/html' href='http://usuilog.blogspot.com/2006/12/perluml.html' title='[Perl]UMLシーケンス図の自動生成(UML::Sequence)'/><author><name>usuihiro</name><uri>http://www.blogger.com/profile/18033487413398851661</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://4.bp.blogspot.com/_sX6CD3lBq0Q/RYEIipTS67I/AAAAAAAAAAY/t7yxl0fdKVw/s72-c/sequence.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2550436420816136794.post-5091339750744858600</id><published>2006-12-13T15:11:00.000+09:00</published><updated>2006-12-14T14:02:48.405+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programming'/><category scheme='http://www.blogger.com/atom/ns#' term='Perl'/><category scheme='http://www.blogger.com/atom/ns#' term='Debugging'/><title type='text'>[Perl]useなしでどこでもDump(@INCにオブジェクトを格納するパターン）</title><content type='html'>PERL HACKSを読んでいたら@INCにはhookが仕込めるということが書いてありました。&lt;br /&gt;&lt;br /&gt;&lt;a href="http://d.hatena.ne.jp/holidays-l/20061008"&gt;■[Perl]use無しでどこでも変数をダンプするpackage P;p&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;でも言及されているとおりかねてからuseがめんどうだと思っていたのですが、これを使えばうまくいくんじゃないか？ということでやってみました。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;@INCの仕組み&lt;br /&gt;&lt;/span&gt;&lt;a href="http://perldoc.perl.org/functions/require.html"&gt;&lt;br /&gt;http://perldoc.perl.org/functions/require.html&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;によると@INCにはCODEやオブジェクトを格納することができます。&lt;br /&gt;これを利用するとモジュールロード前にhookを仕込むことができます。&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;There are three forms of hooks: subroutine references,&lt;br /&gt;array references and blessed objects.&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;とあります。subroutine referencesが簡単ですがどーせならblessed objectsの方がということでこちらでやってみます。&lt;br /&gt;オブジェクトの場合はINCというメソッドを定義するとモジュールをロードするたびにそのメソッドを呼び出してくれます。ただmainパッケージになってしまう（ここがよくわらかなかった）らしいのでパッケージ名をフル指定しないといけないようです。&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;span class="synStatement"&gt;package&lt;/span&gt;&lt;span class="synType"&gt; P;&lt;/span&gt;&lt;br /&gt;&lt;span class="synStatement"&gt;use strict&lt;/span&gt;;&lt;br /&gt;&lt;span class="synStatement"&gt;use &lt;/span&gt;YAML;&lt;br /&gt;&lt;br /&gt;&lt;span class="synStatement"&gt;sub&lt;/span&gt;&lt;span class="synIdentifier"&gt; new &lt;/span&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span class="synStatement"&gt;my&lt;/span&gt; &lt;span class="synIdentifier"&gt;$class&lt;/span&gt; = &lt;span class="synStatement"&gt;shift&lt;/span&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span class="synStatement"&gt;return&lt;/span&gt; &lt;span class="synStatement"&gt;bless&lt;/span&gt; { &lt;span class="synConstant"&gt;modules &lt;/span&gt;=&amp;gt; [ &lt;span class="synIdentifier"&gt;@_&lt;/span&gt; ] }, &lt;span class="synIdentifier"&gt;$class&lt;/span&gt;;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span class="synStatement"&gt;sub&lt;/span&gt;&lt;span class="synIdentifier"&gt; import &lt;/span&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span class="synStatement"&gt;my&lt;/span&gt; &lt;span class="synIdentifier"&gt;$class&lt;/span&gt; = &lt;span class="synStatement"&gt;shift&lt;/span&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span class="synStatement"&gt;my&lt;/span&gt; (&lt;span class="synIdentifier"&gt;@modules&lt;/span&gt;) = &lt;span class="synIdentifier"&gt;@_&lt;/span&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span class="synStatement"&gt;push&lt;/span&gt; &lt;span class="synIdentifier"&gt;@modules&lt;/span&gt;, &lt;span class="synStatement"&gt;split /&lt;/span&gt;&lt;span class="synConstant"&gt;[,&lt;/span&gt;&lt;span class="synSpecial"&gt;\s&lt;/span&gt;&lt;span class="synConstant"&gt;]&lt;/span&gt;&lt;span class="synSpecial"&gt;+&lt;/span&gt;&lt;span class="synStatement"&gt;/msx&lt;/span&gt;, &lt;span class="synIdentifier"&gt;$ENV&lt;/span&gt;{P} || &lt;span class="synConstant"&gt;q{}&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span class="synStatement"&gt;unshift&lt;/span&gt; &lt;span class="synIdentifier"&gt;@INC&lt;/span&gt;, P-&amp;gt;&lt;span class="synStatement"&gt;new&lt;/span&gt;(&lt;span class="synIdentifier"&gt;@modules&lt;/span&gt;)&lt;br /&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;span class="synStatement"&gt;unless&lt;/span&gt; (&lt;span class="synStatement"&gt;grep&lt;/span&gt; {&lt;span class="synStatement"&gt;ref&lt;/span&gt; &lt;span class="synIdentifier"&gt;$_&lt;/span&gt; &lt;span class="synStatement"&gt;eq&lt;/span&gt; __PACKAGE__ } &lt;span class="synIdentifier"&gt;@INC&lt;/span&gt;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span class="synStatement"&gt;sub&lt;/span&gt;&lt;span class="synIdentifier"&gt; p &lt;/span&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span class="synStatement"&gt;my&lt;/span&gt; (&lt;span class="synIdentifier"&gt;$package&lt;/span&gt;, &lt;span class="synIdentifier"&gt;$file&lt;/span&gt;, &lt;span class="synIdentifier"&gt;$line&lt;/span&gt;) = &lt;span class="synStatement"&gt;caller&lt;/span&gt;();&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span class="synStatement"&gt;warn&lt;/span&gt; &lt;span class="synConstant"&gt;&amp;quot;[&lt;/span&gt;&lt;span class="synIdentifier"&gt;$file&lt;/span&gt;&lt;span class="synConstant"&gt; at line &lt;/span&gt;&lt;span class="synIdentifier"&gt;$line&lt;/span&gt;&lt;span class="synConstant"&gt;] &amp;quot;&lt;/span&gt; . YAML::Dump(&lt;span class="synIdentifier"&gt;@_&lt;/span&gt;);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span class="synStatement"&gt;sub&lt;/span&gt;&lt;span class="synIdentifier"&gt; P::INC &lt;/span&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span class="synStatement"&gt;my&lt;/span&gt; (&lt;span class="synIdentifier"&gt;$self&lt;/span&gt;, &lt;span class="synIdentifier"&gt;$module&lt;/span&gt;) = &lt;span class="synIdentifier"&gt;@_&lt;/span&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span class="synStatement"&gt;if&lt;/span&gt; (&lt;span class="synStatement"&gt;my&lt;/span&gt; &lt;span class="synIdentifier"&gt;@modules&lt;/span&gt; = @{&lt;span class="synIdentifier"&gt;$self&lt;/span&gt;-&amp;gt;{modules}}) {&lt;br /&gt;&amp;nbsp;&amp;nbsp; &lt;span class="synStatement"&gt;return&lt;/span&gt; &lt;span class="synStatement"&gt;unless&lt;/span&gt; ( &lt;span class="synStatement"&gt;grep&lt;/span&gt; { &lt;span class="synIdentifier"&gt;$module&lt;/span&gt; =~ m|^&lt;span class="synIdentifier"&gt;$_&lt;/span&gt;| } &lt;span class="synIdentifier"&gt;@modules&lt;/span&gt;);&lt;br /&gt;&amp;nbsp;&amp;nbsp;}&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;(&lt;span class="synStatement"&gt;my&lt;/span&gt; &lt;span class="synIdentifier"&gt;$mod_name&lt;/span&gt; = &lt;span class="synIdentifier"&gt;$module&lt;/span&gt;) =~ s|/|::|g;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span class="synIdentifier"&gt;$mod_name&lt;/span&gt; =~ s|\.pm&lt;span class="synIdentifier"&gt;$|&lt;/span&gt;|;&lt;br /&gt;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span class="synStatement"&gt;no strict&lt;/span&gt; &lt;span class="synConstant"&gt;'refs'&lt;/span&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;*{&lt;span class="synConstant"&gt;&amp;quot;&lt;/span&gt;&lt;span class="synIdentifier"&gt;$mod_name&lt;/span&gt;&lt;span class="synSpecial"&gt;\:&lt;/span&gt;&lt;span class="synConstant"&gt;:p&amp;quot;&lt;/span&gt;} = &lt;span class="synIdentifier"&gt;\&amp;amp;p&lt;/span&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span class="synStatement"&gt;return&lt;/span&gt;;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span class="synConstant"&gt;1&lt;/span&gt;;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;こんな感じで実装してみました。&lt;br /&gt;&lt;br /&gt;pを使う方&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;span class="synStatement"&gt;package&lt;/span&gt;&lt;span class="synType"&gt; PUser;&lt;/span&gt;&lt;br /&gt;&lt;span class="synStatement"&gt;use strict&lt;/span&gt;;&lt;br /&gt;&lt;span class="synStatement"&gt;use &lt;/span&gt;base &lt;span class="synConstant"&gt;'Class::Accessor'&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;&lt;span class="synStatement"&gt;sub&lt;/span&gt;&lt;span class="synIdentifier"&gt; hoge &lt;/span&gt;{&lt;br /&gt;&amp;nbsp;&amp;nbsp;p &lt;span class="synConstant"&gt;&amp;quot;Hello Debug P&amp;quot;&lt;/span&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;p { &lt;span class="synConstant"&gt;hoge &lt;/span&gt;=&amp;gt; &lt;span class="synConstant"&gt;'foo'&lt;/span&gt; }, &lt;span class="synConstant"&gt;&amp;quot;bar bar&amp;quot;&lt;/span&gt;;&lt;br /&gt;&amp;nbsp;&amp;nbsp;&lt;span class="synStatement"&gt;warn&lt;/span&gt; &lt;span class="synConstant"&gt;&amp;quot;hoge called&amp;quot;&lt;/span&gt;;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span class="synConstant"&gt;1&lt;/span&gt;;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;起動ファイル(run_p.pl)&lt;br /&gt;&lt;pre&gt;&lt;span class="synStatement"&gt;use strict&lt;/span&gt;;&lt;br /&gt;&lt;span class="synStatement"&gt;use &lt;/span&gt;PUser;&lt;br /&gt;PUser-&amp;gt;hoge();&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;これで&lt;br /&gt;&lt;pre class="console"&gt;&lt;br /&gt;perl -MP run_p.pl&lt;br /&gt;&lt;/pre&gt;とやると全てのパッケージでp関数が利用できます。&lt;br /&gt;&lt;br /&gt;&lt;iframe src="http://rcm-jp.amazon.co.jp/e/cm?t=usuilog-22&amp;o=9&amp;amp;p=8&amp;l=as1&amp;amp;asins=0596526741&amp;fc1=000000&amp;amp;IS2=1&amp;lt1=_blank&amp;amp;amp;amp;lc1=0000FF&amp;bc1=000000&amp;amp;bg1=FFFFFF&amp;f=ifr" style="width: 120px; height: 240px;" marginwidth="0" marginheight="0" frameborder="0" scrolling="no"&gt;&lt;/iframe&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2550436420816136794-5091339750744858600?l=usuilog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://usuilog.blogspot.com/feeds/5091339750744858600/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2550436420816136794&amp;postID=5091339750744858600' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2550436420816136794/posts/default/5091339750744858600'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2550436420816136794/posts/default/5091339750744858600'/><link rel='alternate' type='text/html' href='http://usuilog.blogspot.com/2006/12/usedumpinc.html' title='[Perl]useなしでどこでもDump(@INCにオブジェクトを格納するパターン）'/><author><name>usuihiro</name><uri>http://www.blogger.com/profile/18033487413398851661</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2550436420816136794.post-6620515112766018106</id><published>2006-12-06T12:23:00.000+09:00</published><updated>2006-12-14T14:03:03.112+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='JavaScript'/><category scheme='http://www.blogger.com/atom/ns#' term='Programming'/><title type='text'>[JavaScript]JSONPでdel.icio.usのfeedを取得する</title><content type='html'>JavaScript学習。JSONPを試してみました。&lt;br /&gt;&lt;br /&gt;JSONPとはJavaScriptでのRemote Procedure Callの一種です。同様なものとしてXMLHttpRequestが一般的ですが、これはリクエストの送信先が同じドメイン内に限定されているのに対し、JSONPでは異なるドメインにリクエストを送信し、結果を受け取ることができます。&lt;br /&gt;JSONPではscriptタグのsrc属性はドメインが限定されていないことを利用します。&lt;br /&gt;リクエストを受け取ったサーバはレスポンスをJavaScriptの関数呼び出しの形式で返します。クライアントは側ではそれをscriptタグを使って読み込むとコードが関数呼び出しとして評価されるので、その関数を実装しておくことでサーバのレスポンスを処理できるという仕組みです。&lt;br /&gt;例としてdel.icio.usを使ってみます。&lt;br /&gt;以下にリクエストを投げると&lt;br /&gt;&lt;pre&gt;&lt;span class="synConstant"&gt;&lt;/span&gt;&lt;a href="http://del.icio.us/feeds/json/usuihiro?callback=handleResponse"&gt;&lt;span class="synConstant"&gt;http://del.icio.us/feeds/json/usuihiro&lt;/span&gt;&lt;span class="synConstant"&gt;?callback=handleResponse&lt;/span&gt;&lt;/a&gt;&lt;/pre&gt;&lt;pre&gt;handleResponse([{ .. }, ... ])&lt;/pre&gt;という形式でレスポンスが返されます。クライアント側はこのhandleRequest関数を定義しておき、引数から受け取ったデータを処理すればよいという仕組みです。&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;実装手順&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;まずsubmitボタンが押されるとsendJSONPが呼ばれるようにイベントハンドラを登録します。onSubmitでも充分なのですがここではprototype.jsを使用してみました。&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;span class="synIdentifier"&gt;function&lt;/span&gt; startup() &lt;span class="synIdentifier"&gt;{&lt;/span&gt;&lt;br /&gt;Event.observe(&lt;span class="synConstant"&gt;'form'&lt;/span&gt;, &lt;span class="synConstant"&gt;'submit'&lt;/span&gt;, sendJSONP );&lt;br /&gt;&lt;span class="synIdentifier"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;つづいてJSONPリクエストを送信するためのスクリプトタグを生成し、HTMLの要素に追加します。&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;span class="synType"&gt;var&lt;/span&gt; src = &lt;span class="synConstant"&gt;'http://del.icio.us/feeds/json/'&lt;/span&gt;&lt;br /&gt; + user_name + &lt;span class="synConstant"&gt;'?callback=handleResponse'&lt;/span&gt;;&lt;br /&gt;&lt;span class="synType"&gt;var&lt;/span&gt; script = document.createElement(&lt;span class="synConstant"&gt;"script"&lt;/span&gt;);&lt;br /&gt;script.setAttribute(&lt;span class="synConstant"&gt;'type'&lt;/span&gt;, &lt;span class="synConstant"&gt;'text/javascript'&lt;/span&gt;);&lt;br /&gt;script.setAttribute(&lt;span class="synConstant"&gt;'charset'&lt;/span&gt;, &lt;span class="synConstant"&gt;'utf-8'&lt;/span&gt;);&lt;br /&gt;script.setAttribute(&lt;span class="synConstant"&gt;'src'&lt;/span&gt;, src);&lt;br /&gt;&lt;span class="synType"&gt;var&lt;/span&gt; head = document.getElementsByTagName(&lt;span class="synConstant"&gt;'head'&lt;/span&gt;).item(0);&lt;br /&gt;head.appendChild(script);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;最後にレスポンスを処理する関数を定義します。del.icio.usの場合はリクエスト送信時にcallbackパラメータで指定した名前の関数を呼び出す形でレスポンスが返されるので、その名前で関数を作成します。&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&lt;span class="synIdentifier"&gt;function&lt;/span&gt; handleResponse(json) &lt;span class="synIdentifier"&gt;{&lt;/span&gt;&lt;br /&gt;// ...&lt;br /&gt;&lt;span class="synIdentifier"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;こんな感じで外部ドメインとのやり取りをJavaScriptで実現できます。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:130%;"&gt;サンプルコード&lt;/span&gt;&lt;br /&gt;&lt;span style="font-size:100%;"&gt;以下のサンプルではアカウント名を入力してsubmitするとdel.icio.usのfeedsを取得して表示します。&lt;/span&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;&amp;lt;html&amp;gt;&amp;lt;head&amp;gt;&lt;br /&gt;&amp;lt;script language=&lt;span class="synConstant"&gt;"JavaScript"&lt;/span&gt; src=&lt;span class="synConstant"&gt;"lib/prototype-1.4.0.js"&lt;/span&gt; /&amp;gt;&lt;br /&gt;&amp;lt;script language=&lt;span class="synConstant"&gt;"JavaScript"&lt;/span&gt;&amp;gt;&lt;br /&gt;&amp;lt;!--&lt;br /&gt;&lt;span class="synIdentifier"&gt;function&lt;/span&gt; startup() &lt;span class="synIdentifier"&gt;{&lt;/span&gt;&lt;br /&gt;Event.observe(&lt;span class="synConstant"&gt;'form'&lt;/span&gt;, &lt;span class="synConstant"&gt;'submit'&lt;/span&gt;, sendJSONP );&lt;br /&gt;&lt;span class="synIdentifier"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="synComment"&gt;// JSONPの結果呼び出される関数&lt;/span&gt;&lt;br /&gt;&lt;span class="synIdentifier"&gt;function&lt;/span&gt; handleResponse(json) &lt;span class="synIdentifier"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span class="synType"&gt;var&lt;/span&gt; html = &lt;span class="synConstant"&gt;""&lt;/span&gt;;&lt;br /&gt;&lt;span class="synStatement"&gt;if&lt;/span&gt; (json.length == 0) &lt;span class="synIdentifier"&gt;{&lt;/span&gt;&lt;br /&gt; &lt;span class="synType"&gt;var&lt;/span&gt; user_name = $F(&lt;span class="synConstant"&gt;'user_name'&lt;/span&gt;);&lt;br /&gt; alert(&lt;span class="synConstant"&gt;"Feeds not found of "&lt;/span&gt; + user_name);&lt;br /&gt; &lt;span class="synStatement"&gt;return&lt;/span&gt; &lt;span class="synConstant"&gt;false&lt;/span&gt;;&lt;br /&gt;&lt;span class="synIdentifier"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;json.each( function (elem) &lt;span class="synIdentifier"&gt;{&lt;/span&gt;&lt;br /&gt; var text = &lt;span class="synConstant"&gt;'&amp;lt;a href="'&lt;/span&gt; + elem[&lt;span class="synConstant"&gt;"u"&lt;/span&gt;] + &lt;span class="synConstant"&gt;'"&amp;gt;'&lt;/span&gt;&lt;br /&gt;  + elem[&lt;span class="synConstant"&gt;"d"&lt;/span&gt;] + &lt;span class="synConstant"&gt;'&amp;lt;/a&amp;gt;'&lt;/span&gt;;&lt;br /&gt; // タグがあれば追加する&lt;br /&gt; if ( elem[&lt;span class="synConstant"&gt;"t"&lt;/span&gt;]　&amp;&amp;amp; elem[&lt;span class="synConstant"&gt;"t"&lt;/span&gt;].length &amp;gt; 0) &lt;span class="synIdentifier"&gt;{&lt;/span&gt;&lt;br /&gt;  text += &lt;span class="synConstant"&gt;' tags: ('&lt;/span&gt; + elem[&lt;span class="synConstant"&gt;"t"&lt;/span&gt;].join(&lt;span class="synConstant"&gt;','&lt;/span&gt;) + &lt;span class="synConstant"&gt;')'&lt;/span&gt;;&lt;br /&gt; &lt;span class="synIdentifier"&gt;}&lt;/span&gt;&lt;br /&gt; html += &lt;span class="synConstant"&gt;"&amp;lt;li&amp;gt;"&lt;/span&gt; + text + &lt;span class="synConstant"&gt;"&amp;lt;/li&amp;gt;&lt;/span&gt;&lt;span class="synSpecial"&gt;\n&lt;/span&gt;&lt;span class="synConstant"&gt;"&lt;/span&gt;;&lt;br /&gt;&lt;span class="synIdentifier"&gt;}&lt;/span&gt; );&lt;br /&gt;$(&lt;span class="synConstant"&gt;"list_html"&lt;/span&gt;).innerHTML = html;&lt;br /&gt;&lt;span class="synStatement"&gt;return&lt;/span&gt; &lt;span class="synConstant"&gt;true&lt;/span&gt;;&lt;br /&gt;&lt;span class="synIdentifier"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="synComment"&gt;// JSONPリクエストを送信。結果が関数呼び出し形式で返ってくるので&lt;br /&gt;// それを評価させる為にscriptタグを生成する&lt;/span&gt;&lt;br /&gt;&lt;span class="synIdentifier"&gt;function&lt;/span&gt; sendJSONP(e) &lt;span class="synIdentifier"&gt;{&lt;/span&gt;&lt;br /&gt;&lt;span class="synType"&gt;var&lt;/span&gt; user_name = $F(&lt;span class="synConstant"&gt;'user_name'&lt;/span&gt;);&lt;br /&gt;&lt;span class="synStatement"&gt;if&lt;/span&gt; (!user_name) &lt;span class="synIdentifier"&gt;{&lt;/span&gt;&lt;br /&gt; alert (&lt;span class="synConstant"&gt;'input user_name'&lt;/span&gt;);&lt;br /&gt; &lt;span class="synStatement"&gt;return&lt;/span&gt; &lt;span class="synConstant"&gt;false&lt;/span&gt;;&lt;br /&gt;&lt;span class="synIdentifier"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span class="synComment"&gt;// scriptタグの生成&lt;/span&gt;&lt;br /&gt;&lt;span class="synType"&gt;var&lt;/span&gt; src = &lt;span class="synConstant"&gt;'http://del.icio.us/feeds/json/'&lt;/span&gt;&lt;br /&gt;  + user_name + &lt;span class="synConstant"&gt;'?callback=handleResponse'&lt;/span&gt;;&lt;br /&gt;&lt;span class="synType"&gt;var&lt;/span&gt; script = document.createElement(&lt;span class="synConstant"&gt;"script"&lt;/span&gt;);&lt;br /&gt;script.setAttribute(&lt;span class="synConstant"&gt;'type'&lt;/span&gt;, &lt;span class="synConstant"&gt;'text/javascript'&lt;/span&gt;);&lt;br /&gt;script.setAttribute(&lt;span class="synConstant"&gt;'charset'&lt;/span&gt;, &lt;span class="synConstant"&gt;'utf-8'&lt;/span&gt;);&lt;br /&gt;script.setAttribute(&lt;span class="synConstant"&gt;'src'&lt;/span&gt;, src);&lt;br /&gt;&lt;span class="synType"&gt;var&lt;/span&gt; head = document.getElementsByTagName(&lt;span class="synConstant"&gt;'head'&lt;/span&gt;).item(0);&lt;br /&gt;head.appendChild(script);&lt;br /&gt;&lt;br /&gt;&lt;span class="synComment"&gt; // これを呼ばないと通常のGETリクエストも送信されてしまう。&lt;/span&gt;&lt;br /&gt;Event.stop(e); &lt;span class="synComment"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="synStatement"&gt;return&lt;/span&gt; &lt;span class="synConstant"&gt;false&lt;/span&gt;;&lt;br /&gt;&lt;span class="synIdentifier"&gt;}&lt;/span&gt;&lt;br /&gt;&lt;span class="synComment"&gt;//--&amp;gt;&lt;/span&gt;&lt;br /&gt;&amp;lt;/script&amp;gt;&lt;br /&gt;&amp;lt;/head&amp;gt;&lt;br /&gt;&amp;lt;body onload=&lt;span class="synConstant"&gt;"startup()"&lt;/span&gt;&amp;gt;&lt;br /&gt;&amp;lt;h1&amp;gt;del.icio.usからJSONPを利用してfeedを取得します。&amp;lt;/h1&amp;gt;&lt;br /&gt;&amp;lt;form id=&lt;span class="synConstant"&gt;"form"&lt;/span&gt; method=&lt;span class="synConstant"&gt;"get"&lt;/span&gt;&amp;gt;&lt;br /&gt; user_name: &amp;lt;input id=&lt;span class="synConstant"&gt;"user_name"&lt;/span&gt; type=&lt;span class="synConstant"&gt;"text"&lt;/span&gt; /&amp;gt;&lt;br /&gt; &amp;lt;input type=&lt;span class="synConstant"&gt;"submit"&lt;/span&gt; value=&lt;span class="synConstant"&gt;"Get del.icio.us feeds"&lt;/span&gt;/&amp;gt;&lt;br /&gt;&amp;lt;/form&amp;gt;&lt;br /&gt;&amp;lt;ul id=&lt;span class="synConstant"&gt;"list"&lt;/span&gt; /&amp;gt;&lt;br /&gt;&amp;lt;/body&amp;gt;&lt;br /&gt;&amp;lt;/html&amp;gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;iframe src="http://rcm-jp.amazon.co.jp/e/cm?t=usuilog-22&amp;o=9&amp;p=13&amp;l=st1&amp;mode=books-jp&amp;search=JavaScript%20AJAX&amp;fc1=&amp;lt1=&amp;lc1=&amp;bg1=&amp;f=ifr" marginwidth="0" marginheight="0" width="468" height="60" border="0" frameborder="0" style="border:none;" scrolling="no"&gt;&lt;/iframe&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2550436420816136794-6620515112766018106?l=usuilog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://usuilog.blogspot.com/feeds/6620515112766018106/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2550436420816136794&amp;postID=6620515112766018106' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2550436420816136794/posts/default/6620515112766018106'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2550436420816136794/posts/default/6620515112766018106'/><link rel='alternate' type='text/html' href='http://usuilog.blogspot.com/2006/12/jsonpdeliciousfeed.html' title='[JavaScript]JSONPでdel.icio.usのfeedを取得する'/><author><name>usuihiro</name><uri>http://www.blogger.com/profile/18033487413398851661</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2550436420816136794.post-6748177303609868021</id><published>2006-11-30T15:07:00.000+09:00</published><updated>2006-12-14T14:03:20.116+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programming'/><category scheme='http://www.blogger.com/atom/ns#' term='Perl'/><title type='text'>[Perl]例外をオブジェクトとして扱う</title><content type='html'>例外をオブジェクトとして扱うと以下のような利点があります。&lt;br /&gt;&lt;ol&gt;&lt;li&gt;エラーの種類を正規表現ではなくオブジェクトの型で分けられる&lt;/li&gt;&lt;li&gt;オブジェクトに複雑な情報を付加できる&lt;/li&gt;&lt;/ol&gt;例外オブジェクトを扱うモジュールとしてErrorモジュールやException::Classが有りますが、そういったモジュールを使わなくてもPerl5.005以降ではdieにblessされたリファレンスが渡せるため、普通に例外オブジェクトが使えます。&lt;br /&gt;&lt;br /&gt;たとえばこんな感じでエラークラスを定義しておくと&lt;br /&gt;&lt;pre&gt;&lt;span class="synStatement"&gt;use strict&lt;/span&gt;;&lt;br /&gt;&lt;span class="synStatement"&gt;package&lt;/span&gt;&lt;span class="synType"&gt; MyException;&lt;/span&gt;&lt;br /&gt;&lt;span class="synStatement"&gt;use &lt;/span&gt;base &lt;span class="synConstant"&gt;'Class::Accessor'&lt;/span&gt;;&lt;br /&gt;&lt;span class="synStatement"&gt;use &lt;/span&gt;overload &lt;span class="synConstant"&gt;qw{""}&lt;/span&gt; =&amp;gt; &lt;span class="synIdentifier"&gt;\&amp;as_string&lt;/span&gt;;&lt;br /&gt;&lt;span class="synStatement"&gt;use &lt;/span&gt;Carp;&lt;br /&gt;__PACKAGE__-&amp;gt;mk_accessors(&lt;span class="synConstant"&gt;qw(description stacktrace associated)&lt;/span&gt;);&lt;br /&gt;&lt;span class="synStatement"&gt;sub&lt;/span&gt;&lt;span class="synIdentifier"&gt; new &lt;/span&gt;{&lt;br /&gt;&lt;span class="synStatement"&gt;my&lt;/span&gt; &lt;span class="synIdentifier"&gt;$class&lt;/span&gt; = &lt;span class="synStatement"&gt;shift&lt;/span&gt;;&lt;br /&gt;&lt;span class="synStatement"&gt;my&lt;/span&gt; &lt;span class="synIdentifier"&gt;$desc&lt;/span&gt;  = &lt;span class="synStatement"&gt;shift&lt;/span&gt;;&lt;br /&gt;&lt;span class="synStatement"&gt;my&lt;/span&gt; &lt;span class="synIdentifier"&gt;@args&lt;/span&gt;  = &lt;span class="synIdentifier"&gt;@_&lt;/span&gt;;&lt;br /&gt;&lt;span class="synStatement"&gt;unless&lt;/span&gt; (&lt;span class="synIdentifier"&gt;$desc&lt;/span&gt; =~&lt;span class="synStatement"&gt; /&lt;/span&gt;&lt;span class="synSpecial"&gt;\n\z&lt;/span&gt;&lt;span class="synStatement"&gt;/&lt;/span&gt;) {&lt;br /&gt;        &lt;span class="synStatement"&gt;my&lt;/span&gt; &lt;span class="synIdentifier"&gt;$line&lt;/span&gt; = (&lt;span class="synStatement"&gt;caller&lt;/span&gt;(&lt;span class="synIdentifier"&gt;$Carp::CarpLevel&lt;/span&gt;))[&lt;span class="synConstant"&gt;2&lt;/span&gt;];&lt;br /&gt;        &lt;span class="synIdentifier"&gt;$desc&lt;/span&gt; .= &lt;span class="synConstant"&gt;" at line &lt;/span&gt;&lt;span class="synIdentifier"&gt;$line&lt;/span&gt;&lt;span class="synConstant"&gt;."&lt;/span&gt;;&lt;br /&gt;}&lt;br /&gt;&lt;span class="synStatement"&gt;my&lt;/span&gt; &lt;span class="synIdentifier"&gt;$self&lt;/span&gt; = &lt;span class="synIdentifier"&gt;$class&lt;/span&gt;-&amp;gt;SUPER::&lt;span class="synStatement"&gt;new&lt;/span&gt;({ &lt;span class="synConstant"&gt;description &lt;/span&gt;=&amp;gt; &lt;span class="synIdentifier"&gt;$desc&lt;/span&gt;, &lt;span class="synIdentifier"&gt;@args&lt;/span&gt; });&lt;br /&gt;&lt;br /&gt;&lt;span class="synIdentifier"&gt;$self&lt;/span&gt;-&amp;gt;stacktrace(&lt;span class="synConstant"&gt;"&lt;/span&gt;&lt;span class="synIdentifier"&gt;$class&lt;/span&gt;&lt;span class="synConstant"&gt;"&lt;/span&gt;.  Carp::longmess() );&lt;br /&gt;&lt;span class="synStatement"&gt;return&lt;/span&gt; &lt;span class="synIdentifier"&gt;$self&lt;/span&gt;;&lt;br /&gt;}&lt;br /&gt;&lt;span class="synStatement"&gt;sub&lt;/span&gt;&lt;span class="synIdentifier"&gt; throw &lt;/span&gt;{&lt;br /&gt;&lt;span class="synStatement"&gt;my&lt;/span&gt; &lt;span class="synIdentifier"&gt;$proto&lt;/span&gt; = &lt;span class="synStatement"&gt;shift&lt;/span&gt;;&lt;br /&gt;&lt;span class="synStatement"&gt;my&lt;/span&gt; &lt;span class="synIdentifier"&gt;$desc&lt;/span&gt;  = &lt;span class="synStatement"&gt;shift&lt;/span&gt;;&lt;br /&gt;&lt;span class="synStatement"&gt;die&lt;/span&gt; &lt;span class="synIdentifier"&gt;$proto&lt;/span&gt; &lt;span class="synStatement"&gt;if&lt;/span&gt; &lt;span class="synStatement"&gt;ref&lt;/span&gt; &lt;span class="synIdentifier"&gt;$proto&lt;/span&gt;;&lt;br /&gt;&lt;span class="synStatement"&gt;local&lt;/span&gt; &lt;span class="synIdentifier"&gt;$Carp::CarpLevel&lt;/span&gt; = &lt;span class="synIdentifier"&gt;$Carp::CarpLevel&lt;/span&gt; + &lt;span class="synConstant"&gt;1&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;&lt;span class="synStatement"&gt;my&lt;/span&gt; &lt;span class="synIdentifier"&gt;$self&lt;/span&gt; = &lt;span class="synIdentifier"&gt;$proto&lt;/span&gt;-&amp;gt;&lt;span class="synStatement"&gt;new&lt;/span&gt;(&lt;span class="synIdentifier"&gt;$desc&lt;/span&gt;, &lt;span class="synIdentifier"&gt;@_&lt;/span&gt;);&lt;br /&gt;&lt;span class="synStatement"&gt;die&lt;/span&gt; &lt;span class="synIdentifier"&gt;$self&lt;/span&gt;;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span class="synStatement"&gt;sub&lt;/span&gt;&lt;span class="synIdentifier"&gt; as_string &lt;/span&gt;{&lt;br /&gt;&lt;span class="synStatement"&gt;my&lt;/span&gt; &lt;span class="synIdentifier"&gt;$self&lt;/span&gt; = &lt;span class="synStatement"&gt;shift&lt;/span&gt;;&lt;br /&gt;&lt;span class="synStatement"&gt;return&lt;/span&gt;&lt;br /&gt;&lt;span class="synConstant"&gt;qq{&lt;/span&gt;&lt;span class="synIdentifier"&gt;$self&lt;/span&gt;&lt;span class="synConstant"&gt;-&amp;gt;{description}&lt;/span&gt;&lt;br /&gt;------------------- stacktrace ---------------------&lt;br /&gt;&lt;span class="synIdentifier"&gt;$self&lt;/span&gt;-&amp;gt;{stacktrace}&lt;br /&gt;};&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span class="synStatement"&gt;package&lt;/span&gt;&lt;span class="synType"&gt; HogeException;&lt;/span&gt;&lt;br /&gt;&lt;span class="synStatement"&gt;our&lt;/span&gt; &lt;span class="synIdentifier"&gt;@ISA&lt;/span&gt; = &lt;span class="synConstant"&gt;qw(MyException)&lt;/span&gt;;&lt;br /&gt;&lt;span class="synStatement"&gt;&lt;/span&gt;&lt;br /&gt;&lt;span class="synStatement"&gt;package&lt;/span&gt;&lt;span class="synType"&gt; SystemException;&lt;/span&gt;&lt;br /&gt;&lt;span class="synStatement"&gt;our&lt;/span&gt; &lt;span class="synIdentifier"&gt;@ISA&lt;/span&gt; = &lt;span class="synConstant"&gt;qw(MyException)&lt;/span&gt;;&lt;br /&gt;&lt;/pre&gt;以下のようにisaで判断して関連するオブジェクトを取り出したりできます。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;span class="synPreProc"&gt;#!/usr/local/bin/perl&lt;/span&gt;&lt;br /&gt;&lt;span class="synStatement"&gt;use strict&lt;/span&gt;;&lt;br /&gt;&lt;span class="synStatement"&gt;package&lt;/span&gt;&lt;span class="synType"&gt; App;&lt;/span&gt;&lt;br /&gt;&lt;span class="synStatement"&gt;use &lt;/span&gt;MyException;&lt;br /&gt;&lt;span class="synStatement"&gt;use &lt;/span&gt;Data::Dumper;&lt;br /&gt;&lt;br /&gt;&lt;span class="synStatement"&gt;sub&lt;/span&gt;&lt;span class="synIdentifier"&gt; hoge_func &lt;/span&gt;{&lt;br /&gt; &lt;span class="synStatement"&gt;my&lt;/span&gt; &lt;span class="synIdentifier"&gt;$obj&lt;/span&gt; = { &lt;span class="synConstant"&gt;hoge &lt;/span&gt;=&amp;gt; &lt;span class="synConstant"&gt;"&lt;/span&gt;&lt;span class="synIdentifier"&gt;@_&lt;/span&gt;&lt;span class="synConstant"&gt;"&lt;/span&gt; };&lt;br /&gt; HogeException-&amp;gt;throw(&lt;span class="synConstant"&gt;'normal throw'&lt;/span&gt;, &lt;span class="synConstant"&gt;associated &lt;/span&gt;=&amp;gt; &lt;span class="synIdentifier"&gt;$obj&lt;/span&gt;);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span class="synStatement"&gt;sub&lt;/span&gt;&lt;span class="synIdentifier"&gt; run &lt;/span&gt;{&lt;br /&gt; &lt;span class="synStatement"&gt;my&lt;/span&gt; &lt;span class="synIdentifier"&gt;$class&lt;/span&gt; = &lt;span class="synStatement"&gt;shift&lt;/span&gt;;&lt;br /&gt; &lt;span class="synStatement"&gt;eval&lt;/span&gt; {&lt;br /&gt;         &lt;span class="synIdentifier"&gt;$class&lt;/span&gt;-&amp;gt;hoge_func(&lt;span class="synConstant"&gt;'hoge_func'&lt;/span&gt;, &lt;span class="synIdentifier"&gt;@_&lt;/span&gt;);&lt;br /&gt; };&lt;br /&gt; &lt;span class="synStatement"&gt;if&lt;/span&gt; (&lt;span class="synStatement"&gt;my&lt;/span&gt; &lt;span class="synIdentifier"&gt;$err&lt;/span&gt; = &lt;span class="synIdentifier"&gt;$@&lt;/span&gt;) {&lt;br /&gt;     &lt;span class="synStatement"&gt;print&lt;/span&gt; &lt;span class="synConstant"&gt;"#####&lt;/span&gt;&lt;span class="synSpecial"&gt;\n&lt;/span&gt;&lt;span class="synIdentifier"&gt;$err&lt;/span&gt;&lt;span class="synConstant"&gt;#####&lt;/span&gt;&lt;span class="synSpecial"&gt;\n&lt;/span&gt;&lt;span class="synConstant"&gt;"&lt;/span&gt;; &lt;span class="synComment"&gt;# MyException-&gt;as_stringが呼ばれる&lt;/span&gt;&lt;br /&gt;     &lt;span class="synStatement"&gt;if&lt;/span&gt; (UNIVERSAL::isa(&lt;span class="synIdentifier"&gt;$err&lt;/span&gt;,&lt;span class="synConstant"&gt;'HogeException'&lt;/span&gt;)) {&lt;br /&gt;     &lt;span class="synComment"&gt;# オブジェクトの型で処理を分岐。関連付けられている情報を取り出す&lt;/span&gt;&lt;br /&gt;     &lt;span class="synStatement"&gt;print&lt;/span&gt; &lt;span class="synIdentifier"&gt;Dumper&lt;/span&gt;(&lt;span class="synIdentifier"&gt;$err&lt;/span&gt;-&amp;gt;associated);&lt;br /&gt;   } &lt;span class="synStatement"&gt;else&lt;/span&gt; {&lt;br /&gt;     &lt;span class="synStatement"&gt;die&lt;/span&gt; &lt;span class="synIdentifier"&gt;$err&lt;/span&gt;;&lt;br /&gt;   }&lt;br /&gt; }&lt;br /&gt;};&lt;br /&gt;&lt;br /&gt;&lt;span class="synStatement"&gt;package&lt;/span&gt;&lt;span class="synType"&gt; main;&lt;/span&gt;&lt;br /&gt;App-&amp;gt;run(&lt;span class="synConstant"&gt;'hoge'&lt;/span&gt;);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;実行結果&lt;br /&gt;&lt;pre class="console"&gt;&lt;br /&gt;#####&lt;br /&gt;normal throw at line 9.&lt;br /&gt;------------------- stacktrace ---------------------&lt;br /&gt;HogeException at die2.pl line 9&lt;br /&gt; App::hoge_func('App', 'hoge_func', 'hoge') called at die2.pl line 15&lt;br /&gt; eval {...} called at die2.pl line 14&lt;br /&gt; App::run('App', 'hoge') called at die2.pl line 29&lt;br /&gt;&lt;br /&gt;#####&lt;br /&gt;$VAR1 = {&lt;br /&gt;   'hoge' =&gt; 'App hoge_func hoge'&lt;br /&gt; };&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;ただこのままだとモジュール内で普通にdieされているものはスタックトレースがでなかったりと不便なので、シグナルハンドラを使ってもうひと頑張りしてみます&lt;br /&gt;&lt;pre&gt;&lt;span class="synStatement"&gt;local&lt;/span&gt; &lt;span class="synIdentifier"&gt;$SIG&lt;/span&gt;{__DIE__} =&lt;span class="synIdentifier"&gt; &lt;/span&gt;&lt;span class="synStatement"&gt;sub&lt;/span&gt;&lt;span class="synIdentifier"&gt; &lt;/span&gt;{&lt;br /&gt; if (&lt;span class="synStatement"&gt;ref&lt;/span&gt; &lt;span class="synIdentifier"&gt;$_&lt;/span&gt;[&lt;span class="synConstant"&gt;0&lt;/span&gt;] &amp;&amp;amp; &lt;span class="synIdentifier"&gt;$_&lt;/span&gt;[&lt;span class="synConstant"&gt;0&lt;/span&gt;]-&amp;gt;isa(&lt;span class="synConstant"&gt;'MyException'&lt;/span&gt;) ) {&lt;br /&gt;     &lt;span class="synIdentifier"&gt;$_&lt;/span&gt;[&lt;span class="synConstant"&gt;0&lt;/span&gt;]-&amp;gt;throw;&lt;br /&gt; }&lt;br /&gt; else {&lt;br /&gt;     &lt;span class="synComment"&gt;# スタックトレースにここの呼び出しを含めないようにする&lt;br /&gt;    &lt;/span&gt; &lt;span class="synStatement"&gt;local&lt;/span&gt; &lt;span class="synIdentifier"&gt;$Carp::CarpLevel&lt;/span&gt; = &lt;span class="synIdentifier"&gt;$Carp::CarpLevel&lt;/span&gt; + &lt;span class="synConstant"&gt;1&lt;/span&gt;;&lt;br /&gt;     SystemException-&amp;gt;throw( &lt;span class="synStatement"&gt;join&lt;/span&gt; &lt;span class="synConstant"&gt;" "&lt;/span&gt;, &lt;span class="synIdentifier"&gt;@_&lt;/span&gt; )&lt;br /&gt; };&lt;br /&gt;};&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;これを設定しておくと普通にdieが使われている場所でも例外オブジェクトに変換されてスタックトレースが取れるようになります。&lt;br /&gt;スタックトレースだけを考えたら&lt;br /&gt;&lt;pre&gt;&lt;span class="synStatement"&gt;local&lt;/span&gt; &lt;span class="synIdentifier"&gt;$SIG&lt;/span&gt;{__DIE__} =&lt;span class="synIdentifier"&gt; &lt;/span&gt;\&amp;amp;Carp::confess&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;で充分だと思います。&lt;br /&gt;&lt;br /&gt;&lt;iframe src="http://rcm-jp.amazon.co.jp/e/cm?t=usuilog-22&amp;o=9&amp;p=13&amp;l=st1&amp;mode=books-jp&amp;search=Perl&amp;fc1=&amp;lt1=&amp;lc1=&amp;bg1=&amp;f=ifr" marginwidth="0" marginheight="0" width="468" height="60" border="0" frameborder="0" style="border:none;" scrolling="no"&gt;&lt;/iframe&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2550436420816136794-6748177303609868021?l=usuilog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://usuilog.blogspot.com/feeds/6748177303609868021/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2550436420816136794&amp;postID=6748177303609868021' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2550436420816136794/posts/default/6748177303609868021'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2550436420816136794/posts/default/6748177303609868021'/><link rel='alternate' type='text/html' href='http://usuilog.blogspot.com/2006/11/perl_3196.html' title='[Perl]例外をオブジェクトとして扱う'/><author><name>usuihiro</name><uri>http://www.blogger.com/profile/18033487413398851661</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2550436420816136794.post-4660423145504712161</id><published>2006-11-30T11:54:00.000+09:00</published><updated>2006-12-12T23:19:19.215+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programming'/><category scheme='http://www.blogger.com/atom/ns#' term='Perl'/><title type='text'>[Perl]YAMLでblessさせる</title><content type='html'>YAMLファイル内に!perl/packageというタグを記述することでファイルロード時に値をblessさせることができます。&lt;br /&gt;例えばこんなかんじで&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;span class="synPreProc"&gt;#!/usr/local/bin/perl&lt;/span&gt;&lt;br /&gt;&lt;span class="synStatement"&gt;use strict&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;&lt;span class="synStatement"&gt;package&lt;/span&gt;&lt;span class="synType"&gt; Model::Book;&lt;/span&gt;&lt;br /&gt;&lt;span class="synStatement"&gt;use &lt;/span&gt;base &lt;span class="synConstant"&gt;'Class::Accessor'&lt;/span&gt;;&lt;br /&gt;&lt;br /&gt;&lt;span class="synStatement"&gt;my&lt;/span&gt; &lt;span class="synIdentifier"&gt;@accessors&lt;/span&gt; = &lt;span class="synConstant"&gt;qw(author title publisher)&lt;/span&gt;;&lt;br /&gt;__PACKAGE__-&amp;gt;mk_accessors(&lt;span class="synIdentifier"&gt;@accessors&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;&lt;span class="synStatement"&gt;sub&lt;/span&gt;&lt;span class="synIdentifier"&gt; as_string &lt;/span&gt;{&lt;br /&gt; &lt;span class="synStatement"&gt;my&lt;/span&gt; &lt;span class="synIdentifier"&gt;$self&lt;/span&gt; = &lt;span class="synStatement"&gt;shift&lt;/span&gt;;&lt;br /&gt; &lt;span class="synStatement"&gt;return&lt;/span&gt; &lt;span class="synStatement"&gt;join&lt;/span&gt; &lt;span class="synConstant"&gt;"&lt;/span&gt;&lt;span class="synSpecial"&gt;\n&lt;/span&gt;&lt;span class="synConstant"&gt;"&lt;/span&gt;, &lt;span class="synStatement"&gt;map&lt;/span&gt; {&lt;span class="synConstant"&gt;"&lt;/span&gt;&lt;span class="synIdentifier"&gt;$_&lt;/span&gt;&lt;span class="synConstant"&gt;: "&lt;/span&gt; . &lt;span class="synIdentifier"&gt;$self&lt;/span&gt;-&amp;gt;&lt;span class="synIdentifier"&gt;$_&lt;/span&gt;()} &lt;span class="synIdentifier"&gt;@accessors&lt;/span&gt;;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span class="synStatement"&gt;package&lt;/span&gt;&lt;span class="synType"&gt; main;&lt;/span&gt;&lt;br /&gt;&lt;span class="synStatement"&gt;use &lt;/span&gt;YAML::Syck;&lt;br /&gt;&lt;span class="synStatement"&gt;use &lt;/span&gt;Data::Dumper;&lt;br /&gt;&lt;br /&gt;&lt;span class="synStatement"&gt;my&lt;/span&gt; &lt;span class="synIdentifier"&gt;$data&lt;/span&gt; = &lt;span class="synStatement"&gt;do&lt;/span&gt; { &lt;span class="synStatement"&gt;local&lt;/span&gt; &lt;span class="synIdentifier"&gt;$/&lt;/span&gt;; &lt;span class="synIdentifier"&gt;&amp;lt;DATA&amp;gt;&lt;/span&gt;};&lt;br /&gt;&lt;span class="synStatement"&gt;my&lt;/span&gt; &lt;span class="synIdentifier"&gt;$yml&lt;/span&gt; = YAML::Syck::Load(&lt;span class="synIdentifier"&gt;$data&lt;/span&gt;);&lt;br /&gt;&lt;br /&gt;&lt;span class="synStatement"&gt;print&lt;/span&gt; &lt;span class="synIdentifier"&gt;Dumper&lt;/span&gt;(&lt;span class="synIdentifier"&gt;$yml&lt;/span&gt;);&lt;br /&gt;&lt;span class="synStatement"&gt;for&lt;/span&gt; &lt;span class="synStatement"&gt;my&lt;/span&gt; &lt;span class="synIdentifier"&gt;$model&lt;/span&gt; (@{&lt;span class="synIdentifier"&gt;$yml&lt;/span&gt;-&amp;gt;{models}}) {&lt;br /&gt;       &lt;span class="synStatement"&gt;print&lt;/span&gt; &lt;span class="synConstant"&gt;"############&lt;/span&gt;&lt;span class="synSpecial"&gt;\n&lt;/span&gt;&lt;span class="synConstant"&gt;"&lt;/span&gt;;&lt;br /&gt;       &lt;span class="synStatement"&gt;print&lt;/span&gt; &lt;span class="synIdentifier"&gt;$model&lt;/span&gt;-&amp;gt;as_string . &lt;span class="synConstant"&gt;"&lt;/span&gt;&lt;span class="synSpecial"&gt;\n&lt;/span&gt;&lt;span class="synConstant"&gt;"&lt;/span&gt;;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;span class="synComment"&gt;__END__&lt;/span&gt;&lt;br /&gt;&lt;span class="synComment"&gt;models:&lt;/span&gt;&lt;br /&gt;&lt;span class="synComment"&gt;  - !perl/Model::Book&lt;/span&gt;&lt;br /&gt;&lt;span class="synComment"&gt;      author: Damian Conway&lt;/span&gt;&lt;br /&gt;&lt;span class="synComment"&gt;      title: Perl Best Practice&lt;/span&gt;&lt;br /&gt;&lt;span class="synComment"&gt;      publisher: O'REILLY&lt;/span&gt;&lt;br /&gt;&lt;span class="synComment"&gt;  - !perl/Model::Book&lt;/span&gt;&lt;br /&gt;&lt;span class="synComment"&gt;      author: Larry Wall&lt;/span&gt;&lt;br /&gt;&lt;span class="synComment"&gt;      title: Programming Perl&lt;/span&gt;&lt;br /&gt;&lt;span class="synComment"&gt;      publisher: O'REILLY&lt;/span&gt;&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;としておくと&lt;br /&gt;&lt;br /&gt;&lt;pre class="console"&gt;&lt;br /&gt;$VAR1 = {&lt;br /&gt;         'models' =&gt; [&lt;br /&gt;                       bless( {&lt;br /&gt;                                'publisher' =&gt; 'O\'REILLY',&lt;br /&gt;                                'title' =&gt; 'Perl Best Practice',&lt;br /&gt;                                'author' =&gt; 'Damian Conway'&lt;br /&gt;                              }, 'Model::Book' ),&lt;br /&gt;                       bless( {&lt;br /&gt;                                'publisher' =&gt; 'O\'REILLY',&lt;br /&gt;                                'title' =&gt; 'Programming Perl',&lt;br /&gt;                                'author' =&gt; 'Larry Wall'&lt;br /&gt;                              }, 'Model::Book' )&lt;br /&gt;                     ]&lt;br /&gt;       };&lt;br /&gt;############&lt;br /&gt;author: Damian Conway&lt;br /&gt;title: Perl Best Practice&lt;br /&gt;publisher: O'REILLY&lt;br /&gt;############&lt;br /&gt;author: Larry Wall&lt;br /&gt;title: Programming Perl&lt;br /&gt;publisher: O'REILLY&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;のような結果になります。&lt;br /&gt;&lt;br /&gt;これを使えば引数にオブジェクトをとるプラグインなんかも容易にYAMLでDIできるなぁと思ったのですが、以下のような問題が発覚しました。&lt;br /&gt;&lt;br /&gt;&lt;ol&gt;&lt;li&gt;    newなどの初期化メソッドを一切呼んでくれない&lt;/li&gt;&lt;li&gt;    単にblessするだけでuseすらしてくれない&lt;/li&gt;&lt;/ol&gt;&lt;br /&gt;これらのことから結局はなんらかのフレームワークに頼らないと上手く実現できなさそう。。。Rubyの場合は&lt;a href="http://yaml4r.sourceforge.net/cookbook/"&gt;YAML for Ruby&lt;/a&gt;にもあるようにいろいろできるみたいですが、PerlのYAMLサポートはいまいち充分ではないようです。なんかやり方あるのかなぁ。。。&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;&lt;iframe src="http://rcm-jp.amazon.co.jp/e/cm?t=usuilog-22&amp;o=9&amp;p=13&amp;l=st1&amp;mode=books-jp&amp;search=Perl&amp;fc1=&amp;lt1=&amp;lc1=&amp;bg1=&amp;f=ifr" marginwidth="0" marginheight="0" width="468" height="60" border="0" frameborder="0" style="border:none;" scrolling="no"&gt;&lt;/iframe&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2550436420816136794-4660423145504712161?l=usuilog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://usuilog.blogspot.com/feeds/4660423145504712161/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2550436420816136794&amp;postID=4660423145504712161' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2550436420816136794/posts/default/4660423145504712161'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2550436420816136794/posts/default/4660423145504712161'/><link rel='alternate' type='text/html' href='http://usuilog.blogspot.com/2006/11/perlyamlbless_29.html' title='[Perl]YAMLでblessさせる'/><author><name>usuihiro</name><uri>http://www.blogger.com/profile/18033487413398851661</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2550436420816136794.post-5896124805625210749</id><published>2006-11-30T11:50:00.000+09:00</published><updated>2006-12-14T14:03:33.285+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programming'/><category scheme='http://www.blogger.com/atom/ns#' term='Perl'/><title type='text'>[Perl]Time::Piece::localime + ONE_YEARで小ハマリ</title><content type='html'>&lt;a href="http://d.hatena.ne.jp/usuihiro1978/20061117"&gt;http://d.hatena.ne.jp/usuihiro1978/20061117&lt;/a&gt;&lt;br /&gt;から移動。&lt;br /&gt;&lt;br /&gt;Time::PieceとTime::Secondsを使って日付の比較を行うときに以下のようなコードを書いていて小ハマリしました。&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;use Time::Piece;&lt;br /&gt;use Time::Seconds;&lt;br /&gt;&lt;br /&gt;if ($t1 &gt;localtime + ONE_YEAR) {&lt;br /&gt;   # コード&lt;br /&gt;} else {&lt;br /&gt;   # コード&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;上記コードでの&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;localtime + ONE_YEAR&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;は&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;localtime( + ONE_YEAR)&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;となってしまいます。&lt;br /&gt;よって&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;localtime() + ONE_YEAR&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;と書かないとだめ。&lt;br /&gt;&lt;br /&gt;localtimeがプロトタイプ宣言で&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;sub localtime ()&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;となっていれば()つけなくても大丈夫なわけですが、引数を渡せる為そうはなっていません。&lt;br /&gt;こういう関数に引数を渡さないときは明示的に()をつけておいたほうがよさそうですね。&lt;br /&gt;&lt;br /&gt;&lt;iframe src="http://rcm-jp.amazon.co.jp/e/cm?t=usuilog-22&amp;o=9&amp;amp;p=13&amp;l=st1&amp;amp;mode=books-jp&amp;search=Perl&amp;amp;fc1=&amp;lt1=&amp;amp;lc1=&amp;bg1=&amp;amp;f=ifr" marginwidth="0" marginheight="0" border="0" style="border: medium none ;" frameborder="0" height="60" scrolling="no" width="468"&gt;&lt;/iframe&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2550436420816136794-5896124805625210749?l=usuilog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://usuilog.blogspot.com/feeds/5896124805625210749/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2550436420816136794&amp;postID=5896124805625210749' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2550436420816136794/posts/default/5896124805625210749'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2550436420816136794/posts/default/5896124805625210749'/><link rel='alternate' type='text/html' href='http://usuilog.blogspot.com/2006/11/timepiecelocalime-oneyear.html' title='[Perl]Time::Piece::localime + ONE_YEARで小ハマリ'/><author><name>usuihiro</name><uri>http://www.blogger.com/profile/18033487413398851661</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2550436420816136794.post-7498303255220925516</id><published>2006-11-30T11:48:00.001+09:00</published><updated>2006-12-14T14:03:58.031+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programming'/><category scheme='http://www.blogger.com/atom/ns#' term='Perl'/><title type='text'>[Perl]無限ループを書く最も簡単な方法？</title><content type='html'>普通無限ループといったら&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;while(1){&lt;br /&gt;   # なんらかの処理&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;といった形で書くと思います。&lt;br /&gt;しかしPerlプログラマは怠惰です。一文字でも多くタイプするのを好まないでしょう。1をタイプするのが面倒なので次のように書きましょう。&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;while(){&lt;br /&gt;   # なんらかの処理&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;これで見事に無限ループしてくれます。&lt;br /&gt;&lt;br /&gt;尚、当然ですが以下のように明らかに偽と評価されるものだとループに入りません。&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;while(undef){&lt;br /&gt;   # なんらかの処理&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;while(''){&lt;br /&gt;   # なんらかの処理&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;while(()){&lt;br /&gt;   # なんらかの処理&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;while(0){&lt;br /&gt;   # なんらかの処理&lt;br /&gt;}&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;残念なのは後置にすると無限ループしないところです。これができれば更にタイプ量が減ってうれしいのですが。&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;print "hello." while();&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;きっと役に立たない知識ですね。。。（というより紛らわしいので迷惑です）&lt;br /&gt;Perlがどう解釈しているのかさっぱりわからない。。。&lt;br /&gt;&lt;br /&gt;&lt;iframe src="http://rcm-jp.amazon.co.jp/e/cm?t=usuilog-22&amp;o=9&amp;p=13&amp;l=st1&amp;mode=books-jp&amp;search=Perl&amp;fc1=&amp;lt1=&amp;lc1=&amp;bg1=&amp;f=ifr" marginwidth="0" marginheight="0" width="468" height="60" border="0" frameborder="0" style="border:none;" scrolling="no"&gt;&lt;/iframe&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2550436420816136794-7498303255220925516?l=usuilog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://usuilog.blogspot.com/feeds/7498303255220925516/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2550436420816136794&amp;postID=7498303255220925516' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2550436420816136794/posts/default/7498303255220925516'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2550436420816136794/posts/default/7498303255220925516'/><link rel='alternate' type='text/html' href='http://usuilog.blogspot.com/2006/11/perl_29.html' title='[Perl]無限ループを書く最も簡単な方法？'/><author><name>usuihiro</name><uri>http://www.blogger.com/profile/18033487413398851661</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2550436420816136794.post-7896149755471138812</id><published>2006-11-22T12:28:00.001+09:00</published><updated>2006-12-14T14:03:45.134+09:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='Programming'/><category scheme='http://www.blogger.com/atom/ns#' term='Perl'/><title type='text'>[Perl]myと後置ifでstatic変数が作れる？</title><content type='html'>myと後置ifでstatic変数のような動きになるけどこれは仕様上想定内の動きなのだろうか？&lt;br /&gt;&lt;pre&gt;&lt;br /&gt;use strict;&lt;br /&gt;sub counter {&lt;br /&gt;  my $cnt if (0);&lt;br /&gt;  ++$cnt;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;print (counter() . "\n") for (1..3);&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;実行結果&lt;br /&gt;&lt;pre class="console"&gt;&lt;br /&gt;1&lt;br /&gt;2&lt;br /&gt;3&lt;br /&gt;&lt;/pre&gt;&lt;br /&gt;&lt;br /&gt;&lt;iframe src="http://rcm-jp.amazon.co.jp/e/cm?t=usuilog-22&amp;o=9&amp;p=13&amp;l=st1&amp;mode=books-jp&amp;search=Perl&amp;fc1=&amp;lt1=&amp;lc1=&amp;bg1=&amp;f=ifr" marginwidth="0" marginheight="0" width="468" height="60" border="0" frameborder="0" style="border:none;" scrolling="no"&gt;&lt;/iframe&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2550436420816136794-7896149755471138812?l=usuilog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://usuilog.blogspot.com/feeds/7896149755471138812/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2550436420816136794&amp;postID=7896149755471138812' title='0 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2550436420816136794/posts/default/7896149755471138812'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2550436420816136794/posts/default/7896149755471138812'/><link rel='alternate' type='text/html' href='http://usuilog.blogspot.com/2006/11/myifstatic.html' title='[Perl]myと後置ifでstatic変数が作れる？'/><author><name>usuihiro</name><uri>http://www.blogger.com/profile/18033487413398851661</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-2550436420816136794.post-6468771961975078425</id><published>2006-10-31T14:12:00.001+09:00</published><updated>2007-01-11T10:25:42.098+09:00</updated><title type='text'>はじめに</title><content type='html'>プログラミング関連のこととか書いていきます。多分。&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/2550436420816136794-6468771961975078425?l=usuilog.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://usuilog.blogspot.com/feeds/6468771961975078425/comments/default' title='コメントの投稿'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=2550436420816136794&amp;postID=6468771961975078425' title='1 件のコメント'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/2550436420816136794/posts/default/6468771961975078425'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/2550436420816136794/posts/default/6468771961975078425'/><link rel='alternate' type='text/html' href='http://usuilog.blogspot.com/2006/10/test.html' title='はじめに'/><author><name>usuihiro</name><uri>http://www.blogger.com/profile/18033487413398851661</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='http://img2.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry></feed>
