約 2,903,626 件
https://w.atwiki.jp/mhikichi/pages/26.html
マージソート 併合処理を繰り返して並べ替えをするマージソートについて実装してみます。 今回のプログラムは基本情報技術者平成22年春期のアルゴリズム問題を参考に実装します。 元の問題と見比べて参考にしてみてください。 HTMLの修正 今回はデータが多い方がソートの効果が出やすいので、元のカードの並び替えるように実装します。 ソートボタンを開始ボタンの隣に追加できるように以下の行を追加しておきましょう。 INPUT TYPE="button" NAME="cmdSort" value="ソート" onclick="startsort()" startsort()が今回のプログラムの始まりです、 併合処理の修正 前回の併合処理では、HIGH-VALUEを使って終了判定をしていました。 マージソートの実装ではHIGH-VALUEを使いにくいので、違う手法を採用します。 最初はHIGH-VALUEがあるパターンと同じです。 カードを比べて、小さい方を出して行きます。 この場合は1と3の比較で1が出されました。 続いて2,3の比較で2が出されました。 続いて3,5の比較で2が出されました。 続いて4,5の比較で2が出されました。 続いて4,5の比較で2が出されました。 HIGH-VALUEがありませんので、この場合は比較対象がありません。 こうなる直前に比較をやめる必要があります。 繰り返しの条件は、HIGH-VALUEがある場合とは変わってきます。 この場合は、 「どちらかのカードが無くなった時」終わります。 繰り返すための条件に言い換えると、 「どちらのカードもまだある時」繰り返します。 しかし、ここで終了するとカードが残ってしまいます。 どちらかのカードがまだ余っていますので、それらを全て出し終われば終了です。 以下にコメントとともにソースコードを示します。 merge2()として前回のmerge()とは別に作ります。 slist1とslist2は配列として受け取ります。 num1,num2はそれぞれのサイズです。 マージした結果はlistという配列に受け取ります。 function merge2(slist1,num1,slist2,num2,list) { var i,j; i=0; j=0; while(i num1 j num2) { // i,j両方のカードがまだある間繰り返す。 if( slist1[i].num slist2[j].num ) { // slist1のカードが小さい場合 list[i+j] = slist1[i]; // listに入れて i=i+1; // slist1を進める } else { // slist2のカードが小さい場合 list[i+j] = slist2[j]; // listに入れて j=j+1; // slist2を進める } } // ここまでで、どちらかのカードが無くなっている while(i num1 || j num2 ) { // どちらかがまだ無くなっていない間繰り返す if( i num1 ) { // slist1がまだ残っている場合 list[i+j] = slist1[i]; // slist1のカードをlistに入れて i=i+1; // slist1を進める } else { // slist2がまだ残っている場合 list[i+j] = slist2[j]; // slist2のカードをlistに入れて j=j+1; //slist2を進める } } } 前回のマージと違い、表示領域ではなく配列に併合していきます。 未だここまででは、結果には現れませんが、実行してみて動作確認はしておきましょう。 今までのプログラムも動かなくなっていたら、何か間違えているのでここで修正します。 マージソートの仕組み 併合処理を利用してマージソートは出来ています。 併合処理の前提は、「それぞれが既に並び変わっている」ことです。 最初は、全く並び変わっていないことが想定されるので、半分ずつに分割していきます。 最終的に分割したものが1枚になれば、その組は並んでいると見なせます。 分割が終了してから併合を開始します。 分割された部分から順次並び変わります。 それぞれが並び変わったら併合処理を繰り返していくと、最後には全て並び変わった状態になります。 仕組みが分かったところで実装します。 function mergesort(list,num) { ここにプログラムを書く } list は並び替えたい配列。numはその大きさを受け取ってきます。 内部で使う配列を宣言します。 var slist1=[]; //分割する片方の配列 var slist2=[]; //分割するもう一方の配列 var num1; // slist1の大きさ var num2; // slist2の大きさ var i; //ループ用の変数 まず、1個のデータしか残っていない場合は並び替えようが無いので、何もしません。 2個以上のデータの場合は、並び変わる可能性があります。 if(num 1) { // 2個以上なら処理をする ほかのプログラムはさらにこの中に書く } 分割するサイズを計算します。 num1=Math.floor(num/2); //全体の半分にしますが、端数は切り捨てます。 num2=num-num1; //全体から残り半分の大きさを計算します。 これにより、例えばnumが7個の場合は3個と4個に分割されます。 分割処理を行います。単純にnum1個のデータをlistから slist1にコピーしています。 for(i=0;i num1;i++) { slist1[i]=list[i]; } 分割処理その2です。先ほどnum1番目まで終わりましたからその続きからコピーします。 コピーする数はnum2です。 for(i=0;i num2;i++) { slist2[i]=list[num1+i]; } 次が、このマージソートの肝になる部分です。 再帰呼び出しという手法を用いています。自分自身がプログラムを呼び出しています。 分割したそれぞれについてマージソートを行うように命令を出します。 mergesort(slist1,num1); // 前半部分をマージソート mergesort(slist2,num2); // 後半部分をマージソート merge2(slist1,num1,slist2,num2,list); // 前半と後半は並び変わったので、それを併合する 最後に仕上げです。 最初にHTMLで作成したボタンはstartsort()という関数を呼び出します。 ここで最終結果を表示するために dispCard()を呼び出します。 function startsort() { mergesort(cards,cardcnt); // カードをマージソートする dispCard(); // カードの表示 }
https://w.atwiki.jp/mhikichi/pages/23.html
今まで作って来たトランプを基本に配列のずらしこみを学びます。 準備 HTMLとCSSを準備します。 トランプその2で作成したプログラムをForkしましょう。 線形探索のプログラムも後半で使います。 HTMLとCSSを準備します。 このページで作成するプログラムで共通で使用します。 HTML html body form name="form1" br INPUT TYPE="button" NAME="cmdCalc" value="開始" onclick="start()" /form div id="disp" /div form name="form2" INPUT TYPE="button" NAME="cmdGet" value="カードをもらう" onclick="getcard()" INPUT TYPE="button" NAME="cmdPut" value="カードを返す" onclick="putcard()" br どのマーク?(0 ♠,1 ♣, 2 ♥, 3 ♦) INPUT TYPE="text" NAME="txtA" br どの数字?(1~13) INPUT TYPE="text" NAME="txtB" br INPUT TYPE="button" NAME="cmdPut2" value="指定したカードを返す" onclick="putcard2()" /form div id="disp2" /div /body /html トランプその2で作成したHTMLにボタンをいくつか追加しています。 getcard() カードをもらうボタン putcard() カードを返すボタン putcard2() 指定したカードを返すボタン 手札の準備 カードをもらって手札にする処理を考えます。 カードの枚数が増減しますから、それぞれのカード枚数を保存するための変数を用意します。 プログラムではカードの枚数に合わせた処理になるよう修正していきます。 先頭に以下の変数を定義します。 var cards=[]; //既に定義済みのトランプを保存する配列 var mycards=[]; // 追加。手札のカードを保存する配列 var cardcnt; // 追加。トランプの枚数を保存する変数 var mycardcnt; // 追加。手札の枚数を保存する変数。 カードの初期化を行う関数(initCard)を修正します。 最後に以下の一文を追加してください. cardcnt=13*4; 最初のカードの枚数で初期化しています。 新しく手札を初期化する関数(initMyCard)も作ります。 function initMyCard() { mycardcnt=0; } 最初は手札がありません。枚数が0枚であることを設定しています。 次に表示用のプログラム(dispCard)を修正します。 これまではカードの枚数が決まっていましたが、カードの枚数が変数cardcntに格納されています。 繰り返し条件を変更して以下のようにします。 for(i=0;i cardcnt;i++) { tempHtml = tempHtml+ markimg[cards[i].mark] + " " + numimg[cards[i].num] +" /font "; } 次に手札の表示用のプログラムを新しく書きます。(dispMyCard) dispCardとほぼ同じプログラムです。 function dispMyCard() { var tempHtml = ""; for(i=0;i mycardcnt;i++) { tempHtml = tempHtml+ markimg[mycards[i].mark] + " " + numimg[mycards[i].num] +" /font "; } tempHtml += " BR "; document.getElementById("disp2").innerHTML = tempHtml; } 変更点はcards mycardsと cardcnt mycardcnt , 表示する領域は disp2 です。 また、今までdispCardの中で宣言されていた markimgとrumimgは共通で使うため関数の外部に移動します。 var markimg = [" font color='black' ♠"," font color='black' ♣"," font color='red' ♥"," font color='red' ♦"]; var numimg = ["","A","2","3","4","5","6","7","8","9","10","J","Q","K"]; ここで、手札を含めて初期化できるようにstart関数を修正します。 function start() { initCard(); initMyCard(); //追加 shuffleCard(); dispCard(); dispMyCard(); //追加 } 手札の初期化と表示を追加しましょう。 ここまでで動作確認をしておきましょう。特に新しい機能が追加されたわけではありませんが、修正によって現状維持できているかを確認する事は大切です。 配列ずらしこみ ボタンを押すとカードを一枚手札に入れる処理を書きます。 場のカードの一番先頭を手札に最後に入れることにします。 まずは処理イメージからです。 先頭のカードを抜いて一時保存の領域に保存しておきます。 続いてずらしこみのイメージです。 空けたカードの位置へ向かって順次繰り返しで隣のカードをコピーしていきます。処理中は同じカードが2枚存在するように見えます。 関数 getcardを作成します。 function getcard() ここにプログラムを書く } カードを一時保存する変数cと繰り返し用の変数iを宣言しておきます。 var c; var i; 引くカードが無ければ処理を続けることはできません。 最初にカードの枚数が0より大きいことを確認します。 if( cardcnt 0 ) { ここに処理を書く } カードを引く処理では、最初に先頭のカードを一時保存用の変数cに代入します。 c = cards[0]; ずらしこみの基本的なプログラムです。先頭のカードは一時保存用の変数に入れましたから、そこへ次々とカードをずらしていきます。cards[i]とcards[i+1]は常に隣のカードを表しています。 for(i=0;i cardcnt;i++) { cards[i]=cards[i+1]; } カードのずらしこみが終わったら、カード枚数を一枚減らします。 cardcnt--; 続いて、一時保存しておいたカードを手札のカードの配列に入れます。 mycardcntにはカードの枚数が入っていますが、配列の最後の添え字も表しています。さらに手札の枚数を一枚増やしておきます。 mycards[mycardcnt]=c; mycardcnt++; 最後に移動したカードを表示するためにカード表示用関数を呼び出します。 dispCard(); dispMyCard(); ここまでの完成版のプログラムです。カードを返すボタンは練習で作成するので、まだ未完成です。 練習 手札のカードの先頭のカードを場札のカードに返す関数 putcard を作成しましょう。基本的にはgetcardの逆の操作を行えばOKです。 手札にカードをもらう時に、最後では無く先頭にカードをもらうように修正してみましょう。先頭にカードをもらうためには、後ろの方にカードをずらしこみをして先頭をあけてから新しいカードを入れましょう。 繰り返す順番に注意
https://w.atwiki.jp/reaper-matome/pages/2.html
ReaScript編 ReaScript入門ガイド はじめに 使ってみよう編 探してみよう編 作ってみよう編 スクリプトをつかう メニューへの登録 キーバインドについて マウスコマンドの編集 拡張:起動時に実行する 拡張:サイクルアクション スクリプトをさがす 拡張機能の紹介 スクリプトの紹介 コミュニティ スクリプトをつくる 言語について 開発環境をつくろう 開発のすすめかた 拡張機能について 開発Tips ループするスクリプト 変数の値を保存する ※随時追加予定 JSFX編 ※更新中 日本語版APIリファレンス ※おことわり ReaScript基本API ※更新中 SWS Extentions ※更新中 テーマ開発編 はじめに テーマの作り方 WALTERについて Theme Adjusterとの連携 各コントロールパネル解説 グローバル設定 トラックCP マスタートラックCP エンベロープCP ミキサーCP マスターミキサーCP 再生コントローラー
https://w.atwiki.jp/hear_br0wn/pages/56.html
●JSON形式(JavaScript Object Notation) 配列変数(Array)・オブジェクト変数(Object)の値を一括で設定できる方法 【初期化】 ●配列 例: 初期化と値を一括設定 var a_ary = [10,20,30]; 値を参照 trace(a_ary[0]); trace(a_ary[1]); trace(a_ary[2]); ●オブジェクト変数 初期化と値を一括設定 var a_obj = {"key1" 30, "key2" 100, "key3" 500}; 値を参照 trace(a_obj["key1"]); trace(a_obj["key2"]); trace(a_obj["key3"]); ※以下のサイトでまとめられている http //www.json.org/ 例:
https://w.atwiki.jp/sakaj/pages/10.html
実行中のメソッド名を取得する。 new Throwable().getStackTrace()[0].getMethodName(); javascript document.cookie; プレースホルダ String year = yyyy.format(selectedDate); String month = MM.format(selectedDate); String date = dd.format(selectedDate); Object[] dateArgs = { year, month, date }; MessageFormat form = new MessageFormat("{0}年{1}月{2}日"); e.printStackTrace?()の文字列を取得する StringWriter stringWriter = new StringWriter(); ex.printStackTrace(new PrintWriter(stringWriter)); String message = stringWriter.getBuffer().toString(); ソースをShift_JISで書いて、EUC-JPで出力するってこと %@ page contentType=text/html; charset=EUC-JP" pageEncoding="Shift_JIS" % Javaから、WEBブラウザを起動(Windowsのみ) Runtime.getRuntime().exec( new String[] { "rundll32.exe", "url.dll,FileProtocolHandler", "http //jp.sun.com/" }); WEBアプリケーションのルートを取得してパスを生成する String root_path = this.getServletContext().getRealPath("/"); String file_path = root_path + "hoge.dat" Set-Cookie UserName=lightbox Cookie UserName = new Cookie( "UserName", "lightbox" ); response.addCookie( UserName ); DOM取得 public Document getDocument( String xml ){ try { // ドキュメントビルダーファクトリを生成 DocumentBuilderFactory dbfactory = DocumentBuilderFactory.newInstance(); // ドキュメントビルダーを生成 DocumentBuilder builder = dbfactory.newDocumentBuilder(); // パースを実行してDocumentオブジェクトを取得 System.out.println(getTextXml()); Document doc = builder.parse( new ByteArrayInputStream( xml.getBytes("UTF-8") ) ); return doc; // ルート要素を取得(タグ名:message) Element root = doc.getDocumentElement(); // 最初の子ノード(テキストノード)の値を表示 System.out.println(root.getFirstChild().getNodeName()); } catch (Exception e) { e.printStackTrace(); } } public class SgPsr{ public Object parse( Node n ){ //Node root = doc.getDocumentElement(); if( n.getNodeType()==Node.TEXT_NODE n.getNodeValue().trim().length()==0 ){ return ""; } NodeList cc = n.getChildNodes(); for( int i=0; i cc.getLength(); i++ ){ Node c = cc.item(i); String name = c.getNodeName(); if( name.equals("ItemSearchResponse") ){ return parse(c); } if( name.equals("Items") ){ return parseItems(c); } } return ""; } public Object parseItems( Node n ){ List aa = new ArrayList(); NodeList cc = n.getChildNodes(); for( int i=0; i cc.getLength(); i++ ){ Node c = cc.item(i); String name = c.getNodeName(); if( name.equals("Item") ){ aa.add( parse(c) ); } } return ""; } } dump Query //dump Query public String dumpQuery(HttpServletRequest request){ Map ?, ? qsMap = request.getParameterMap(); Set ? ks = qsMap.keySet(); Map ? m = new HashMap(); for( Iterator ? i = ks.iterator(); i.hasNext(); ){ String k = i.next()+""; String[] v = (String[])qsMap.get(k); m.put(k, v[0]); } return ""+m; } ファイルのタイムスタンプを取得する。 File fp; long tm; java.util.Date da; String timeStr; fp = new File("test.txt"); tm = fp.lastModified(); da = new java.util.Date( tm ); timeStr = new String(DateFormat.getDateTimeInstance().format(da) ); MD5 MessageDigest md = MessageDigest.getInstance("MD5"); byte[] xx = "password".getBytes(); md.update(xx);//dat配列からダイジェストを計算する byte[] yy = md.digest(); Hex public String toHexString(byte[] arr) { StringBuffer buff = new StringBuffer(arr.length * 2); for (int i = 0; i arr.length; i++) { String b = Integer.toHexString(arr[i] 0xff); if (b.length() == 1) { buff.append("0"); } buff.append(b); } return buff.toString(); }
https://w.atwiki.jp/submarine/pages/184.html
Actionscript Library Actionscriptは3Dやモーション関係も多いですが、そちらはあまり興味がないので省略。 Imageproseccing Library ベーシックな画像処理ライブラリ(Creative Common License) ※追記 実際にjoa-ebertさんのImage Processing Library を試してみました。 これは、Webcum に特化した画像処理ライブラリですね。 高速な分、精度的には今ひとつ。 写真の加工編集などには向かないです。残念。 PortAs? 2色画像のベクタ変換(GPL) Group Loader BulkLoader 画像読込 AS+Flex SDKってたかが画像読込が非常に面倒だったりする。 BMP Decoder PSD Perser デコーダ・パーサ
https://w.atwiki.jp/hide1227/pages/16.html
【参考文献】:AJAX HACKS 6章 Hacks45-52(p207~) MVCアーキテクチャ MVCとはデザインパターンの一種で、アプリケーションの構成を、Model、View、Controllerというコンポーネントに分けて設計する手法を言う。 Ruby On Rails のインストール 編集中。。。あまりここに時間を割きたくないな。ぼそ ここでは、InstantRails-1.7-win.zipを導入して使います。 Rails アプリの作成 1.開発環境 始める前に、念のため開発に使用するマシンのスペックを調べておきます。 Windows XP SP2 であれば、まあ問題ないでしょう。今回はWindows2000でやってみます。 ちなみに、マシンスペックの調べ方は、コマンドで「dxdiag」 C \InstantRails\rails_apps dxdiag 今回の開発環境のサンプル) ------------------ System Information ------------------ Time of this report 10/16/2008, 09 52 20 Machine name HIDE2000 Operating System Windows 2000 Professional (5.0, Build 2195) Service Pack 4 Language Japanese (Regional Setting Japanese) System Manufacturer VMware, Inc. System Model VMware Virtual Platform BIOS Default System BIOS Processor Intel(R) Core(TM)2 Quad CPU Q6600 @ 2.40GHz, ~2.4GHz Memory 724MB RAM Page File 408MB used, 1049MB available Windows Dir C \WINNT DirectX Version DirectX 9.0c (4.09.0000.0904) DX Setup Parameters Not found DxDiag Version 5.03.0001.0904 32bit Unicode 【補足:開発支援の為のIDE Tool】 開発支援の為のIDEToolとして、eclipseかAptanaかNetBeansなどを利用すると便利だと思います。 今回は「eclipse」に「Aptana」プラグイン、「RadRails」プラグインを仕込んで使います。(※) ※)手っ取り早く環境を構築するには? これらが全部そろった「pleiades-all-in-one-ultimate_20081006.zip」がお勧めです。(=>ダウンロードはこちらから。Eclipse 3.4.1 Ganymedeのultimateがお勧めです。ちなみに3.3.1のほうにはultimateでも今回使いたいRadRailsのプラグインが入ってませんでした。。。) ※) eclipse 3.2.1 に RadRailsプラグインを追加する方法 AptanaプラグインとRailsプラグインのインストール Eclipseを起動し、「ヘルプ」→「ソフトウェアの更新」→「検索してインストール」を選びます。 ダイアログボックスが出たら「新規フィーチャーを探す」を選びます。 アップデートサイト選択画面で「新規リモート」を選びます。 ここでは次の2つのサイトを登録します。 ・http //update.aptana.com/install/3.2/ ・http //update.aptana.com/install/rails/3.2/ 1つ目がAptana本体、2つ目がAptanaのRailsプラグインになります。 リモートサイトを2つ登録し終わったら、「次へ」をクリックし、 以降は通常の更新機能と同様に操作して、インストールを行います。 Railsパースペクティブを開く プラグインのインストールが終わり、Eclipseを再起動したら、 Railsパースペクティブを開きます。 「ウィンドウ」→「パースペクティブを開く」→「その他」の中に 「Rails」というパースペクティブがあるので、これを選択します。 ここを参考にしました。http //blog.codezine.jp/editor/2007/06/aptana_eclipseruby_on_rails_1.phpちなみに、3.3.x だとうまくいきません。3.3用のURLもどこかにあると思いますが、 それは調べていません。 2.Railsのヴァージョン Railsの開発の場合、特にヴァージョンの組み合わせは重要です。 今回は、InstantRails-1.7-win.zipをインストールして準備した環境なので、「Rails 1.2.3」になります。このヴァージョンが現在最も情報量が豊富です。(=>ダウンロードはこちらから。) ※ rubyの最新の1.9などは1.8.6に比べてだいぶ変わったようですし、フレームワークであるrailsもヴァージョンが1.2.X系と2.X系ではscaffoldなどかなりやり方が異なります。パッケージ管理Toolであるgemなども実はgem自体のヴァージョンによりインポートできるモジュールのヴァージョンが違ったりと、手抜かりがあるとなかなか手こずりますので注意しましょう。 C \InstantRails\rails_apps ruby -vruby 1.8.6 (2007-03-13 patchlevel 0) [i386-mswin32] C \InstantRails\rails_apps gem envRubyGems Environment - VERSION 0.9.2 (0.9.2) - INSTALLATION DIRECTORY C /InstantRails/ruby/lib/ruby/gems/1.8 - GEM PATH - C /InstantRails/ruby/lib/ruby/gems/1.8 - REMOTE SOURCES -http //gems.rubyforge.org C \InstantRails\rails_apps rake --version rake, version 0.7.2 C \InstantRails\rails_apps rails --version Rails 1.2.3 C \InstantRails\rails_apps mysql --version mysql Ver 14.12 Distrib 5.0.27, for Win32 (ia32) ・ もうひとつのヴァージョンの調べ方 ひとつひとつのコマンドを打ち込んでヴァージョンを調べてもいいけれども、Railsの場合たくさんのパッケージやモジュールで構成されていて調べるのはいささか面倒です。そこで一発でこれらを調べるコマンドを紹介します。ただし、これはプロジェクト内部のaboutコマンドなので、少なくとも後述するプロジェクトを何かひとつ作成してから、実行してください。 // これはうまくいきません。 C \InstantRails\rails_apps ruby script/about C \InstantRails\rails_apps\hacks ruby script/aboutAbout your application s environmentRuby version 1.8.6 (i386-mswin32) RubyGems version 0.9.2 Rails version 1.2.3 Active Record version 1.15.3 Action Pack version 1.13.3 Action Web Service version 1.2.3 Action Mailer version 1.3.3 Active Support version 1.4.2 Application root C /InstantRails/rails_apps/hacks Environment development Database adapter mysql 3.作成手順 RailsアプリはDB利用を前提としたWebアプリになるため、Railsの命名規則が重要になってきます。ここら辺はDRYやCoCの思想によるところですが、今回のAjax用のRailsアプリサンプルとして以下の情報をまず収集します。 プロジェクト名:プロジェクトのルートとなる名前、主にフォルダ管理のため。 使用するRDB:MySQL,SQLite3,PostgreSQL,SQL Server,DB2,Oracle DB名:開発用、テスト用、リリース用の三種類を用意します。 テーブル名:複数形小文字英数字 モデル名:原則としてテーブル名と関連します。単数形のテーブル名 それでは、今回のAjax用のRailsアプリサンプルの情報を定義していきましょう。 プロジェクト名:hacks 使用するRDB:mysql DB名:hacks_development,hacks_test,hacks_production テーブル名:kilowatts モデル名:Kilowatt ここで、一応テーブルの定義も決めておきましょうか。 Kilowattsテーブル定義 NO カラム名 型 NotNull 主キー 1 id int true true 2 kdate text 3 kwatts int DDLファイルを作成するとしたら、以下のようになるかと思います。(※) DDL kilowatts.sql DROP TABLE IF EXISTS kilowatts; CREATE TABLE kilowatts ( id MEDIUMINT NOT NULL AUTO_INCREMENT, kdate TEXT, kwatts INT, PRIMARY KEY(id) ); ※)ただし、Railsの作成方法では、このようなDB周りの準備もRailsでサポートされており、具体的には「マイグレーション」という手法を使います。ちなみに、この作成方法はRails 1.2.x 系列とRails 2.x 系列で作成手順が違います。これは追って説明します。 【参考】:ソースダウンロード ちなみに、このページはUTF8になります。ブラウザで文字化けなどしたらエンコードを変更してみてください。AjaxHacksSamples.zipを解凍してサンプルコードを手に入れてください。 【事前準備】 InstantRailsでインストールした場合は、InstantRails.exe は起動しておきましょう。起動するとApacheとMySQlが立ち上がります。後ほどRailsからDBを作成したり、テーブルを作成しますが、そのためには今回使用するMySQLがサービスとして起動している必要があります。Webサーバは開発モードでは他の(Mongrelサーバ)を使うのでApacheは立ち上げる必要性はないですが、DBの確認作業で、phpMyAdminというToolを使う場合はApacheサーバを立ち上げておく必要があります。 また、DBにMySQLを使用するのであれば、最初に、my.iniファイルにてDBの文字コード指定をしておきます。以下のソースの青字部分を追記してください。 C \InstantRails\mysql\my.ini ; ---------------------- IMPORTANT ---------------------------; ; ${path} is used to specify Instant Rails installation path. ; ;-------------------------------------------------------------; [mysqld] datadir=${path}/mysql/data basedir=${path}/mysql bind-address=127.0.0.1 ; Uncomment for use on USB key ; skip-innodbdefault-character-set=utf8 skip-character-set-client-handshake ここまで準備すれば、雛形部分の作成は15分もかからないでしょう。 【プロジェクトの作成】 // 1.0 railsアプリのルートフォルダに移動 // InstantRailsでインストールした場合には、その下に「rails_apps」があるはず。そこです。C \ cd C \InstantRails\rails_apps // 2.0 railsコマンドの実行 // 通常は、Rails 1.2.3 の場合、DBは mysql になります。 // rails hacks // // デフォルトじゃないDBシステムを指定するには // rails hacks -d mysql // かもしくは、 // rails hacks --database=mysql //C \InstantRails\rails_apps rails hacks -d mysql 【DB作成】 DBの作成の仕方には幾通りかあります。各ベンダーにより簡単なやりかたがそれぞれあるでしょうが、RailsにはrakeコマンドでDB作成Toolを作成することもできます。それを使用すればマルチDBの作成が夢ではないと思いますが、それは次回のテーマに譲ることにして、ここでは、使用するDBをMySQLとした場合、InstantRails導入した際に利用できるphpMyAdminを使用して簡単に作成してしまいましょう。InstantRails.exeが立ち上がっている状態であれば、以下のURLにアクセスできるはずです。 http //127.0.0.1/mysql/ 今回作成するDBは三種類です。 hacks_development hacks_test hacks_production これは先ほどのプロジェクトの作成の際に自動で命名規約されているDB名です。もちろんこれを変更することも可能ですが、それは以下のリソースに定義してあります。まず素直に自動生成されたソースを覗いてみましょう。 C \InstantRails\rails_apps\hacks\config\database.yml development adapter mysql database hacks_development username root password host localhost test adapter mysql database hacks_test username root password host localhost production adapter mysql database hacks_production username root password host localhost 今回はここでデフォルトに指定されているDB名をそのまま使用することにします。DB名を変えたければ、[database ]の値を変えればいいでしょう。 ちなみに、今回はMySQLなのでこのまま使用しますが、Oracleなどの場合は、DBを複数作成するよりも、スキーマを3つ用意したほうが現実的だと思われます。 【補足:文字コード問題】 my.iniに指定したように、このdatabase.ymlファイルでも文字コードを指定します。3つのDB定義の最後の要素にそれぞれ以下を追加します。(※MySQL使用時には必要ですがOracle使用する場合は必要がないようです。) encoding utf8 また、文字コード問題というと、DBの文字コードだけでなく、Ruby自体の文字コード指定をする必要があります。 今回のRailsアプリの文字コード指定は、「environment.rb」というファイルでの最初の行で設定します。 例)文字コードをUTF-8に指定するやりかた。 $KCODE = "UTF8" もしくは、 $KCODE = u どちらも同じ意味です。最初の 1 バイトしか読み取っていないようです。しかも大文字小文字すら関係ないようです。でも自分としては可読性を考慮してUTF8と記述したいところです。 【参考サイト】http //www.ruby-lang.org/ja/man/html/_C1C8A4DFB9FEA4DFCAD1BFF4.html では、phpMyAdminのサイトにてこれらの3つのDBを作成してみましょう。 確認は、phpMyAdminでもできますが、コンソールからDBが作成されたことを確認してみます。 C \InstantRails\rails_apps\hacks mysql -u root Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 18 to server version 5.0.27-community Type help; or \h for help. Type \c to clear the buffer. mysql show databases; +----------------------------------------+ | Database | +----------------------------------------+ | information_schema | |hacks_development | |hacks_production | |hacks_test | +----------------------------------------+ 29 rows in set (0.01 sec) mysql 【eclipse へインポート】 この辺で、今後の作業の円滑を図り、eclipseへプロジェクトごとインポートしておきます。 プロジェクトを選択 選択してOK押下 作成されたことを確認 プロジェクトをマウントしたら、すかさずeclipseプロジェクト上の文字コードをUTF8に設定する。 【テーブルの作成】事前準備してあるテーブル定義書に従い、Rails用のDDLファイルといえるマイグレーションファイルを作成します。 作成の手順は、Rails 1.2.3 と Rails 2.0.2 では微妙に異なります。Rails 1.2.3では、 ジェネレータの「migration」サブコマンドにてマイグレーションファイルのスタブを作成して後 テーブル定義書に従い、マイグレーションファイルの編集 「db migrate」コマンドを実行する。 その後、「scaffold」を実行し、テーブルに対応するモデルクラスやコントロールクラスのCRUD構成を一気に作成する。 という手順になるが、Rails 2.0.2では 「scaffold」にて、MVCアーキテクチャのすべてのソースを一気に作成する。 「db migrate」コマンドを実行する。 ただし、その際の「scaffold」のコマンドオプションの指定の仕方が変わりました。カラム名や型を同時に宣言しなければならなくなりました。 ここでは、Railsのヴァージョンは 1.2.3 なので、最初の手続きによるやり方で行う。 ちなみに、eclipse の RadRailsパースペクティブにおいては、generatorというviewが存在し、 そこでコマンドを実行が可能です。 ここでは、コマンドラインでの実行方法を紹介します。(Rails 1.2.3の場合) C \InstantRails\rails_apps\hacks ruby script/generate migration create_kilowatts create db/migrate create db/migrate/001_create_kilowatts.rb C \InstantRails\rails_apps\hacks ちなみに、Rails 2.0.2の場合は migrationではなく、ここでいきなりscaffold していいです。 C \InstantRails\rails_apps\hacks ruby script/generate scaffold kilowatt kdate text kwatts integer では、eclipse に戻って、作業領域をリフレッシュ(F5)した後、編集してみましょう。 001_create_kilowatts.rb(Rails 1.2.3の場合) class CreateKilowatts ActiveRecord Migration def self.up create_table( kilowatts) do |table| table.column kdate , text table.column kwatts , integer end end def self.down drop_table kilowatts end end 001_create_kilowatts.rb(Rails 2.0.2の場合) class CreateKilowatts ActiveRecord Migration def self.up create_table( kilowatts) do |table| table.text kdate table.integer kwatts end end def self.down drop_table kilowatts end end (※注意) Rails1.2.3とRails2.0.2の表記の違いに注意してください。また2.0.2の場合、自動生成される「table.timestamps」ですが、これはカラムの「create_at」と「update_at」に相当します。 このマイグレーションファイルはマルチDBに対応したRails独自の文法による記載になります。 非常に便利なものだが、まず各ベンダーのRDBの型との対応に注意しなければなりません。 手元には、データ型の対応表が必要になると思われる。 型 説明 MySQL SQL Server Oracle id プライマリキー int(11) int NUMBER(38) string 文字列 varchar(255) varchar(255) VARCHAR(255) text 長い文字列 text text CLOB integer 整数 int(11) int NUMBER(38) float 浮動少数 float real NUMBER decimal 精度の高い小数 decimal(10,0) decimal(18,0) NUMBER(38) datetime 日時 datetime datetime DATE timestamp 日時(より細かい) datetime datetime DATE time 時間 time datetime DATE date 日付 date datetime DATE binary バイナリデータ blob image BLOB boolean Boolean型 tinyint(1) bit NUMBER(1) create_at マジックフィールド datetime datetime DATE update_at マジックフィールド datetime datetime DATE 次に「rake db migrate」コマンドを実行する。(ちなみに eclipse の Rake view からも実行が可能だ。) C \InstantRails\rails_apps\hacks rake db migrate == CreateKilowatts migrating ================================================= -- create_table( kilowatts) - 0.0780s == CreateKilowatts migrated (0.0780s) ======================================== この時、「テーブル schema_info」も同時に作成されていることに着目しておこう。これはマイグレーションにおける履歴管理のためのテーブルで、Railsの管理の下、テーブル定義が仕様変更となっても、すぐに反映させたり、また逆に元に戻すことを可能にした仕組みだ。 この点を踏まえると、Railsを使うならば、マイグレーションなしに勝手にテーブル作成することは好ましくないといえるだろう。 【テーブル作成の確認】 C \InstantRails\rails_apps\hacks mysql -u root Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 30 to server version 5.0.27-community Type help; or \h for help. Type \c to clear the buffer.mysql use hacks_development; Database changedmysql show tables; +-----------------------------+ | Tables_in_hacks_development | +-----------------------------+ | kilowatts | |schema_info | +-----------------------------+ 2 rows in set (0.00 sec) mysql 【足場の作成】 ここで足場となるMVCアーキテクチャに沿ったソースを自動生成します。そのためのコマンドとして、先ほど紹介した「scaffold」というコマンドがあります。 C \InstantRails\rails_apps\hacks ruby script/generate scaffold kilowatt exists app/controllers/ exists app/helpers/ create app/views/kilowatts exists app/views/layouts/ exists test/functional/ dependency model exists app/models/ exists test/unit/ exists test/fixtures/ create app/models/kilowatt.rb create test/unit/kilowatt_test.rb create test/fixtures/kilowatts.yml create app/views/kilowatts/_form.rhtml create app/views/kilowatts/list.rhtml create app/views/kilowatts/show.rhtml create app/views/kilowatts/new.rhtml create app/views/kilowatts/edit.rhtml create app/controllers/kilowatts_controller.rb create test/functional/kilowatts_controller_test.rb create app/helpers/kilowatts_helper.rb create app/views/layouts/kilowatts.rhtml create public/stylesheets/scaffold.css ここまでで雛形が完成したはずです。 【動作確認】 では、早速サーバを起動させてみましょう。WebサーバはRailsでは複数用意されていますが、開発モード時点ではApacheなどは使わないです。(かといって現在あがっているApacheを落とす必要はありません。)簡易サーバとして、Mongrelサーバというものが、ありますので、今回はそれを使用します。 サーバー起動のやり方は、コマンドラインとeclipseでの起動のさせ方とありますが、ポート番号まで比較的簡単に指定できるeclipse起動のやり方を紹介します。 まず、eclipseにて対象となるプロジェクト(今回の場合は「hacks」)を選択して、Runします。 ここでOKを押下すれば、対象のサーバインスタンスが立ち上がるはずなのですが、実際には別のインスタンスが起動してしまうような現象に遭遇しました。ヴァージョンは、3.2.1でも3.4.1でも起こります。なのでその場合は、一旦関係のないサーバインスタンスを停止し、再度Serversヴューにて起動対象のサーバインスタンスを選択して実行してみてください。 以上のように起動すれば、Webアプリが起動されているはずです。 以下のURLをブラウザで指定してみましょう。 (今回はIP指定しますが、普段の開発ではHOSTはlocalhostか127.0.0.1でかまわないでしょう。) // 今回のURLhttp //192.168.1.29 3008/kilowatts/ // 通常はデフォルト指定のままなので以下のURLhttp //localhost 3008/kilowatts/http //127.0.0.1 3008/kilowatts/ ホスト名の次に指定するURIの要素がテーブル名になっていることに着目してください。 また、デフォルトの入り口が、indexになるのですが、実際にはlist画面にリダイレクトされています。ここは、Railsの仕組みをもう少し追いかけていくことで判明します。 とりあえず、ここまでで Railsのアプリの土台部分がが作成できました。 おめでとうございます!! Ajaxライブラリの導入方法 Ajaxには多数のライブラリが存在しており、現在では生で「XMLHttpRequest」オブジェクトを操作することはあまり機会がなくなっているといえるんではないでしょうか。最も有名なライブラリは「Prototype」ですが、これはどうやらRuby On Railsがそのルーツだそうです。ということで Railsをやるならデフォルトでついてきてます。 %= javascript_include_tag defaults% この記述でHTMLソースにはどのように変換されているか調べてみると、 script src="/javascripts/prototype.js?1224125580" type="text/javascript" /script script src="/javascripts/effects.js?1224125580" type="text/javascript" /script script src="/javascripts/dragdrop.js?1224125580" type="text/javascript" /script script src="/javascripts/controls.js?1224125580" type="text/javascript" /script script src="/javascripts/application.js?1224125580" type="text/javascript" /script でした。 自動生成された javascriptライブラリをこの一行でロードしています。一番お手軽な書式ですが、必要なものだけを指定したほうが効率がいいでしょう。その場合は、 %= javascript_include_tag"prototype.js"% ところで、このロードの順番は重要です。前後を入れ替えないこと。 逆に言うと、自分で定義した javascript関数は一番最後にロードされる「application.js」に入れるべきです。 XMLHttpRequestの使い方 XMLHttpRequestの使い方を調べるためにサンプルを作成しましょう。 RailsではXMLHttpRequestを生で使わないとはどういうことでしょうか? ひとつには、ライブラリ「prototype.js」を内部で利用しているため、そのラッパークラスを通じて操作できるためです。 しかし、Railsの場合は、さらにそれをラッピングしたメソッドが存在し、それを利用することができます。 まず、それを確かめるためのコントロールとヴューを作成したいと思います。 ここで、今回はDBを使わないので、あえてscaffoldはせずに、generateではコントローラだけを指定してモデルは作成しないことにします。必要なのはアクションとその画面のみ…ということで、このようなコマンドを実行してみます。 C(コントローラ) hacks V(ヴュー) monitor C \InstantRails\rails_apps\hacks ruby script/generate controller hacks exists app/controllers/ exists app/helpers/ create app/views/hacks exists test/functional/ create app/controllers/hacks_controller.rb create test/functional/hacks_controller_test.rb create app/helpers/hacks_helper.rb コントローラですが、hacks_controller.rb はJavaでいえばサーブレットみたいなものです。URIにも反映されます。V(ヴュー) monitorはまだここでは作成してませんが、アクション名でもあり、コントローラに実装するメソッド名でもあり、Viewとしてのrhtmlファイル名であったりします。この命名規則がしっかりしたところが、Railsが優れた生産性を誇る仕組みでもあります。この恩恵は非常に効率的ですね。MVCに着眼すれば、これからの作業の太枠が決まります。 コントローラのスタブメソッド作成 ヴューの作成 URLの決定 まずアクセス先のURLを決めてしまいます。 http //192.168.1.29 3008/hacks/monitor にすることにして、 コントローラのスタブメソッド作成します。(file ///C /InstantRails/rails_apps/hacks/app/controllers/hacks_controller.rb) class HacksController ApplicationController def index # # URI省略時のインデックスページの処理。特定のアクションにたらい回します。 # monitor render action = monitor end def monitor # # ここに処理を書きます。アクセス時の業務処理です。 # end def tmp # # ここに処理を書きます。まだメソッド名も決めてませんが「送信ボタン」に対応するアクションです。 # end end ヴューの作成 レイアウトをまず決めます。対応するコントローラに対して1本作成します。 file ///C /InstantRails/rails_apps/hacks/app/views/layouts/hacks.rhtml これは、外枠だけの入れ物なので、既存のレイアウトをそのまま複製してしまいます。タイトルくらいはそれらしく編集しておきましょう。 !DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http //www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd" html xmlns="http //www.w3.org/1999/xhtml" xml lang="en" lang="en" head meta http-equiv="content-type" content="text/html;charset=UTF-8" / %= javascript_include_tag defaults % %= stylesheet_link_tag scaffold % title Ajax呼び出し時の内部状態 %= controller.action_name % /title /head body p style="color green" %= flash[ notice] % /p %= yield % /body /html yieldに入るアクションごとの部品ヴューは file ///C /InstantRails/rails_apps/hacks/app/views/hacks/monitor.rhtml になるでしょう。 内容は、 h1 Monitor /h1 % form_tag action = tmp do % %= render partial = form % %= submit_tag 送信 % % end % な感じにしておきます。送信ボタン押下時のメソッド名をそろそろ決めておかないといけませんが、とりあえず、こうしておきます。 画面自体は出ることをサーバにて確認できます。 では、ここからいよいよメインディッシュにんります。RailsでAjaxを使うには、対応するいくつかのメソッドが用意されています。XMLHttpRequestでは「form_tag」は使用しないのです。その代わりに「form_remote_tag メソッド」を使用します。 form_remote_tag メソッド XMLHttpRequestの機能を活用するためのメソッドです。 基本構造は、 %=form_remote_tag(...param...) % div /div p %= submit_tag 送信 % /p %=end_form_tag% パラメータ部分は多少複雑です。ハッシュ形式の指定方法です。 それぞれのキー項目をみていきます。赤字は必須指定。 update = "" url = {} position = "" success = "" loading = "" loaded = "" interactive = "" failure = "" update = "表示要素のid属性値" なんだけれどもここは結構重要です。肝です。 completeや success指定との違いがわかりづらいのです。ここに参考にできる記事がありますが、もっと調べておく必要性を感じます。 url = { action = リクエストを処理するアクションのシンボル } position = "挿入位置" success = "XMLHttpRequestのreadystateが成功時" ちなみに、readystateがsuccess というのは厳密にはないはずなのだが、指定できるそうだ。completeとほとんど似た状態だが、わずかに successのほうが早い状態になります。 complete = "Element.toggle( id属性値 )" readystate 状態 意味 0 uninitialized 初期化されていない 1 loading 読み込み中 2 loaded 読み込み完了 3 interactive 操作可能 4 complete 準備完了 file ///C /InstantRails/rails_apps/hacks/app/views/hacks/monitor.rhtml %= form_remote_tag ( update = "complete", url = { action = zero_update }, position = "top", success = "$( success ).innerHTML= 成功; ステータスコード= +request.status", loading = "$( loading ).innerHTML= リクエスト送信中…; ステータスコード= +request.status", loaded = "$( loaded ).innerHTML= リクエスト送信完了; ステータスコード= +request.status", interactive = "$( inter ).innerHTML= レスポンス受信中; ステータスコード= +request.status", failure = "$( failure ).innerHTML= エラー; ステータスコード= +request.status") % h3 Ajax呼び出しの内部状態を表示します /h3 div id="loading" style="font-size 1.2em" /div div id="loaded" style="font-size 1.2em" /div div id="inter" style="font-size 1.2em" /div div id="success" style="font-size 1.2em; color green" /div div id="failure" style="font-size 1.2em; color red" /div div id="complete" style="font-size 1.2em; color green" /div p %=submit_tag 送信 % /p %=end_form_tag % file ///C /InstantRails/rails_apps/hacks/app/views/hacks/monitor.rhtml defzero_update # # ここに処理を書きます。まだメソッド名も決めてませんが「送信ボタン」に対応するアクションです。 # render text = "Ajax hello!!!" end render text = "Ajax hello!!!" ここが遷移しない仕組みです。遷移先の画面指定などはしていないのです。この例ではサーバ側の固定文字列を返していますが、コントローラで料理ができるということは、「可変データを非同期に返せる」ということです。静的なサーバ上のデータを返したいだけであるならば、もっと別の手法があります。その手法は別のテーマで触れる予定です。 変換後のHTMLは form action="/hacks/zero_update" method="post"onsubmit="new Ajax.Updater( complete , /hacks/zero_update , {asynchronous true, evalScripts true, insertion Insertion.Top, onFailure function(request){$( failure ).innerHTML= エラー; ステータスコード= +request.status}, onInteractive function(request){$( inter ).innerHTML= レスポンス受信中; ステータスコード= +request.status}, onLoaded function(request){$( loaded ).innerHTML= リクエスト送信完了; ステータスコード= +request.status}, onLoading function(request){$( loading ).innerHTML= リクエスト送信中…; ステータスコード= +request.status}, onSuccess function(request){$( success ).innerHTML= 成功; ステータスコード= +request.status}, parameters Form.serialize(this)}); return false;" h3 Ajax呼び出しの内部状態を表示します /h3 div id="loading" style="font-size 1.2em" /div div id="loaded" style="font-size 1.2em" /div div id="inter" style="font-size 1.2em" /div div id="success" style="font-size 1.2em; color green" /div div id="failure" style="font-size 1.2em; color red" /div div id="complete" style="font-size 1.2em; color green" /div p input name="commit" type="submit" value="送信" / /p /form 内部では、prototype.jsのクラスが使用されているようです。 しかも変換されているのは、「Ajax.Request」ではなく「Ajax.Updater」のようです。ほとんど似た処理ですが、サーバ上のデータをページに非同期に挿入するのに使います。 非同期の持ち味を実感するには、クライアントサイドで「onSubmit」とか「onClick」とかでは、実感が薄いですね。 トリガーとなるイベントの種類や指定方法も整理しておくといいでしょう。 その前に、 successと completeの違いについて整理しておきます。上記のソースの実行結果は、実は問題があります。 successと completeの違いについて どちらもサーバからレスポンスが返される準備が整った状態ではありますが、ステータスでいうと、まず successになり、次に completeになります。これを同じ意味と捕らえるのはもったいないことです。実際に updateで指定された要素に結果が挿入されるのは、 completeのタイミングですが、そもそも非同期処理のため、ページが遷移せず、つまりは既読のデータ(id=completeで指定された領域のデータ)は消えないのです。そのため、前回サーバより取得した値は消えずに残り、そこに追記という形で対象要素にロードされるため、意図した結果にならないでしょう。その場合に、 successのステータスにおいて対象要素の「過去の値」を消す処理を施すことができます。 %= form_remote_tag ( update = "complete", url = { action = zero_update }, position = "top", success = "$( complete ).innerHTML= ;$( success ).innerHTML= 成功; ステータスコード= +request.status", loading = "$( loading ).innerHTML= リクエスト送信中…; ステータスコード= +request.status", loaded = "$( loaded ).innerHTML= リクエスト送信完了; ステータスコード= +request.status", interactive = "$( inter ).innerHTML= レスポンス受信中; ステータスコード= +request.status", failure = "$( failure ).innerHTML= エラー; ステータスコード= +request.status") % h3 Ajax呼び出しの内部状態を表示します /h3 div id="loading" style="font-size 1.2em" /div div id="loaded" style="font-size 1.2em" /div div id="inter" style="font-size 1.2em" /div div id="success" style="font-size 1.2em; color green" /div div id="failure" style="font-size 1.2em; color red" /div div id="complete" style="font-size 1.2em; color green" /div p %= submit_tag 送信 % /p %= end_form_tag % 遷移させないということは a RailsでのAjax利用の構造 a 自作のJavaScriptはどこに書くのか? link サーバ内テンプレートを元にコンボボックス表示 a リクエストの判別方法 a DBの値を元にコンボボックス表示 a 定期的なリクエスト実行 定期的な実行を伴うAjaxの処理は、「PeriodicalExecuter」を使用しますが、Railsではこれをさらにラップして「periodically_call_remote」というメソッドを使用します。 ここでは、サンプルとして、クライアント側から非同期に、ブラウザを利用しているユーザからは意識させずに、サーバーにアクセスし、サーバ上にあるDBの最新情報を取得して、それを画面を遷移させることなく表示するサンプルを作成してみます。 対象の画面:index3 イベント:タイマー 定期実行時間:3秒 リクエスト先のコントローラ:greeting リクエスト先のアクション:select_todos_by_mysql レスポンス先のエレメントID:complete とすると、 1、Viewは(greeting/index3.html.erb) hr/ %=periodically_call_remote( update = "complete", frequency = 3, url = { action = select_todos_by_mysql}, position = "top", success = "$( complete ).innerHTML = ", loading = "", loaded = "", interactive = "", failure = "") % div id="success" style="font-size 1.0em; color green" /div div id="complete" style="font-size 1.0em; color green" /div 2、コントローラは(greeting_controller.rb) def select_todos_by_mysql if request.xml_http_request?() @stmt = @con.createStatement rs = @stmt.executeQuery("select * from todos") str = while rs.next str += rs.getString(3) str += " br / " end puts str render text = str end end になります。(ここでDB接続と切断は他のアクションでも共通処理になるはずなので外だしすることにします。※後述します。)ここで、request.xml_http_request?()は非同期でリクエストされた時のみ処理するための記述です。 機能の内容をみてみましょう。 periodically_call_remoteメソッド update = レスポンス先のエレメントID指定, frequency = 秒数, url = { action = アクション名( メソッド名)}, position = 挿入場所, success = レスポンス完了前の直前処理, 変換後のHTMLは script type="text/javascript" // ![CDATA[ new PeriodicalExecuter(function() {new Ajax.Updater( complete , /greeting/select_todos_by_mysql , {asynchronous true, evalScripts true, insertion Insertion.Top, onFailure function(request){}, onInteractive function(request){}, onLoaded function(request){}, onLoading function(request){}, onSuccess function(request){$( complete ).innerHTML = }, parameters authenticity_token= + encodeURIComponent( e4a2e3f8ab38073ed2a9d8acaced418f8042a651 )})}, 3) //]] /script div id="success" style="font-size 1.0em; color green" /div div id="complete" style="font-size 1.0em; color green" /div これだけの記述で、タイマーによる非同期処理が実現できます。 なお、DBアクセスの部分は、今回「ActiveRecordを使わないやりかた」として、通常の「DriverManagerによる接続」を実装してみました。しかし、これはJrubyOnRailsによるJDBC接続となるため、ここでのトピックとしてのテーマとずれますが、実現方法はいたって簡単です。使用するDBのJDBCドライバを使用するRubyのlibフォルダに格納し使います。 DB接続と切断をアクション共通処理としてくくりだしたいので、 DB接続(共通処理:除外するアクションも指定可能) アクション:DB操作 DB切断(共通処理:除外するアクションも指定可能) こういう処理の流れが太枠になります。この構成をRailsで行うには、事前処理と事後処理ということで、 # DB接続部分は外だしし、メソッドの前に実行させる。 before_filter db_connect, except = [ index, index2, index3, index4] # DB切断は外だしし、メソッドの前に実行させる。 after_filter db_close, except = [ index, index2, index3, index4] を定義し、 private def db_connect begin java.lang.Class.forName( com.mysql.jdbc.Driver ).newInstance @con = java.sql.DriverManager.getConnection( jdbc mysql //localhost/JRoR2MySQLTom01_development , root , ); # rescue = ex # @message = error occureed !!! # ensure # @con.close if @con end end def db_close @con.close if @con end を実装します。この処理は「除外指定されていないメソッド」である「select_todos_by_mysql」の前後に差し込まれて実行されるため、DBの接続切断処理が自動的に行われる結果となります。 リクエスト情報 a
https://w.atwiki.jp/suffix/pages/1199.html
http //craftymind.com/factory/html5video/CanvasVideo.html のサイトが凄かったので、canvasとvideo連携の方法について調べてみた。 videoの情報をcanvasに書き出す理屈は以下のような形で実現できそう。 後は、show関数を編集して、動画にエフェクトを与えられたら面白そう。 !DOCTYPE html html lang="ja" head meta charset="UTF-8" / title /title script !-- //onload時の処理を記載 window.onload =function test() { setInterval("show()",50); //フレームレートを指定 }; //videoのデータをcanvasに書き出す function show() { var canvas = document.getElementById("canvas"); var canvas_context = canvas.getContext( 2d ); var video = document.getElementById("video"); canvas.width = video.videoWidth; canvas.height = video.videoHeight; canvas_context.drawImage(video,0,0); } -- /script /head body div style="display none" !--video本体は表示しない-- video id="video" autoplay="true" source src="test.mp4" /video /div canvas id="canvas" /canvas /body /html
https://w.atwiki.jp/purkinje/pages/27.html
所持品の取得と消費による数の増減を扱う関数を作る。event、equip、magicの3つとも関数の構造はそっくりなので、eventだけを紹介する。 イベントアイテムを取得する get_event()関数では、まず手に入れたイベントアイテムが既に所有しているかどうかを調べる。Pip_event[i].id_numを手がかりにして所有しているイベントアイテム名data_event[Pip_event[i].id_num].nameを全部調べる。イベントアイテム名に対応するデータベース該当しなければ、新規アイテムとしてPip_eventの中でid番号が0で連番が最小のところに居場所を作る。該当すれば、該当id番号の数量event[i].numを増加させる。 function get_event(event_name, event_num) { var i, j; var new_event = true; // add_msg("get_eventに入った。"); // デバッグ表示用 for (i=0; i Pip_event.length; i++) { // add_msg("iの値は" + i); // デバッグ表示用 if (event_name === data_event[Pip_event[i].id_num].name new_event === true) { Pip_event[i].num += event_num; add_msg(event_name + "の数が" + event_num + "個増えた。"); new_event = false; } } if (new_event === true) { j = 0; while (data_event[j].name !== event_name) { j++; } i = 0; while (Pip_event[i].id_num !== 0) { i++; } Pip_event[i].id_num = j; Pip_event[i].num = event_num; add_msg(event_name + "を新たに入手した。"); } update_status(); } イベントアイテムを消費するlose_event()関数では、Pip_event[i].id_numを手がかりにして所有しているイベントアイテム名data_event[Pip_event[i].id_num].nameを全部調べる。見つけたら、Pip_event[i].num -= num;で個数をnum個減らす。 function lose_event(name, num) { var i,j; for (i=0; i Pip_event.length; i++) { if (data_event[Pip_event[i].id_num].name === name) { Pip_event[i].num -= num; add_msg(name + "の数が" + num + "個減った。"); } } update_status(); } イベントアイテムをすべて失うclear_event()関数では、特別扱いのE・Jを除きPip_eventを0で埋め尽くす。 冒険進行に必要なアイテムは、再度入手可能と言うことにして、特別扱いはE・Jのみにしてみた。 function clear_event() { var i; for (i=0; i Pip_event.length; i++) { //add_msg(data_event[Pip_event[i].id_num].name + "の数は" + Pip_event[i].num + "個"); if (data_event[Pip_event[i].id_num].name === "E・J") { // } else if (data_event[Pip_event[i].id_num].name === "首に刺さったボルト") { // } else if (data_event[Pip_event[i].id_num].name === "羊皮紙") { // } else if (data_event[Pip_event[i].id_num].name === "金貨") { // } else if (data_event[Pip_event[i].id_num].name === "通行許可硬貨") { // } else if (data_event[Pip_event[i].id_num].name === "サクラの花") { // } else if (data_event[Pip_event[i].id_num].name === "楕円のメダル") { // } else if (data_event[Pip_event[i].id_num].name === "警告球") { // } else if (data_event[Pip_event[i].id_num].name === "八角形の銅貨") { // } else if (data_event[Pip_event[i].id_num].name === "八角形の合金の硬貨") { // } else if (data_event[Pip_event[i].id_num].name === "エクスカリバー") { } else { Pip_event[i].id_num = 0; Pip_event[i].num = 0; } //add_msg(data_event[Pip_event[i].id_num].name + "の数は" + Pip_event[i].num + "個"); } } update_status()関数で、表示されている所持品を全部更新しよう。これもeventだけ示す。equip、magicも同様。htmlはこれ。 div 戦利品 /div div id="event0_line" INPUT TYPE="button" id="event0_button" value="click_event0_label" onClick="click_event(0)" span id="event0_exist" /span span id="event0_name" 戦利品0 /span span id="event0_num" 0 /span span id="event0_comment" コメント0 /span /div div id="event1_line" INPUT TYPE="button" id="event1_button" value="click_event1_label" onClick="click_event(1)" span id="event1_exist" /span span id="event1_name" 戦利品1 /span span id="event1_num" 1 /span span id="event1_comment" コメント1 /span /div div id="event2_line" INPUT TYPE="button" id="event2_button" value="click_event2_label" onClick="click_event(2)" span id="event2_exist" /span span id="event2_name" 戦利品2 /span span id="event2_num" 2 /span span id="event2_comment" コメント2 /span /div div id="event3_line" INPUT TYPE="button" id="event3_button" value="click_event3_label" onClick="click_event(3)" span id="event3_exist" /span span id="event3_name" 戦利品3 /span span id="event3_num" 3 /span span id="event3_comment" コメント3 /span /div div id="event4_line" INPUT TYPE="button" id="event4_button" value="click_event4_label" onClick="click_event(4)" span id="event4_exist" /span span id="event4_name" 戦利品4 /span span id="event4_num" 4 /span span id="event4_comment" コメント4 /span /div div id="event5_line" INPUT TYPE="button" id="event5_button" value="click_event5_label" onClick="click_event(5)" span id="event5_exist" /span span id="event5_name" 戦利品5 /span span id="event5_num" 5 /span span id="event5_comment" コメント5 /span /div div id="event6_line" INPUT TYPE="button" id="event6_button" value="click_event6_label" onClick="click_event(6)" span id="event6_exist" /span span id="event6_name" 戦利品6 /span span id="event6_num" 6 /span span id="event6_comment" コメント6 /span /div div id="event7_line" INPUT TYPE="button" id="event7_button" value="click_event7_label" onClick="click_event(7)" span id="event7_exist" /span span id="event7_name" 戦利品7 /span span id="event7_num" 7 /span span id="event7_comment" コメント7 /span /div div id="event8_line" INPUT TYPE="button" id="event8_button" value="click_event8_label" onClick="click_event(8)" span id="event8_exist" /span span id="event8_name" 戦利品8 /span span id="event8_num" 8 /span span id="event8_comment" コメント8 /span /div div id="event9_line" INPUT TYPE="button" id="event9_button" value="click_event9_label" onClick="click_event(9)" span id="event9_exist" /span span id="event9_name" 戦利品9 /span span id="event9_num" 9 /span span id="event9_comment" コメント9 /span /div div id="event10_line" INPUT TYPE="button" id="event10_button" value="click_event10_label" onClick="click_event(10)" span id="event10_exist" /span span id="event10_name" 戦利品10 /span span id="event10_num" 10 /span span id="event10_comment" コメント10 /span /div div id="event11_line" INPUT TYPE="button" id="event11_button" value="click_event11_label" onClick="click_event(11)" span id="event11_exist" /span span id="event11_name" 戦利品11 /span span id="event11_num" 11 /span span id="event11_comment" コメント11 /span /div div id="event12_line" INPUT TYPE="button" id="event12_button" value="click_event12_label" onClick="click_event(12)" span id="event12_exist" /span span id="event12_name" 戦利品12 /span span id="event12_num" 12 /span span id="event12_comment" コメント12 /span /div div id="event13_line" INPUT TYPE="button" id="event13_button" value="click_event13_label" onClick="click_event(13)" span id="event13_exist" /span span id="event13_name" 戦利品13 /span span id="event13_num" 13 /span span id="event13_comment" コメント13 /span /div div id="event14_line" INPUT TYPE="button" id="event14_button" value="click_event14_label" onClick="click_event(14)" span id="event14_exist" /span span id="event14_name" 戦利品14 /span span id="event14_num" 14 /span span id="event14_comment" コメント14 /span /div div id="event15_line" INPUT TYPE="button" id="event15_button" value="click_event15_label" onClick="click_event(15)" span id="event15_exist" /span span id="event15_name" 戦利品15 /span span id="event15_num" 15 /span span id="event15_comment" コメント15 /span /div div id="event16_line" INPUT TYPE="button" id="event16_button" value="click_event16_label" onClick="click_event(16)" span id="event16_exist" /span span id="event16_name" 戦利品16 /span span id="event16_num" 16 /span span id="event16_comment" コメント16 /span /div div id="event17_line" INPUT TYPE="button" id="event17_button" value="click_event17_label" onClick="click_event(17)" span id="event17_exist" /span span id="event17_name" 戦利品17 /span span id="event17_num" 17 /span span id="event17_comment" コメント17 /span /div div id="event18_line" INPUT TYPE="button" id="event18_button" value="click_event18_label" onClick="click_event(18)" span id="event18_exist" /span span id="event18_name" 戦利品18 /span span id="event18_num" 18 /span span id="event18_comment" コメント18 /span /div div id="event19_line" INPUT TYPE="button" id="event19_button" value="click_event19_label" onClick="click_event(19)" span id="event19_exist" /span span id="event19_name" 戦利品19 /span span id="event19_num" 19 /span span id="event19_comment" コメント19 /span /div div id="event20_line" INPUT TYPE="button" id="event20_button" value="click_event20_label" onClick="click_event(20)" span id="event20_exist" /span span id="event20_name" 戦利品20 /span span id="event20_num" 20 /span span id="event20_comment" コメント20 /span /div div id="event21_line" INPUT TYPE="button" id="event21_button" value="click_event21_label" onClick="click_event(21)" span id="event21_exist" /span span id="event21_name" 戦利品21 /span span id="event21_num" 21 /span span id="event21_comment" コメント21 /span /div div id="event22_line" INPUT TYPE="button" id="event22_button" value="click_event22_label" onClick="click_event(22)" span id="event22_exist" /span span id="event22_name" 戦利品22 /span span id="event22_num" 22 /span span id="event22_comment" コメント22 /span /div update_staus()関数で、値の表示を更新し、id番号id_numが0のものは表示しないようにする。 function update_status() { var i; // eventアイテムの更新 for (i=0; i Pip_event.length; i++) { document.getElementById("event" + i + "_exist").innerHTML = ""; document.getElementById("event" + i + "_name").innerHTML = data_event[ Pip_event[i].id_num ].name; document.getElementById("event" + i + "_num").innerHTML = Pip_event[i].num; document.getElementById("event" + i + "_button").value = data_event[ Pip_event[i].id_num ].label; document.getElementById("event" + i + "_comment").innerHTML = data_event[ Pip_event[i].id_num ].comment; } for (i=Pip_event.length; i data_event.length-1; i++) { document.getElementById("event" + i + "_exist").innerHTML = ""; document.getElementById("event" + i + "_name").innerHTML = "なし"; document.getElementById("event" + i + "_num").innerHTML = 0; document.getElementById("event" + i + "_button").value = "なし"; document.getElementById("event" + i + "_comment").innerHTML = ""; } // IDが0なら非表示、それ以外なら表示 for (i=0; i Pip_event.length; i++) { if (Pip_event[i].id_num === 0) { document.getElementById("event" + i +"_line").style.display = none ; //非表示 } else { document.getElementById("event" + i +"_line").style.display = block ; //表示 } } // マーリンの隠れ家から取ってきた装備品の更新 for (i=0; i Pip_equip.length; i++) { document.getElementById("equip" + i + "_exist").innerHTML = ""; document.getElementById("equip" + i + "_name").innerHTML = data_equip[ Pip_equip[i].id_num ].name; document.getElementById("equip" + i + "_num").innerHTML = Pip_equip[i].num; document.getElementById("equip" + i + "_button").value = data_equip[ Pip_equip[i].id_num ].label; document.getElementById("equip" + i + "_comment").innerHTML = data_equip[ Pip_equip[i].id_num ].comment; } for (i=Pip_equip.length; i data_equip.length-1; i++) { document.getElementById("equip" + i + "_exist").innerHTML = ""; document.getElementById("equip" + i + "_name").innerHTML = "なし"; document.getElementById("equip" + i + "_num").innerHTML = 0; document.getElementById("equip" + i + "_button").value = "なし"; document.getElementById("equip" + i + "_comment").innerHTML = ""; } // IDが0なら非表示、それ以外なら表示 for (i=0; i Pip_equip.length; i++) { if (Pip_equip[i].id_num === 0) { document.getElementById("equip" + i +"_line").style.display = none ; //非表示 } else { document.getElementById("equip" + i +"_line").style.display = block ; //表示 } } // マーリンの隠れ家から取ってきた魔法の品の更新 for (i=0; i Pip_magic.length; i++) { document.getElementById("magic" + i + "_exist").innerHTML = ""; document.getElementById("magic" + i + "_name").innerHTML = data_magic[ Pip_magic[i].id_num ].name; document.getElementById("magic" + i + "_num").innerHTML = Pip_magic[i].num; document.getElementById("magic" + i + "_button").value = data_magic[ Pip_magic[i].id_num ].label; document.getElementById("magic" + i + "_comment").innerHTML = data_magic[ Pip_magic[i].id_num ].comment; } for (i=Pip_magic.length; i data_magic.length-1; i++) { document.getElementById("magic" + i + "_exist").innerHTML = ""; document.getElementById("magic" + i + "_name").innerHTML = "なし"; document.getElementById("magic" + i + "_num").innerHTML = 0; document.getElementById("magic" + i + "_button").value = "なし"; document.getElementById("magic" + i + "_comment").innerHTML = ""; } // IDが0なら非表示、それ以外なら表示 for (i=0; i Pip_magic.length; i++) { if (Pip_magic[i].id_num === 0) { document.getElementById("magic" + i +"_line").style.display = none ; //非表示 } else { document.getElementById("magic" + i +"_line").style.display = block ; //表示 } } calc_defense(); // 防御力再計算 update_LIFE_POINT(); // 生命点再表示 } // 防御力再計算 function calc_defense() { var i; Pip.defence = 0; // 今回の冒険で防御力を上下させるアイテムは無し } 本当なら、引数で指定されたアイテム名を持っているかどうか調べ、持っていれば何番目に持っているか(Pip_event[i].id_numのi)を返す小さな関数を書くべきだったが、書いてない。
https://w.atwiki.jp/saicron/pages/56.html
あいうえお 開く ここ、Topだよ。 かきくけこ 表示 aaa bbb ccc aaa 前月 2021年12月 翌月 日 月 火 水 木 金 土 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 テクノラティでDrupalを検索した結果 #technorati 口コミ一覧 #bf ブログをDrupalで検索した結果 #blogsearch ブログタイトルをDrupalで検索した結果 #blogsearch2 DrupalをWikipediaで調べる 自転車 プログラミング言語 Windows Emacs Python JavaScript Ajax Webプログラミング jQuery ウィルコム W-ZERO3[es] @wiki Firefox Firebug Flash ParaFla! ソフトウェア Lisp テキストエディタ Vim CMS Drupal andLinux 英語 WebMapping geeklog Geeklog WordPress jQuery mobile my sites template Sencha Touch Google Maps API Map OpenLayers パン recipe 食生活 #center(){title} aaa aaaaaaaaaaaaaaaa bbbbbbbbbbbbbbb #image(http //atwiki.jp/image/header_logo.gif) #image(http //atwiki.jp/image/header_logo.gif) #ref(http //atwiki.jp/image/header_logo.gif) #ref(http //atwiki.jp/image/header_logo.gif) tags (andLinux) 2011/02/10 11 28/ edit this_page andLinux Contents インストール LAMP環境を作る page top/ edit this page インストール +情報源… 情報源 andLinuxのインストール方法! Think IT andLinuxのインストール josch (よっしゅ) のホームページ andLinux 日本語の設定 josch (よっしゅ) のホームページ andLinux 起動の高速化 josch (よっしゅ) のホームページ page top/ edit this page Windows7(32bit)へのインストールログ page top/ edit this page LAMP環境を作る 今回は、特にLinux上で動作するWebアプリケーションの開発環境として、andLinuxを利用する方法を紹介していきます。 第3回 andLinuxを使いこなす! Think IT 2011/02/10 11 28/ edit this_page tags (andLinux) 2011/03/11 10 41/ edit this_page tags (JavaScript Webプログラミング) JavaScript LiveScript Netscape Navigator 2.0 (Netscape Communications) 1995 JavaScript 1996 Internet Explorer 3.0に搭載 1997 通信に関する標準を策定する国際団体EcmaインターナショナルによってJavaScriptの中核的な仕様がECMAScriptとして標準化 page top/ edit this page 目次 未分類 プログラミングリファレンス JavaScriptWeb Tools Tutorials実行 実行キュー 関数型プログラミング言語として Scope Closure tmp ひとめぐり サンプル 実装 DOM page top/ edit this page 未分類 Standard ECMA-262 ECMAScript Language Specification 5th edition (December 2009)ECMAScript Language Specification (3rd edition, December 1999) の邦訳 ECMAScript ウィキペディア プログラミング Firefoxの「ツール」→「エラーコンソール」で実行できる。 FirefoxのFirebugの「コンソール」で実行できる。 Aptanaで実行できる。 JavaScriptの()無し関数はやっぱりポインタ(f() → f)。 リファレンス MDN JavaScript Standard ECMA-262 ECMAScript Language Specification 5th edition (December 2009) MDN とほほのJavaScriptリファレンス JavaScriptリファレンス - JavaScriptist 一撃必殺JavaScript日本語リファレンス page top/ edit this page JavaScript EfficientJavaScript - Dev.Opera - 効率的な JavaScript JavaScriptの巧い書き方 JavaScript を学ぶ際に一番重要なのに、誤解されがちな setTimeout 系の概念 JavaScriptの実行キューのお勉強 javascriptは本当にシングルスレッドで実行されているけれど起こるsetTimeout/prompt現象 page top/ edit this page # Web Tools JS Bin JavaScriptオンラインエディタ JSLint The JavaScript Code Quality Tool page top/ edit this page Tutorials jQueryの基礎 実行 DOMの構築が済んだタイミングで実行する(画像の読み込みは終了していない)。 jQuery(document).ready(function(){ // jQuery or JavaScript のコード }); または、 $(document).ready(function(){ // jQuery or JavaScript のコード }); または、 $(function(){ // jQuery or JavaScript のコード }); jQuery関数($関数)は何度書いてもよい。 onLoadと同じタイミング(画像の読み込みを含めて全て終了後)に実行する場合。 $(window).load(function() { // jQuery or JavaScript のコード }); 実行キュー JavaScript を学ぶ際に一番重要なのに、誤解されがちな setTimeout 系の概念 IT戦記 JavaScriptのタイマー処理 setTimeoutとその活用 (function(){})() と function(){}() page top/ edit this page 関数型プログラミング言語として JavaScript の function は lambda かもしれない。 Functional Javascript エレガントな JavaScript を作成するための関数型プログラミングの使用 JavaScriptの巧い書き方 (名前空間) 24 wyas (名前空間) そろそろきっちりJavaScript マイコミジャーナル (関数リテラル/オブジェクト/prototypeチェーン/prototype.jsを読む) page top/ edit this page Scope JavaScript の変数とスコープ JavaScript のスコープに変数を動的に追加する JavaScriptクロージャを完全理解!スコープチェインを知る(前編) JavaScript でブロックスコープを実現する JavaScriptでthisスコープをコントロールする JavaScript のブロックスコープと名前空間 page top/ edit this page Closure JavaScript Closures 101- they're not magic 猿でもわかるクロージャ超入門 まとめ page top/ edit this page tmp prototype.jsを読む(1) Firebugクックブック #1 Firefox 3とFirebugで始めるJavaScript開発 Firebug page top/ edit this page ひとめぐり プログラマのためのJavaScript 初心者でも使えてプログラマでも困惑するJavaScript page top/ edit this page サンプル 新JavaScript例文辞典 JavaScriptテクニックブック page top/ edit this page 実装 JavaScriptは何で動くのか? 各Webブラウザ +SpiderMonkey… What is SpiderMonkey? SpiderMonkey とは何か? SpiderMonkey は Mozilla の C による JavaScript 実装につけられたコードネームである。 +jslib… jslibs (SpiderMonkeyの拡張?) standalone JavaScript development runtime environment with general purpose native libraries +Rhino… Rhino JavaScript for Java Rhino はすべてが Java で記述された JavaScript のオープンソースな実装です。それは一般的には、Java アプリケーション環境へ組み込まれて、エンドユーザーによるスクリプトの記述が可能になります。J2SE 6 ではデフォルトの Java スクリプティングエンジンとして組み込まれています。 もっともお手軽な対話的JavaScript処理系 page top/ edit this page DOM The DOM and JavaScript - MDN JavaScript DOM リファレンス 文書オブジェクトモデル(DOM)第1水準 仕様書 Version 1.0. The DOM and JavaScript DOMから始めるJavaScriptモダン・スクリプティング JavaScriptでDOMを使う――オブジェクト指向入門の入門 page top/ edit this page { 2011/03/11 10 41/ edit this_page tags (JavaScript Webプログラミング)