2008/02/29

global.asaがApplication.cfm、onRequestEnd.cfmに相当

仕事でAPS(.netではありません)のプログラムを行うことがあるのですが、ソースを探しても、どーしてもみつからない定数があって、さらによく探してみると、global.asaというファイルにありました。

ASPはファイルの拡張子がaspなのに、.asaってなんだよと思い、ぐぐってみると、global.asaは、application.cfmとonRequestEnd.cfmに相当するファイルのようです。

ASP@Workshopによると、

'アプリケーション開始時
Sub Application_OnStart

End Sub

'アプリケーション終了時
Sub Application_OnEnd

End Sub


via:global.asaとは

つまり、Application.cfmのように最初に読み込まれるようにするには、Application_OnStartを定義し、onRequestEnd.cfmのように最後に読み込まれるようにするには、Application_OnEndを定義するればいいんですね。

Application.cfmのような機能を備えているのは、直感的にわかったのですが、最後に読み込まれる機能も備えているとは思わなかった。

2008/02/28

でた!!oracle、エラーORA-00600

昨日、oracleの伝説的なエラー、ORA-00600が発生!!

このエラーがでた場合、オラクルに問い合わせ直行行きらしく、ものすごい焦りました。

原因ですが、from句がdblink先のテーブルを参照しているシノニムのカーソルを含んだ、PackageBodyのコンパイルをかけたら、下のようなORA-00600が発生しました。

PL/SQL: ORA-00600: 内部エラー・コード、引数: [12840],[],[],[],[],[],[],[]

まじ、どうしようかとこのブログのタイトル通り、ものすごいテンパってしまったのですが、シノニムの部分をviewに変更して解決することができました。

ここで、メモも兼ねてまとめてみたいと思います。

1.DBLinkを定義
CREATE PUBLIC DATABASE LINK ORACLE_DB01.WORLD
  CONNECT TO ORA_USERNAME
  IDENTIFIED BY ORA_PASSWORD
  USING 'ORACLE_SID01'
/

2.DBLINK先のテーブルを参照するSYNONYMを作成
CREATE SYNONYM hoge_synonym
    FOR hoge@ORACLE_DB01.WORLD
/

3.上で作成したSYNONYMをFROM句としたカーソルを含むPackageBodyを定義
CREATE OR REPLACE PACKAGE BODY hogePack
IS
・・・・
  CURSOR crs
  SELECT clm
    FROM hoge_synonym
   WHERE ・・・・・
    ;

BEGIN
・・・
EXCEPTION
・・・
END;
/

ここで、コンパイルをかけるとバグが発生します。
そこで、参照先をSYNONYMからVIEWに変更して再コンパイル

4.viewの作成
CREATE OR REPLACE VIEW hoge_view
    AS
SELECT *
    FROM hoge@ORACLE_DB01.WORLD
/

5.カーソルの変更
CREATE OR REPLACE PACKAGE BODY hogePack
IS
・・・
  CURSOR crs
    SELECT clm
      FROM hoge_view
    WHERE ・・・・・
    ;

BEGIN
・・・
EXCEPTION
・・・
END;
/

うーん、実に難しい。。。

orz

2008/02/27

また、XMLHTTPRequestにバグが。。。

ホント最悪。。。orz

IEで、ファイルをオープンする時に、ファンクションのパラメータ問わず、trueで通信しちゃっていました。

問題箇所

httpObj.open(httpMethod,url,true);



httpObj.open(httpMethod,url,asynch);

に修正しました。

すでに、opensourceにバグ修正後の1.0.2をアップロードしました。

うぎゃ~~~~

2008/02/26

oracleのuserを削除する

前回、試しに作ったoracleのユーザーを削除したくて、systemでログインした後、対象となるユーザーをドロップしても、削除できなかったので、sql文で削除することができないかとぐぐってみたところ、できることが判明!!

以下が、そのslq文です。

構文 DROP USER ユーザ名 [ CASCADE ];
オプション CASCADE
削除するユーザがオブジェクトを所有している場合、そのユーザを削除できないが、CASCADEを付けることで削除できる。

via:ユーザーの削除
実行後、無事に、userを削除できたので、ホットしました^-^v

2008/02/25

XMLHttpRequestのドキュメントが完成!!

前回、リリースしたXMLHttpRequestの設計書を一気に仕上げたいと思い、本日、一日かけて仕上げました。

こちらにあります。

うーん、徐々に慣れてきたような。

でも、設計書として、まだ完璧とは、いえないので、これからももっと、もっと、わかりやすい設計書をかけるように心がけていきたいです。

2008/02/24

XMLHttpRequestにバグが。。。

うわー、またやっちゃった( ̄-  ̄ )
昨日、アップロードしたXMLHTTPRequest.1.0.cfmですが、firefoxで、XMLHttpRequestオブジェクトを作成した後、送信方法が「GET」のままでした。。。

orz

修正箇所は、

httpObj = new XMLHttpRequest();
httpObj.open("GET",url,asynch);

というところを、

httpObj = new XMLHttpRequest();
httpObj.open(httpMethod,url,asynch);

に修正をかけました。

で、coldfusion-addonの方に1.0.1として再アップロードしました。

また、ボンミスをおかしてしまった。。。

2008/02/23

XMLHttpRequest_1.0をリリース

coldfusion 8から、coldfusion.ajax.submitFormという新しい関数が追加されて、同じような機能をもった関数を7でも実装できないかなーって思い、なんとなく作ってみました。

<CFFUNCTION name="XMLHTTPRequest">
<CFOUTPUT>
<SCRIPT type="text/javascript">
function js_XMLHttpRequest(url,func,ahttpMethod,aasynch) {
  var httpObj = "";
  var ret = "";
  var httpMethod = "GET";
  var asynch = true;

  /* quoted Prototype JavaScript framework, version 1.5.1.1 */
  var Prototype = {
   Browser: {
   IE: !!(window.attachEvent && !window.opera),
   Opera: !!window.opera,
   WebKit: navigator.userAgent.indexOf('AppleWebKit/') > -1,
   Gecko: navigator.userAgent.indexOf('Gecko') > -1 && navigator.userAgent.indexOf('KHTML') == -1
   }
  };

  if(ahttpMethod != null){
    if(ahttpMethod.toUpperCase() == "POST"){
      httpMethod = "POST";
    }
  }

  if(aasynch != null){
    if(aasynch == false){
      asynch = false;
    }
  }
  if(Prototype.Browser.IE){
    httpObj = new ActiveXObject("Msxml2.XMLHTTP");
    httpObj.open(httpMethod,url,true);
    httpObj.onreadystatechange = function (){
     if(httpObj.readyState == 4 && httpObj.status == 200){
     ret = httpObj.responseText;
     func(ret);
     }
    };
  }else{
    httpObj = new XMLHttpRequest();
    httpObj.open("GET",url,asynch);
    httpObj.onload = function(){
     ret = httpObj.responseText;
     func(ret);
    };
  }
  httpObj.send(null);
}

</SCRIPT>
</CFOUTPUT>
<CFSETTING SHOWDEBUGOUTPUT="no">
</CFFUNCTION>

とまぁー、このような形で作成しました。

この関数をcfsetで関数を作り出し、後は、javascriptで関数を呼び出せば、オッケー♪
ちなみに、javascriptで呼び出すときは、こんな感じ。

<SCRIPT type="text/javascript">
  var hoge = function(text){
    ...
  }
</SCRIPT>
<A href="javascript:js_XMLHttpRequest('test.cfm',hoge)">Ajax呼び出し</A>

js_XMLHttpRequestに関して、後二つ引数を追加することができて、一つ目は、送信方法。POSTかGETを選択することができて、デフォルトでは、GETになっています。

二つ目は、非同期か同期かを選択する変数で、デフォルトでは、非同期になっています。

うーん、8と比べて忠実に再現できなかったのは、最後、コールバック関数を呼び出すときに、ローカルでは無名関数を定義しないといけないところ。

8では、名前の入った関数を定義すれば、そこに値を返してくれたのですが。

まぁー、そこまででかい差ではないのですが。。。

この関数を使うことで、わざわざ、xmlHttpリクエストを投げるオブジェクトを作成しなくても、urlと関数名さえ指定すれば自動的に非同期でデータを取得できるところ。

せっかく作ったので、coldfusion-addonにもXMLHttpRequest_1.0.cfmとして、アップロードしました。

次は、設計書を作っていきたいと思います。

2008/02/22

google gadgetをディレクトリから削除する方法

去年、googleのgadgetコンテストがあって、その時に、ヘテムルの期間限定coldfusion8ベータホスティングを利用してメモメールというgadgetを作成したのですが、いつの間にか、期間が終わってしまって、使えなくなってしまい、どうすれば、登録されたディレクトリから削除することができるのかなーと思って、google gadet api japanグループに投げたところ、返信が来ました。

こんにちは、○○です。
私もはっきりしたことはわかりませんが、こちらのスレッドを見ると・・・
groupsのURL

手動で消してもらうしかないみたいですね。
まずはガジェットの XML をサーバーから削除してみて、数週間たってもディレクトリから消えないようなら、上記のスレッドに削除要求を投げてみてはいかがでしょう。

via:Google-Gadgets-API-Japan

と回答を頂いたので、さっそくここに投稿しました。
そうすると、なんとgoogleのdeveloperさんから返信がきて、削除してくださいました。

今度から、gadgetをディレクトリから削除する場合は、ここから申請したいと思います。

2008/02/21

goo辞書ガジェットのユーザー数が95000人突破

この前、先輩社員から聞いて、びっくりしたのですが、去年の7月ぐらいに作ったgoo辞書ガジェットのユーザー数が、なんと、なんと、95000人突破しました~♪

goo_dictionary_over95000

お使いいただいているユーザーさん、本当に、本当にありがとうございます★”
こうしてたくさんの方にお使い頂けて本当にうれしいです。

これからも、いいアプリを作っていけたらと思いますので、どうか一つよろしくお願いいたします。

詳しいgoo辞書ガジェットの説明、追加はこちらから行うことができます。

Add to Google

2008/02/20

RelatedwithDate.cfmのドキュメント完成!!

やっと、RelatedwithDate.cfmのドキュメントが完成したぁー^-^v

完璧とは言えないけど、とりあえず完成はしたので、ホッとしました。

ドキュメントはこちらにあります。

今回までで、2つのファイルに対するドキュメントを書いたのですが、やっぱり英語で書くことにものすごく苦痛を感じてしまう。

もっと楽しく作業を進めていくにはどうすればいいのだろうか??

そして、もっと、きちんとした英語で書くにはどうすればいいのだろうか??

それに、設計書としてきちんと構成が成り立っているのか??

色々、課題がありますが、量をこなしていかないとクリアーできないのかなーと疑問に思ってしまう今日この頃。。。

2008/02/19

設計書のテンプレートを考えてみる

前回に引き続き、リファレンスを書いているのですが、仕事でオリジナルの設計書を書いたことがないので、どうやって書いていいのか悩んでいます。

そこで、何か参考にしながら書けばいいのではないか、と思い、いつもお世話になっているgoogle codeのAPI仕様書を参考にしながら、テンプレートを作ってみたいと思います。

まずはじめに、APIの全体像を紹介するためのHomeがあって、次にDocumentに入ります。Documentでは、いくつかの構成にわけてさらに詳しい説明を展開しています。

で、いくつかのサンプルソースが紹介されていて、その後は、関数やメソッドのリファレンスが展開されていました。

以上から、下のような構成になっている感じです。

・Home
  APIの概要を説明する(大まかに説明する)
・Document
  いくつかのテーマに分かれて開設がされている
・Example
  サンプルソースの紹介
・Reference
  関数、メソッド、オブジェクトについての詳細


完全に同じではないと思いますが、だいたいこんな感じなのではと。

で、coldfusion-addonに関しては、関数系の説明を多くしたいので、リファレンスの部分に下のテーブルを追加するような形を考えました。

argumenttyperequireddefaultexplain
     

と引数をより詳しく書いたテーブルにすることでわかりやすくなるのではないかと思いました。

少しでもオリジナリ感を出したいと思ったので、google codeのようなリファレンスの返り値と詳細説明に加え、引数、型、デフォルト値、requiered区の列を追加しました。

これで読んでいる方が少しでも直感的に理解してくれるとうれしいなと思いました。

2008/02/18

wordで、半角スペースや全角スペースを表示する編集記号を使う

前回coldfusion-addonにリリースしたRelatedwithDateのリファレンスをwordで書いてて、スペースやtabなどの編集記号が表示されていないことに気づき、どうやって表示させるだろうーと悩んだので、改めて調べてみることにしました。

ぐぐってみると、インストラクターのネタ張にやり方が書いてあったので、実際にチャレンジしました。

▼操作方法 : すべての編集記号が非表示になるよう設定を変更する
メニュー[ツール]-[オプション]をクリック
 ↓
[オプション]ダイアログ-[表示]タブをクリック
 ↓
[編集記号の表示]欄-[タブ][段落記号][任意指定のハイフン][任意指定の改行][スペース][隠し文字][すべて]チェックを、全部Offにする
 ↓
[オプション]ダイアログ-[OK]ボタンをクリック

via:編集記号の表示設定

2つ目の↓の後に書かれている「off」の部分をonにして手順通り進めていくと、記号が表示されました。

編集記号表示前
edit_mark_No01

編集記号表示後
edit_mark_No02

確かに、半角スペースには「・」、全角スペースには「□」、tabには、「→」が表示されました。

ただ、注意する点があって、非表示の時に作った半角スペースや全角スペースは、反映されなくて、表示をOKにした以降にできた記号に反映されるんですね。

うーーーん、非表示から表示に変更したんだから、OKボタンを押下後にできた編集記号のみに適用せずにそれ以前の編集記号にも適用してほしいなーとちょっとグチってみました。

2008/02/17

oracleで、全スキーマ名を取得する

去年、object browserを作っている途中で、投げ出してしまったので、久々に昔のコードを見てみると、忘れてしまっていたことがあったので、書き留めたいと思います。

今回は、あるDBに接続している全スキーマ名を取得するSQL文です。

SELECT DISTINCT USERNAME
 FROM ALL_USERS
;

これで、全スキーマを取得することができます^-^V

2008/02/16

oracleのクライアントが動きました

ちょっと前に、Oracle10gが動かない。。。 orzにて、oracleが動かないことを書きました。

あれから、再インストールを行い、クライアントも入れなおしたのですが、それでも、SQL文を発行できませんでした。
not_exe_sql
結局、何が原因なんだろうーと思っていたら、なんと、お恥ずかしながら、接続情報を入れ忘れていました。

まずは、DBに接続します。(下の図参照)
oracle10g_conn_no01

もしくは、下の入力でも接続できます。
oracle10g_conn_no02

仕事場とは違って、ローカルでインストールを行ったので、接続情報を入れなくても、DBに接続できるだろうーと思っていたのですが、できなかったんですね。

わざわざ、再インストールする必要がなかったのに。。。


orz

2008/02/15

oracleで、オブジェクトのテキストを表示する

Oracleで、あるスキーマが持っているストアドやプロシージャー、パッケージ内のテキストを検索したい場合、以下のSQL文を使って検索する。


SELECT TYPE
         , NAME
         , LINE
         , TEXT
   FROM USER_SOURCE
;

さらに各オブジェクトのソース内に、ある一定のキーワードを含んでいるものを検索したい場合

SELECT TYPE
         , NAME
         , LINE
         , TEXT
   FROM USER_SOURCE
 WHERE TEXT LIKE '%検索したい文字%'
;

で検索することができます。

2008/02/14

基本選択法(選択ソート、selection sort)

前に、基本交換法(隣接交換法・BubbleSort)についてで、BubbleSortのアルゴリズムを書きました。

このアルゴリズムは、基本情報技術者のテキストに乗っていて、読んだだけだとわからないと思い、実際ソースを組んだところから始まりました。



で、他にもまだ、ソートのアルゴリズムがあって、今回は、基本選択法(selection sort)を書きたいと思います。

下のような乱数が与えられたとき、降順か昇順で並び変えを行います。



昇順降順

では、実際のアルゴリズムを見ていきたいと思います。

昇順の場合


js_selectArray = new Array();
var k;
for(var i=0;i<=js_selectArray.length-2;i++){
  k = i;
  for(var j=i+1; j<=js_selectArray.length-1;j++){
    if(js_selectArray[k] > js_selectArray[j]){
      k = j;
    }
  }
  js_selectdummy = js_selectArray[i];
  js_selectArray[i] = js_selectArray[k];
  js_selectArray[k] = js_selectdummy;
  js_selectdummy = "";
}


降順の場合


js_selectArray = new Array();
var k;
for(var i=0;i<=js_selectArray.length-2;i++){
  k = i;
  for(var j=i+1; j>=js_selectArray.length-1;j++){
    if(js_selectArray[k] > js_selectArray[j]){
      k = j;
    }
  }
  js_selectdummy = js_selectArray[i];
  js_selectArray[i] = js_selectArray[k];
  js_selectArray[k] = js_selectdummy;
  js_selectdummy = "";
}

というアルゴリズムで展開されています。

前回のBubble Sortとは違って、基本選択法は、

対象集合から最も小さい(または最も大きい)要素を順次取り出して、端に置いていくことで整列を行う方法

via:栢木先生の基本情報技術者教室:基本選択法

と書かれていました。

う~~~ん、頭の中で整理しながらソースを組まないとわけがわからなくなってきます。

2008/02/13

ColdFusion AdministratorにoracleのDBを登録する

せっかく、DBの設定ができたので、CFでも使いたいと思い、Administratorに登録しちゃいました。
ということで、設定の方法を書いていきたいと思います。

1.administratorをオープンし、データとサービスデータソースを選択
cf_dbsetup_no01

2.データソース名を任意に設定し、ドライバoracleを選択
cf_dbsetup_no02

3.追加ボタンを押下後、SID名サーバー名ユーザー名パスワードをそれぞれ設定
Photobucket

*tnsnames.oraを見て設定し、自分のパソコンで使うときは、サーバー名をlocalhostに設定

2008/02/12

[oracle]10gExpressEditionにスキーマを作成する

昨日、oracle10gの再インストールが完了したので、今日は、スキーマを作成しようと、前に買ったoracle 10g database bronzeの本を読んでいたら、全然、Express Editionと画面がちげぇ~~~。。。


この本だと作成することができないのか??

どうしよぉー、どうしようぉー、と悩んでいたら、インストール時についていたスタート・ガイドというものがあって、開いてみると、英語で書かれているし。。。

orz

仕方なく、訳しながら、スキーマーを作ることにしました。

1.systemでログインする(インストール時に設定したパスワードを使う)
oracle10g_009

2.HomeAdministrationを選択
oracle10g_010

3.Database Usersを選択する
oracle10g_011

4.hrを選択する
oracle10g_012

5.hrスキーマに対するパスワードを設定する(AccountStatusは、Unlockedで)
oracle10g_013

以上で、hrユーザーの設定が完了しました。

今回は、あらかじめ、oracle側が用意してくれたスキーマーの設定を行いましたが、今度は、スキーマー自体オリジナルを作ってみたいと思いました。

2008/02/11

oracle10gExpressEditionの再インストール

昨日の記事で、oracleが動かなくなってしまったことを書いたのですが、ぐぐってみてもそらしい答えを見つけられなかったので、再インストールしました。

メモ代わりにインストール方法を書きたいと思います。

1.exeファイルをダブルクリックする
oracle10g_001

2.画面に従って「次へ」を押す
oracle10g_002


「同意する」にチェックを入れて、「次へ」を押す
oracle10g_003

3.インストールするフォルダを選択する
oracle10g_004

4.「system」スキーマでログインするときのパスワードを設定する
oracle10g_005

5.インストールを開始する
oracle10g_006


oracle10g_007

6.インストール完了!!
oracle10g_008

2008/02/10

Oracle10gが動かない。。。 orz

去年、自宅のパソコンで開発を行いたくて、Oracle 10g Experss Editionをインストールしたのですが、動かない。。。

なぜじゃー。。。

orz

2008/02/09

RelatedwithDate ver 1.0 リリース

toDateファンクションが完成したので、DateAddtoString内に組み込んでみます。
下の部分を変更します。


<CFSET cf_Ret_Date = CreateDate(cf_YYYY,cf_MM,cf_DD)>

この部分を、次のように変更しました。

<CFSET cf_Ret_Date = toDate(aStr)>

これで、日付チェックを経て、日付に日数を追加することができます。

以上から、変更したDateAddtoStringはこのようになりました。

<CFFUNCTION name="DateAddtoString">
  <CFARGUMENT name="aStr" type="String" required="yes">
  <CFARGUMENT name="aNum" type="numeric" required="no" default=1>
  <CFARGUMENT name="aType" type="String" required="no" default="d">

  <CFSCRIPT>
  var cf_Ret_Date = "";
  </CFSCRIPT>

  <CFSET cf_Ret_Date = toDate(aStr)>

  <!--- when function returned false --->
  <CFIF cf_Ret_Date eq false>
    <CFRETURN false>
  </CFIF>

  <!--- forms date add --->
  <CFSET cf_Ret_Date = DateAdd(aType,aNum,cf_Ret_Date)>
  <CFRETURN cf_Ret_Date>
</CFFUNCTION>

そして、coldfusion-addに今回の日付に関するファンクションをRelatedwithDate.cfmとして、アップロードしました。

よーし、次は、ドキュメントに挑戦だぁー♪

2008/02/08

toDateファンクション作成!!

前回、文字列のまま日付を追加してくれるDateAddtoStringより、文字列のまま、日付を追加することができるファンクションを紹介しました。

で、作りながら、少し気になっていたことがあって、第一引数の文字列から日付を作成する際に、入力チェックをかけたいなーと思いました。

しかし、このファンクション内で記述しまうと、ファンクション自体が長くなってしまい、かつ、日付を作成するという意味では、別機能だと思ったので、あえて日付を作成するファンクションを作成してみました。

具体的には、下のコードに、入力チェックを追加した日付作成ファンクションを作成しました。

<CFSET cf_Ret_Date = CreateDate(cf_YYYY,cf_MM,cf_DD)>

そして、できあがったファンクションは、このような形になりました。

<CFFUNCTION name="toDate">
<CFARGUMENT name="aStr" type="String" required="yes">
<CFSCRIPT>
var cf_YYYY = "";
var cf_MM = "";
var cf_DD = "";
</CFSCRIPT>

<!--- Check is Numeric ? --->
<CFIF IsNumeric(aStr) eq False>
  <CFRETURN false>
</CFIF>

<!--- Check is grater than 0 --->
<CFIF aStr lte 0>
  <CFRETURN false>
</CFIF>

<!--- Check existed dot ? --->
<CFIF Find(".",aStr) neq 0>
  <CFRETURN false>
</CFIF>

<!--- Check is 8 length --->
<CFIF Len(aStr) neq 8>
  <CFRETURN false>
</CFIF>

<CFSET cf_YYYY = Left(aStr,4)>
<CFSET cf_MM = Mid(aStr,5,2)>
<CFSET cf_DD = Right(aStr,2)>

<!--- Check is toDate ? --->
<CFIF IsDate(cf_YYYY&"."&cf_MM&"."&cf_DD) eq False>
  <CFRETURN false>
</CFIF>

<CFRETURN CreateDate(cf_YYYY,cf_MM,cf_DD)>

</CFFUNCTION>

まず、引数が文字列なので、入力された引数が数字に変換できるかどうかのチェック。

<!--- Check is Numeric ? --->
<CFIF IsNumeric(aStr) eq False>
  <CFRETURN false>
</CFIF>

次に、引数は、0よりも大きいか?

<!--- Check is grater than 0 --->
<CFIF aStr lte 0>
  <CFRETURN false>
</CFIF>

さらに小数点の入った文字列型の数字を入力があるかもしれないので、「.」チェック。
<!--- Check existed dot ? --->
<CFIF Find(".",aStr) neq 0>
  <CFRETURN false>
</CFIF>

そして、ジャスト8桁で入力にしてほしいので、8桁以外はエラーになるような処理も追加しました。

<!--- Check is 8 length --->
<CFIF Len(aStr) neq 8>
  <CFRETURN false>
</CFIF>

ラストに、年、月、日、のそれぞれの間に「.」を入れて、IsDateで引数を評価することで、日付型に変更できるかどうかジャッジをしています。

<CFSET cf_YYYY = Left(aStr,4)>
<CFSET cf_MM = Mid(aStr,5,2)>
<CFSET cf_DD = Right(aStr,2)>

<!--- Check is toDate ? --->
<CFIF IsDate(cf_YYYY&"."&cf_MM&"."&cf_DD) eq False>
  <CFRETURN false>
</CFIF>

返り値として、CreateDateされた日付型の引数を返します。

<CFRETURN CreateDate(cf_YYYY,cf_MM,cf_DD)>

そして、今回、苦戦したのは、IsDateの評価!!
単純に下の式では、Falseを返してしまうところ。。

<CFSET hoge = IsDate("20080212")>
<--- 下の式では、falseを返す --->
<CFOUTPUT>#hoge#</CFOUTPUT>

どーしてなんだろうーと思い、7のリファレンスを見てもわからなかったので、「.」を間に挟むことで、問題を解消しました。

<CFSET hoge = IsDate("2008.02.12")>
<--- 下の式では、trueを返す --->
<CFOUTPUT>#hoge#</CFOUTPUT>

これでパーツが完成したので、DateAddtoStringファンクションに組み込んでみたいと思います。

今回の記事では長くなってしまったので、次回の記事にて。。。^-^v

2008/02/07

coldfusion-addonのwikiにErrorRepotを追加

昨日の記事で、最後に「googlecodeのcoldfusion-addonに履歴記録を残そうかな~~」と書いて、実際に書こうかどうか、ものすごく悩みましたが、残さないとなんだか、気持ち悪く感じてきたので、coldFusion add-onのwikiにErrorRepotというページを作りました。

このページでは 主に、toJSONに関するバグ、不具合の報告をしたいと思います。また、修正した後の報告も同じページで書いていきたいと思います。文法があっているか不安ですが、履歴を残すことができたので、なんだかスッキリした気分です。

toJSON.cfmのバグ発見と修正

バグみつかっちゃったよぉー。

今日、toJSON_1.0.cfmで遊んでいたら、引数に入れる配列の要素に文字列が入っていた場合、JavaScriptエラーが走っちゃった><。。。

<CFSET cf_Array[1] = "apple">
<CFSET cf_Array[2] = "lemon">
<CFSET cf_Array[3] = "orange">

と入れると、「オブジェクトがありません」というようなJavaScriptエラーが発生しちゃいました。

なんてことだー。。。きちんと動作確認を行ったのに。。。

初歩の初歩的なところでバグってしまうなんて。。。

しかも、toJSON_1.25.2.cfmでは、配列の要素がnullだった場合、本当なら、JSONの中のデータをnullって返したいんだけど、"null"って文字列で返しちゃっているよ。。

<CFSET cf_Array[1] = "apple">
<CFSET cf_Array[2] = "">
<CFSET cf_Array[3] = "lemon">

結果が、
var data = {
   "1":"apple"
  , "2":"null"
  , "3":"lemon"
}
となってしまうのです。(T_T)

全然だめぇだぁ~

ということでさっそく修正を行い、それぞれ、toJSON_1.0.1.cfm、toJSON_1.25.3.cfmとして、再アップロードを行いました。

すみません。。。

もっとしっかりしないとな~。。。

orz

googlecodeのcoldfusion-addonに履歴記録を残そうかな~~

2008/02/06

toJSON.cfmのドキュメント完成!!

わーい、わーい、やっとtoJSON.cfmのドキュメントが完成しました。
coldfusion-addonのwikiのHomeというページに作りました。

とりあえず、できたので、ほっとしました~♪

2008/02/05

文字列のまま日付を追加してくれるDateAddtoString

以前、先輩社員と一緒に帰るときに、CFのDateAdd関数の引数(3番目)が、文字列型ではなく日付型で、開発時に、日付を文字列として処理してしまっているので、このような仕様だと、一回、一回、文字列型から日付型に変換しなくちゃーいけないからメンドイということをおっしゃっていて、確かにそうだよなー、と思い、今回、文字列型のまま日付の追加ができないか、ファンクションを自作してみました。

<CFFUNCTION name="DateAddtoString">
<CFARGUMENT name="aStr" type="String" required="yes">
<CFARGUMENT name="aNum" type="numeric" required="no" default=1>
<CFARGUMENT name="aType" type="String" required="no" default="d">

<CFSCRIPT>
var cf_YYYY = Left(aStr,4);
var cf_MM = Mid(aStr,5,2);
var cf_DD = Right(aStr,2);
var cf_Ret_Date = "";
</CFSCRIPT>

<CFSET cf_Ret_Date = CreateDate(cf_YYYY,cf_MM,cf_DD)>
<CFSET cf_Ret_Date = DateAdd(aType,aNum,cf_Ret_Date)>
<CFRETURN cf_Ret_Date>
</CFFUNCTION>

と実装しました。

このファンクションは、第一引数に、8桁の日付をとり、 第二引数に、追加したい日付の数、そして最後の引数は、 追加する日付の単位です。また単位については、 DateAdd関数と同じ単位で実装しました。

なんといっても、DateAddと違って、日付は文字列で オッケーなので、
<CFSET hoge = DateAddtoString("20080228",2,"m")>
と書いて、<CFOUTPUT>で出力させた場合、
{ts '2008-04-28 00:00:00'}
と返し、また、デフォルトで、日付に1日追加するように実装しているので、
<CFSET hoge = DateAddtoString("20080228")>と
書くことにより、
{ts '2008-02-29 00:00:00'}
と返してくれます。

まだ、若干、引数の入力チェックに関して弱い部分があるので、もうちょい調整をしたら、googlecodeのcoldfusion-add projectにアップロードしようかと考えています。

2008/02/04

IE上で、ajaxを使ってtextファイルをインクルードする

いつも、google gadgetを作っている時、何も気にせず、googleが用意してくれている共通ファンクションを使って、xmlファイルからデータを取得したり、JSONのデータをjavascriptで使ったりしているんですけど、いったい、どうやって取得しているのか気になったので、調べてみました。

今回、例として、「test」、「hoge」と書いてあるdemo.txtのデータを取りにいきたいと思います。

まずは、XMLHttpRequestオブジェクトを作成します

var httpObj = "";//変数宣言
//ActiveXObjectのオブジェクトを作成する
httpObj = new ActiveXObject("Msxml2.XMLHTTP");

次は、データの送信方法、ファイルの接続先、同期方法を書いたopenメソッドを使います。

//非同期でテキストをデータをget方式で取りにいく
httpObj.open("GET","txtファイルがあるURL",true);

そして、状態が変化したときに、ファンクションを呼び出します。

//状態変化が起きたときにファンクションを起動する
httpObj.onreadystatechange = comploaded();
function comploaded(){
 if(httpObj.readyState == 4 && httpObj.status == 200){
  //コールバック関数
  callback(httpObj);
 }
}

readyState == 4つまりデータを受信完了したとき、かつ、status == 200、リクエストが完了したときにコールバック関数を呼び出すようにしたのですが、エラーになりました。

JavaScriptが「型が一致していません」と怒りました。

なぜ、バグルのじゃぁー??

参考に、AllAboutのAjaxはじめの一歩 XMLHttpRequestを見ながら打っているんですけど、バグっている。。。

なぜじゃー??

今度は、こう変えてみました。

//状態変化が起きたときにファンクションを起動する
httpObj.onreadystatechange = comploaded;
function comploaded(){
 if(httpObj.readyState == 4 && httpObj.status == 200){
  //コールバック関数
  callback(httpObj);
 }
}

と書いたら、動いたー!!!

ファンクションには、引数が必要でなくても「()」が必要なんじゃーないのか??
おかしい、なぜじゃー??

とりあえず、ずーっと考えていると泥沼にはまりそうなので、気持ち悪いけど、いったん納得して、ファンクションの部分を無名関数に書き換えました。

//状態変化が起きたときにファンクションを起動する
httpObj.onreadystatechange = function (){
 if(httpObj.readyState == 4 && httpObj.status == 200){
  //コールバック関数
  callback(httpObj);
 }
};
httpObj.send(null);


そして、callback関数の部分を続けて書いてみました。

function callback(obj){
 var ret = "";
 //テキストデータを取得する
 ret = obj.responseText;
}

これでデータ取得が完了します。
あとは、ファイルの種類に応じてデータを加工すればhtmlに反映させることができます。

うれしくて、このブログにもソース書いて、動作確認を行ったところ、動かなかった。。。
ローカルだと動くのに。。。
Bloggerの使用上無理??ってこと

うまく、動作しなかったので、ローカルで書いたソースをあげます。
<SCRIPT type="text/javascript">
 function js_ajaxcatch(){
  if(!!(window.attachEvent && !window.opera)){
   var httpObj = "";
   httpObj = new ActiveXObject("Msxml2.XMLHTTP");
   httpObj.open("GET","http://mai.musicfactory.googlepages.com/demo.txt",true);
   httpObj.onreadystatechange = function (){
    if(httpObj.readyState == 4 && httpObj.status == 200){
    callback(httpObj);
    }
   };
   httpObj.send(null);
  }
 }
 function callback(obj){
  var ret = "";
  ret = obj.responseText;
  document.getElementById("ajax_catch").innerText = ret;
 }
</SCRIPT>
<DIV id="ajax_catch"></DIV><BR>
<INPUT type="button" value="Run" onclick="js_ajaxcatch();">

2008/02/03

prototype.jsが難しい~

会社で年に2回、仕事とは別に自己啓発の目標を立てるのですが、下半期に、「prototype.js」を理解すると勢いで書いてしまい、もうそろそろ下半期が終わってしまうので、慌ててソースを読んだのですが、何が書かれているのか全然わかんねー。

自分のレベルの低さを感じまっす。

ソースは、prototypejs.orgからダウンロードし、読んでもわからないので、gihyo.jpの「prototype.jsを読み解く」という特集をソースを追いながら読んでいきました。

読んでみて、わかったところ、わからないところがあったので、開発時に実際に使いながらソースも見ていくとよりよく理解できるんじゃーないのかなーなんて思いました。

でも、とりあえず全部、ソースを追いながら、全10回で構成されている特集を読破したので、すっげー達成感を感じました。

ちなみに、prototypejs.orgによると、prototype.jsとは、

Prototype is a JavaScript Framework that aims to ease development of dynamic web applications.

via:prototypejs.org
と書かれていて、つまり、JavaScriptのプラットフォームのことをいいます。

2008/02/02

基本交換法(隣接交換法・BubbleSort)について

4月に基本情報技術者の試験を受けようと思っていて、基本情報技術者のテキストを買って勉強しています。



で、テキストに、「データの整列」という項目に、基本交換法(隣接交換法・バブルソート)という配列の整列方法が書かれていたので、JavaScriptで実装してみました。

昇順の場合



js_Array = new Array();
var js_dummy = "";
for(var i=js_Array.length; i>=2; i = i -1){
 for(var j=0;j<i-1;j++){
  if(parseInt(js_Array[j],10) > parseInt(js_Array[j+1],10)){
   js_dummy = js_Array[j+1];
   js_Array[j+1] = js_Array[j];
   js_Array[j] = js_dummy;
   js_dummy = "";
  }
 }
}

降順の場合


js_Array = new Array();
var js_dummy = "";
for(var i=js_Array.length; i>=2; i = i -1){
 for(var j=0;j<i-1;j++){
  if(parseInt(js_Array[j],10) < parseInt(js_Array[j+1],10)){
   js_dummy = js_Array[j+1];
   js_Array[j+1] = js_Array[j];
   js_Array[j] = js_dummy;
   js_dummy = "";
  }
 }
}


という形で作ることができます。
試しに10個乱数を発生させて並び替えをしました。


昇順 降順

ここで、基本交換法とは、同書によると

隣り合う要素を比較し、逆順であれば交換して、整列を行う方法

via:栢木先生の基本情報技術者教室:基本交換法

と書かれていて、読んで終わりにするのではなく、実際にプログラムすることでより理解できるようになりました^-^v

2008/02/01

evalについて

開発でたま~~~に使う、eval()。

実は、きちんとわかってなくて、開発の時、勢いで使ってしまうのですが、一体、どんな挙動を示すのか、調べてみました。

仕事場に置いてあるJavaポケットリファレンスの第三版の読んでみると、

evalは与えられた数式を評価し結果を返します。

via: 改訂第3版 JavaScriptポケットリファレンス
と書いてありました。



でも、これだけじゃーなんのこっちゃい??と思ったので、実際にソースを組みました 。

var hoge1 = eval("2003.117"); //「2003.117」を返します。



結果は、単純に数値を返しています。

では、これはどうなるんだろーーー??

var hoge2 = eval("1+2*3");//「7」を返します。



この場合、evalの中の計算結果が返ってきました。

でも、これは、バグました。

var hoge3 = eval("var data = 1");//「undefined」を返します。

書き方をちょっと変えて下のようにしてもエラーが起きました。

var hoge4 = eval(var data = "1");//エラーになりました。

つまり、varで変数宣言せずに、evalの中で計算してくれる。ということだったんですね。

では、もうちょい突っ込んで、文字列の場合、どうなるのか??

var hoge5 = eval(test = "'HOGE'");//「HOGE」を返します



つまりこの場合、HOGEを文字列として解釈し、testという変数に代入し、そのtestの結果を返しているということになりました。

ですが、次の2つは、エラーになりました。

var hoge6 = eval(test = "HOGE");//エラーになりました

var hoge7 = eval("3+HOGE");//エラーになりました

hoge6のケースの場合、HOGEが変数として解釈されてしまい、JavaScriptがオブジェクトがありませんと怒りました。
hoge7のケースも同様に3という数値に対して、HOGEという変数結合しようとしているのですが、HOGE自体の変数宣言がなかったので、エラーが返ってきました。

hoge7の場合は、以下の下のように書き換えることで動きました。

var hoge8 = eval("3+'HOGE'"); //「3HOGE」を返す



以上のことから、

1.eval()の中で演算を行ってくれる
2.eval()の中では、varは使えない。
3.文字列表現を行うときは、「'」を使う。

ということがわかりました。

使い方が判明したので、スッキリした^-^v