2010年12月30日木曜日

JavaScriptのツールキット開発を始めました。

久しぶりの投稿です。
現在、VMLエディターをSVGでも利用できるように改造中です。この改造にあわせて、JavaScriptでのツールキット開発も行っています。
今まで、JavaScriptは、ブラウザ組み込みのスクリプト言語としてしか思っていませんでしたが、JavaScriptでのクラス定義が可能なので、使いやすいツールキットの開発をはじめてみました。
クラスを利用すると、ツールキットとして使いやすいインタフェースが提供できる点が大きなメリットですが、JavaScriptの欠点としては、ブラウザ毎で仕様が異なることにあります。
そこで、各ブラウザ毎の動作を自動的に判断するクラスとメソッドを用意する予定あり、大体次のようになります。

/* UnifiedBrowderクラス内で、ブラウザのタイプを調べ、各メソッド処理を決定します。作成しれたクラスインスタンスは、myUBに代入されます */
myUB = new UnifiedBrowser(); 

/* myUBインスタンスのメソッドであるgetMouseButtonを呼び出します。getMouseButtonでは、各ブラウザ毎に異なる処理により左ボタン・右ボタン(例えば、左ボタンなら'L', 右ボタンなら'R')を返却します。このようにすることで、ブラウザ間で異なる処理を一つのメソッドで処理します。*/
var button = myUB.getMouseButton(e);

これだけだと、クラスまで利用せずに、関数で処理すれば良いように思えますが、関数だと、その都度簡単に関数を沢山定義することになり、収集がつかなくなってしまいます。クラスを使うと、このようなブラウザ依存を解消する処理群をメソッドとして、一つのクラスの配下にまとめることができるのが一番のメリットです。

そこで、クラスを有効に活用したJavaScriptツールキットを開発することにしました。Yawdbaデータベースシステムも、このJavaScriptツールキットを利用して構築したいと思っています。

2010年9月20日月曜日

VMLを使った簡単な図形エディターを作ってみました。

久しぶりです。今、JavaScriptを使って簡単な図形エディターを作っています。図形の描画については、マイクロソフトが作ったVMLを使っていますが、今後は、SVGにしないといけないかもしれません。ステップ数は、430ステップです。図形描画として直線、矩形、楕円だけですが、グラデーションや立体化、図形の移動などもマウスでできるようになっているので、結構コンパクトにできたと思っています。
文字列や多角形描画機能を入れても1000ステップぐらいになるかと思います。
使い方は、マウスドラッグにより、画面左のメニューに従って、直線・矩形・楕円を描画します。
また、図形をマウスで選択して図形の移動が可能ですが、さらに、マウス右ボタンで描画属性を変えたり、図形を消すこともできます。
図形が作成できたら、画面の中ほどにある「ソース」ボタンをクリックしてVMLタグリストを取り出し、Webページに貼り付けることで図形描画が可能となります。
このエディターを拡張したいとも思いますが、次には、SVG対応のエディターを開発することを先にしたいとも思います。
私のサイトに、このJavaScriptプログラムをアップしました。YawdbaサイトのJavaScriptのVMLエディターから添付ファイルをダウンロードしてIEで動作することができます。一息ついたら、プログラム解説を載せます。お待ちください。

2010年9月11日土曜日

JavaScriptと図形エディターを作成することができます。

ひさしぶりです。今、JavaScriptを勉強しています。

HTMLのタグでは、テーブルや文章、水平線しか表現できないと思っていましたが、VMLやSVGを使うと図形を描画することができます。これらのタグを使ってグラフを書くこともできます。まずは、VMLで開発しています。
VMLは、IEでしか使えませんが、今後はSVGでの開発も考えています。VMLについては、とほほのVML入門をご覧ください。

そこで、これらの機能を使ってJavaScriptで簡単な図形エディターを作れないか検討しています。マウスドラッグにより図形を描画できるようにしました。
マウス位置は、onmousedownイベント発生時のマウスのXY位置を取得と、マウス移動後のonmouseupイベント発生時のマウスのXY位置から図形の開始位置と終了位置を決定し、document.createElementでVMLタグを作成し、appendChildでdivタグ追加しました。

マウスドラッグの際には、マウスを移動するたびに図形枠を表示していますが、スムーズに動作しており問題はなさそうです。
現在、図形の塗りパターンや線パターンなどを追加していますが、作成できたらソース公開しますので待っていてください。

2010年8月16日月曜日

javaのsqlアクセスメソッドgetStringで文字化け(2)?

以前にjavaプログラミングで、MSAccessデータベースにアクセスする際の文字化けについてお話しました。どのようにコーディングするのかコメントがありましたので、私がYawdbaで使用しているコードの抜粋を説明します。

◆以下のコーディングでODBCデータソースにアクセスします。
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver"); 
cnn = DriverManager.getConnection("jdbc:odbc:" + "データソース");

◆取得したODBCデータソースコネクション(cnn)クラスのcreateStatementメソッドを呼び出し、SQL文を実行するStatementインタフェースを以下のように取得します。

stmt = cnn.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);

◆StatementインタフェースのexecuteQueryメソッドにより、SQL Query文を実行します。
rset =stmt.executeQuery("SELECT * From myTable"); 

◆SQL文が実行したら、取得したResultSetインタフェースオブジェクト(rset)を使って取得するレコード行を設定した後、レコード内のカラム位置(1~)を指定してデータを取得します。
このとき、このデータの型によって動作が異なります。

> データ型がVARCHAR以外なら、通常のgetStringメソッドを使ってデータを取得します。
val = rset.getString(カラム位置);


>データ型がVARCHARなら、ストリームを使ってデータを取得します。
/* データ取得するためのリーダー(myReader)をgetCharacterStreamメソッドで取得します */
Reader              myReader = rset.getCharacterStream(カラム位置);
/* 取得するデータの表示サイズをgetColumnDisplaySizeメソッドで取得し、そのサイズ分のStringBufferを確保しておきます */
StringBuffer       sb = new StringBuffer(該当フィールド表示サイズ);

try    {
        int    c;
        /* 取得したmyReaderを使ってreadメソッドで1文字づつ取得します。*/
        while((c = myReader.read()) != -1) {
        if(c != 0)  /* c == 0の場合には、文字列データとして不正なのでスキップ */
                       sb.append((char)c); /* 取得した文字列をStringBufferに追加します */
                }
        }
        catch (Exception e)
               エラー処理
        }
        val = (sb.length() == 0)?null:sb.toString(); /* StringBufferを文字列に変換します。 */
}


現在開発しているYawdbaもある程度形になれば、Yawdbaのサイトで公開したいと思いますが、暫く時間をください。

2010年8月4日水曜日

構造化プログラミングと抽象化について

私は、プログラミングを始めてから長い間、構造化プログラミングによる設計を行ってきました。この経験のなかで、処理の抽象化による設計が大切であることが分かってきました。今回は、これについて話したいと思います。おそれく、処理の抽象化とオブジェクト指向プログラミングは、近い関係にあるかと思います。
入社後、2年程たってサンディエゴに出張してUCSD-pSystemlの内部構造を勉強することになりました。UCSD-pSystemには、Pascalコンパイラーだけでなく、ファイルシステムやプログラム実行環境、スクリーンエディターが用意されていました。プログラミングに関して勉強になったのは、そのファイルシステムのモジュールの作り方でした。詳しくはこのリソースをご覧ください。
下位のモジュール(では、フロッピーのディスク内のシリンダー番号やセクター番号から物理セクターを読み込んで、メモリ内に読み込むだけにし、この下位モジュールを呼び出す上位モジュールでは、実際に物理セクターを読み出す下位モジュールを使ってファイルシステムが使用する論理ブロック(ブロック長は固定の512バイト?)を実現していました。さらに、その上のモジュールでファイル名の管理などを行う実際のファイルシステムを構築しています。このような構造は、通常のオペレーティングシステムの開発方法としては一般的ですが、下位モジュールに行くに従って実施のディスクアクセスを物理動作を行っています。
この方法のメリットとしては、仮にセクターの管理するバイト数が変更されたとしても、下位モジュールを修正するだけで上位モジュールに手を加えることなく動作できることにあります。同様のシステム構成としては、プロトコルレイアの階層として一般的なOSI参照モデルがあります。このOSI参照モデルの下位層である物理層やデータリンク層から上位に行くに従って、データにやり取りが抽象化されています。
このように、処理やデータを抽象化することにより、仕様変更に強いシステムの構築が可能となります。
なお、私が尊敬する「ニクラウス・ヴィルト」も、プログラミングに関する抽象化の大切さを著しています。

2010年7月23日金曜日

クラスの作り方

Javaプログラミングでは、まず、クラスが必要となります。それでは、クラスを設計する上での基準などあるのでしょうか?。これが、正しいかはわかりませんが、私が考えるクラス設計方法について述べたいと思います。
私は非常に長い間、構造化プログラミングに従ってプログラム設計を行っていましたが、システムプログラム分野では、データの関連をポインターを使ったツリーやノードで表現するデータ構造が決まるとほとんど、プログラム構造が決まってくることがわかってきました。その結果、プログラミングの多くの時間はデータ構造の設計に費やすようになりました。データ構造の設計では、今後、想定される仕様変更や機能追加に対応できるかが大きなポイントとなります。
オブジェクト指向の設計方法でも、クラスを単位を決定するには、今後、どのような仕様変更があるか、作成したクラスが他のモジュールで再利用できるかを観点に決める必要があると思います。
高速性が必要とされるサブルーチンや仕様変更が発生することが想定されないサブルーチンに迄、クラス化する必要はないと思います。

Yawdbaでは、クライアントからWebリクエストから、クライアントのブラウザやパラメータなどを内部データに持つクラスインスタンスを作成し、その後の処理では、このクラスインスタンスのみを使用して処理します。もし、クライアントからの呼び出し方法が変更された場合には、このクラスインスタンスを拡張するだけで、後続の処理に影響を与えないことが可能にしています。

構造化プログラミング

わたしが、プログラマーになったころ(1978年頃)、大量のソースコードを開発する方法として構造化プログラミング手法が確立したころでした。それまでのアセンブラやFortranなどのプログラムロジックには、プログラムを開発する手法がなく、ロジックを記述する手法としてフローチャートがあったのみでした。
構造化プログラミング手法では、 順次繰り返し分岐を組み合わせて論理構造を作り上げるものです。このように論理構造を限定化することにより、大量のソースコードの品質を向上することが可能となりました。最近のプログラム言語では、このような構造化プログラミング技法での順次・繰り返し・分岐をif文やwhile文などの構文として組み込まれています。
したがって、CやJava,VisualBasicなどを使ってgoto文を使わずにコーディングすれば、まずは、構造化プログラミング手法に準じたプログラムとなります。
私の知っている人で、ロジックを従来の方法で設計してフローチャートで記述した後、このフローチャートから順次・繰り返し・分岐の構造を作り出した人がいました。しかし、このモジュールの非常に分かり難く、デバッグが非常に困難になってしまいました。このような方法は、構造化プログラミングとは言えません。

2010年7月18日日曜日

Cプログラマーから見たJava

私は、長くC言語(約20年くらい)プログラミングを行ってきました。当初、C言語は、CobolやFortranには無かった構造化設計が可能な上に、PL/IやPascalで可能であったポインタが利用できる点において、システム開発では有効であったと思います。(PL/Iは、コンパイラーが非常に重くIBMコンピュータでしか完全には利用できませんでしたし、Pascalでは、ビット演算など小回りの効くコーディングができなかったり、オブジェクトモジュール別の開発が面倒でした。)
その後、SmallTalkなどの成功によりオブジェクト指向プログラミングが流行るようになると、C言語でも同様の処理系が開発できないかと言うことが検討されC++が開発されました。しかし、C++を利用せずに、C言語でオブジェクト指向風のコーディングでできないかというアプローチも行われました。なぜ、オブジェクト指向プログラミングが大切かお話するまえに、C言語でオブジェト志向風プログラミングを行うコーディングにつてお話しましょう。これが、分かるとJava処理系の動作について分かるかと思います。

クラスには、インスタンスとメソッドがありますが、これは、C言語での構造体で定義します。インスタンスについては、構造体内の一般の変数、メソッドは、関数へのアドレスを格納します。

例えば、次のように書きます。
struct {
  int  instance;
  int  (*get_method)(void);
}  myClass;

instanceフィールドは、このクラスのインスタンス変数を格納するフィールドであり、get_methodフィールドは、get_method関数ポインターが格納されます。オブジェクト指向は、それぞれのオブジェクト毎に内部インスタンスとメソッドがありますが、このようにすることで、C構造体に付随するインスタンスとメソッドを定義します。あとは、この構造体を通じて、メソッドを通じて操作することでオブジェクト指向を実現します。

しかし、この構造体では、get_methodフィールドは、単に関数ポインターが格納されると宣言しているだけで、実際の関数アドレスが可能されている訳ではありません。そこで、これらの構造体に関数アドレスを事前に設定する必要があります。これらの初期設定する部分を関するにして、上記構造体のアドレスを返却する関数を以下のように用意します。
  myClass *handle = Create();

このCreate関数で、get_method関数アドレズを設定したります。このようにすると、次のように利用できます。
  thisValue =(* handle->get_method)();

Javaでもオブジェクトをクラスから作り出す際に、newオペレーターを使っていますが、内部的には、クラス特有に存在している構造体に、メソッド関数などを定義したり、各クラス内のインスタンス関数を実行しているものと思われます。この方法で、擬似的にオブジェクト指向風のプログラムを作成することができますが、クラスのインヘリタンス(継承)機能をC言語で記述することはできません。

2010年7月11日日曜日

Excelって印刷のことを考えていないと思う

みなさんは、Excelを使って印刷するケースが多いと思いますが、実は、Excelからの印刷では注意すべき点が沢山あります。
Wordなどでは、Wordのファイルメニューにあるページ設定で用紙サイズを指定すると、この用紙で印刷されます。プリンタドライバーの印刷設定に「用紙サイズ」や「原稿サイズ」などの設定がありますが、この用紙サイズを変えても、Wordで設定した用紙サイズで印刷され、印刷レイアウトはあまり変化しません。つまり、Wordでは、Wordで指定された用紙サイズで印刷のレイアウトが決定され、プリンタドライバによって変化することはありません。
一方、Excelでは、印刷指示を行った際に、プリンタドライバで設定した用紙サイズやExcelの[ページ設定]で指定した「用紙サイズ」に合わせて、Excelで印刷できる行数や桁数を計算して印刷します。Excelのページ設定で印刷領域から印刷ページ数を指定してレイアウトを決定する方法もありますが、印刷レイアウトは、プリンタドライバの能力(解像度・印刷可能領域サイズ・搭載フォント種類)によって自動的に変化します。
このため、プリンタドライバを変えてしまうと、思ったように印刷されないなどの現象が発生します。
Excelは、基本的にセルで計算するためのソフトであり、印刷に向いていないことを十分知っておく必要があります。

2010年7月4日日曜日

コンピュータ昔話(PC起動をなぜブートと言うか)

みなさんは、PCを立ち上げる際にブート(Boot)するといいますが、なぜかご存知でしょうか?昔のコンピュータでは、ハードウェアリソースが限られており、そのためにシステムを立ち上げるために必要なプログラムをROMに書き込んでおくことができませんでした。
そこで、最低限の入出力を行う処理だけがコンピュータハードウェアとして用意されており、PCを立ち上げるプログラムをメモリにロードする手順(ブートストラップローダー)を行った後、立ち上げ少しずつ機能を加えながら立ち上げを繰り返しました。まるで、靴紐を編み上げるようにコンピュータを起動するために、コンピュータの立ち上げをBootStrap(靴紐)と言いました。ブートストラップからストラップが無くなり、現在では、PCを立ち上げるのにブートと言うようになりました。


サーブレットからクライアントブラウザを知る方法

お久しぶりです。一ヶ月以上空いてしまいました。
サーブレットは、クライアントブラウザからに表示指示に対して、クライアントブラウザにHTMLページを送信します。しかし、クライアントブラウザの表示機能には差があるため、クライアントブラウザによっては、出力するHTMLページを変更する必要があります。
サーブレットを構築するためのTomcatでは、リクエストを発行したブラウザを検知する方法があります。
クライアントからブラウザ表示指示を送信すると、サーブレット上のdoGetやdoPostメソッドが呼び出されます。この際のパラメータであるHttpServletRequest内のヘッダーからユーザーエージェント文字列を取得してブラウザを判別することが可能です。
世の中にある各ブラウザのユーザーエージェント文字列は、userAgent一覧のように沢山ありブラウザを特定するプログラムを作成するのは大変面倒です。

このようなとき、私は、JavaのStringTokenizerを使って対応しています。
StringTokennizerは、文字列内の空白など文字列を分割する文字(区切り文字)を指定します。すると、この文字が発見されると同時に、分割することができます。

例えば、
    StringTokenizer st = new StringTokenizer(myString, " /");
    while(st.hasMoreTokens()) {
      String s = st.nextToken();
    }
とすると、区切り文字が空白と「/」なので、myString文字列が、"aaaa/bbbb"の場合には、"aaaa"と"bbbb"に分割されます。これをnextTokenメソッドとhasMoreTokenメソッドを使って取り出します。

このメソッドを使って、ユーザーエージェント文字列を解析し、ブラウザを判断することができます。さらに、ブラウザのバージョン情報などの取得も可能です。

    StringTokenizer st = new StringTokenizer(user_agent, " ();,/");
    while(st.hasMoreTokens()) {
      String s = st.nextToken();
      if(0 <= s.indexOf("MSIE")) {
        browser = IEブラウザ
        break;
      }
      if(0 <= s.indexOf("Chrome")) {
        browser =Chromeブラウザ
        break;
      }
      ......
      ......
    }

皆さんも、使って頂ければと思います。

2010年5月5日水曜日

Servletでのパラメータ解析(3)

HttpプロトコルのGETリクエスト時に、パラメータの変数値などに日本語が含まれた場合のパラメータ解析方法について「Servletでのパラメータ解析について(2)」のようにするれば、各ブラウザでの日本語文字コード変換に合わせてパラメータ値を取得が可能であるとお話しました。
しかし、この方法で上手く行かない場合があることが判明しました。
ブラウザからURLを指定時に、URLにパラメータを指定してGETリクエストを発行する以外の方法として、以下のようなHTMLによりGETリクエストを発行することが可能です。

<html>
<body>
<form name="f1" action="http://localhost:8080/TestServlet/Test" method="get">
<input type="text" name="p1">
<input type="submit" nput>
</form>
</body>
</html>

このようなHTMLでは、テキスト入力された日本語文字列をどのような文字コード(ShiftJIS,EUC,UTF8など)で出力するか指定することができます。

例えば、
<meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
と言うタグがHTML上に存在していれば、入力フィールドで指定された日本語文字列は、ShiftJISに変換され、URL上のパラメータとして指定されます。
Servletでのパラメータ解析について(2)」では、各ブラウザに合わせて固定の文字コードに変換するようになっていますが、同じブラウザであっても、HTMLからGETリクエストを行った場合には、HTMLの書き方によって、文字コードがShiftJISになったり、UTF-8に成ったりします。

ブラウザからのURL指定によるGETリクエストと、HTMLからのGETリクエストでの違いがあれば、何らかの対応も可能でしたが、Servletで渡されるHttpServletRequestパラメータからは、全く違いがないために処理を変えることが不可能であることが判明しました。Webアプリケーションでは、各社ブラウザでの動作の違いによって実装が面倒ですが、なんでこんな仕様になってしまったのでしょうか?標準化して欲しいものです。

対応方法としては、ブラウザからの直接GETリクエスト指定時と、HTMLからGETリクエスト時に渡すパラメータで、文字コードを指定するなどの対応が必要かと思います。

2010年5月3日月曜日

Servletでのパラメータ解析(2)

「Servletでのパラメータ解析について(1)」では、ブラウザから「http://localhost:8080/TestSevlet/Test?p1=あいう」などのように直接URL指定を行った場合に、後続のパラメータの処理がブラウザによって異なることをお話しました。
各ブラウザの動作を、プロトコルヘッダのUser-Agentの特定のパラメータから引き出せないか、Webなどで確認したところ、このUser-Agentは、各メーカーが勝手に定義しており定義などないようです。ただし、各ブラウザメーカーともに、他社のブラウザと同等の機能を提供したいので、あまり、突飛なUser-Agentは存在していないようです。
したがって、User-Agentからブラウザの種別を判別して、String命令で各ブラウザにあわせて変換する文字コードを個別に実装するしかなさそうです。

なお、本日、Operaブラウザでの動作を確認しました。すると「http://localhost:8080/TestSevlet/Test?p1=あいう」などと指定するとChromeや他社ブラウザとも異なり、JISコードで展開しているようです。
例えば、上の例をOperaブラウザから入力すると
「http://localhost:8080/TestSevlet/Test?p1=%1B$B$%22$$$&%1B(B」と展開れます。文字列の最初にある「%1B$B」は、これから2バイトの漢字を開始するための指示、最後の「%1B(B」は、2バイト漢字が終了したことを示しています。途中も文字列は、JIS漢字コードとなります。
したがって、OperaブラウザからサーブレットにGetメソッドが送信された場合には、

    String p = req.getParameter("p1");
    v = new String(p.getBytes("iso-8859-1"),"iso-2022-jp");
    
と処理する必要があります。

※ これは、Operaのバグと思われますが、上記の仕様だと、上のp1パラメータとして「あいう」などと入力した例を見てください。展開されたURLは次のようになっています。
   「http://localhost:8080/TestSevlet/Test?p1=%1B$B$%22$$$&%1B(B
このURLでは、パラメータの途中に「&」が現れています。このため、Tomcatでは、「&」は、パラメータ指定の終了を示すので「あいう」のパラメータ値をサーブレットに渡すことは不可能となってしまいます。

なお、いままでの話を整理すると、

① User_Agentから、呼び出しブラウザがChromeだったら、
    String p = req.getParameter("p1");
    v = new String(p.getBytes("iso-8859-1"),"UTF-8");
としてパラメータ値を取り出す。

② User_Agentから、呼び出しブラウザがOperaだったら、
    String p = req.getParameter("p1");
    v = new String(p.getBytes("iso-8859-1"),"iso-2022-jp");
としてパラメータ値を取り出す。

③ それ以外だったら、
    String p = req.getParameter("p1");
    v = new String(p.getBytes("iso-8859-1"),"Windows-31J");
としてパラメータ値を取り出す。

となります。ただし、Operaのようにパラメータの日本語処理で問題が発生することも想定されますので、パラメータは極力英語とすべきでしょう。

Servletでのパラメータ解析(1)

Servletに、パラメータを指定する方法として、FORMタグ無いの変数を設定しておきHTMLでSubmitでPOSTメソッドやGETメソッドで指定する方法が一般的です。
このほかに直接、Webブラウザで
http://localhost:8080/TestSevlet/Test?P1=aaaa
等と指定する方法があります。この指定では、P1と言うパラメータに「aaaa」を指定することになります。
ところが、Chromeブラウザのみ変数の値を「日本語文字」あるいは「漢字」にする(例えば:http://localhost:8080/TestSevlet/Test?p1=あいう)と正しいパラメータが取得できないことが判明しました。文字化けが発生してしまいます。

サーブレット側のコーディングは、通常のサーブレットプログラミング同様に以下のようなコーディングとなっているだけです。
  String p = req.getParameter("p1");
  v = new String(p.getBytes("iso-8859-1"),"Windows-31J");

そこで、Chromeとその他のブラウザgetParameterで得られた変数pを使ってp.getBytesによって取り出した結果を調べました。その結果、Chrome以外のブラウザでは、取得したバイト列がシフトJISである一方、Chromeでは、UTF-8であることが分かりました。

実際、
  String p = req.getParameter("p1");
  v = new String(p.getBytChes("iso-8859-1"),"UTF-8");
とするとChromeでは正常にパラメータが取得できました。

コーディング上で見ると、RequestパラメータからgetHeaderメソッドを使って”User-Agent"のブラウザ情報を取得して、この情報がChromeブラウザであることを示していたら、変換を"UTF-8"にするのが簡単でしょう。

なお、私が調べてブラウザでのUser-Agentは次のようになっていました。

Chrome 4.1.249
Agent=Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US) AppleWebKit/532.5 (KHTML, like Gecko) Chrome/4.1.249.1064 Safari/532.5

FireFox 3.5.2
Agent=Mozilla/5.0 (Windows; U; Windows NT 5.1; ja; rv:1.9.1.2) Gecko/20090729 Firefox/3.5.2 GTB7.0 ( .NET CLR 3.5.30729)

IE8
Agent=Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; GTB6.3; .NET CLR 2.0.50727; .NET CLR 1.1.4322; .NET CLR 3.0.4506.2152; .NET CLR 3.5.30729)

Safari 3.0.3
Agent=Mozilla/5.0 (Windows; U; Windows NT 5.1; ja) AppleWebKit/522.15.5 (KHTML, like Gecko) Version/3.0.3 Safari/522.15.5

今回の現象面からみると、Chromeかどうか判断できれば、ChromeのみUTF-8にするだけでよいが、その他、UTF-8が標準のブラウザの場合に同等の処理が必要となります。上に掲載したUser-Agent文字列などから、言語体系が分かるのかもしれません。(User-Agent文字内には、en-US,ja等と言った言語圏を示す文字列が存在しています。
明日は、ゴールデンウィークなのでUser-Agent文字列について調べようと思います。

続きは、Servetでのパラメータ解析について(2)をご覧ください。




2010年3月23日火曜日

プログラム言語について-Basic言語-

Basic言語は、1964年にコンピュータ教育用の言語として開発されたようです。言語的には、当時使われていたFORTRANに近いものとなります。FORTRAN言語での処理系は、軽いので非常に小さなメモリでも動作できたことから、パソコン上で動作できるようになり、普及しました。
私も以前、Z80パソコン上で動作するBasicインタプリターを開発したことがあります。コンパイラーがコーディングされたプログラムのロジックが動作する機械語を作成するものですが、インタプリターは、機械語を作成するのではなく、直接、動作します。

例えば、以下のBasicプログラムを実行した場合には、
10 A = 10
20 FOR I=1 TO 3
30 A = A+1
40 NEXT I
をRUNコマンドで実行すると、次のように動作します。
① 行番号10でA=10を実行します。変数Aに10を代入する命令ですが、変数Aは未だありませんので、変数Aの領域をメモリに確保して、10を設定します。
② 行番号20は、FOR文であり、そのループ変数がIであること、下限が1、上限が3であることが分かります。そこで、①と同じように変数Iを作りその中に値0を代入します。変数Iの内容が3より小さいので次の行(行番号30)を実行することになります。
③ 行番号30では、A=A+1であることから、変数Aの値を取り出し、その変数値に1を加えた結果を変数Aに格納します。
④ 行番号40では、Iの値に1を加え、行番号20に戻ります。
⑤ この動作を繰り返し、変数Iが3を超えるまで③④を繰り返します。Iが3を超えると行番号40の後の行を探しますが、行番号40に続く行が見つからないので終了となります。変数Aには、13となります。
このように、インタプリターでは、順にプログラムを実行するようになります。

2010年3月7日日曜日

なぜ -1 と-1 を掛けると +1 になる(その2)

このブログサイトで以前、-1×-1が+1になる理由について書いていました。そのときの解法は、乗算の分配の法則と交換を使ったものでした。
一週間ほど前から、図書館で「虚数の話」と言う本を借りて読んでいます。内容は、タイトルどおり虚数の話ですが、この中で、その理由が書かれていました。
虚数とは、二乗してマイナスとなるような数ですが、実は、虚数はそれだけではなく、数を直線上の点として表現するではなく、数を平面上の点として拡張して表現すること重要な要素であるそうです。
数を直線状の値ではなく、平面状の値でとすることで、ベクトルの加算や減算の定義は簡単ですが、乗算については、それぞれの線の長さを乗算した後、その方向を回転することで、従来の乗算と拡張みなすことが可能となりました。
マイナスとは、180°回転した方向を示すので、-1×-1では、先ず-1で180°回転し、次の-1でさらに、180°回転することから、元の位置に戻り0°である+1となります。


詳しくは、ポール・J・ナーイン氏の「虚数の話」をご覧頂くことが良いかと思います。少し難解なので根気強く読むことが必要かと思います。エッセンスが書いてあるのでは、Newtonの2008年12月号ですが、少し断片的過ぎる感じがします。みなさんも、もう一度見直すのも勉強になるかと思います。

2010年2月28日日曜日

プログラム言語について-C言語-

久しぶりです。今日は、C言語についてお話します。最近では、C言語やJavaでのプログラム開発が多くなっていますが、私が最初にC言語を使うようになったのは、約25年前でした。
当時、パソコンでのシステム開発用のプログラム言語としては、アセンブラの他には、PascalやPL/M(PL/I言語の中から、パソコンシステム開発向けに限定したもの)くらいしかありませんでした。共に、メモリの確保やポインターなどを利用したプログラミングが可能となる点が、利用されていた点かと思います。

しかしながら、Pascalではビット演算機能がなく、より高速な処理を行うには不向きでした。Pascalは、設計者であるヴィルトが本来プログラミングとは、事柄を抽象的に考えるべきであり、コンピュータ内のビット形式などを意図したコーディングはすべきでないとの考え方によるものだと思います。しかし、これが、実際のプログラミングでは、より高速に処理するために、コンピュータ内のビット形式を意図する必要がありました。

このような状況下で、使われるようになったのがC言語です。C言語では、PascalやPL/Mなどのようにメモリを動的に確保したり、ポインターが利用できること、CPU上のビット操作が簡単にできること、構文が単純でありコンパイル時間が高速であったことなどからパソコンシステム用のプログラム言語として利用されるようになったと思います。

なお、C言語は、もともとUnixオペレーティングシステムを開発するために設計されているために、面白い書き方があります。。Unixが稼動するミニコンがPDP-11であったことから、PDP-11が6ビットマシンであったころから、通常は、バイナリデータを表現する際に16進数で表現されたますが、8進数の表現のが簡単になっています
 ⇒(文字列の中に16進数表現で書き込むには、「\xAB」、8進数表現で書き込むには「\253」などと指定します)

詳しくは、パソコン昔話(なぜ1バイトは8ビット)をご覧ください。

2010年2月9日火曜日

Javaで構造体を扱う

Javaは、オブジェクト指向の言語と言われますが、いままでC言語などを使ってプログラミングしていた人にとっては、C言語の構造体のメンバーに関数が追加されたものがクラスと考えることができます。詳しくは、Cプログラマーから見たJavaをご覧下さい。
したがって、JavaでのC言語の構造体は、メソッドのないクラスを定義することで利用可能となります。Javaのクラス内で構造体を利用するには、クラスの内部に別ファイルで定義したClassを利用することで対応できますが、この方法だとファイルの数が増えてしまうことが欠点となります。
各クラスのロジックをコーディングする時に、一時的に構造体を使いたくても別にファイルを作成することが必要になってしまいます。
このような場合に、簡単に構造体を作る方法がわかりました。

このような場合、クラス定義のファイルに、一時的に利用する構造体を「final」を付けたクラスとして定義します。

final class xxx_item {
 double key;
 String value;

 public xxx_item (double p1, String p2) {
  key = p1;
  value = p2;
 }
}

public class xxx_list {
 ・・・・・・・
 メソッドなどで
 xxx_item temp = xxx_item(10,"aaaaa");  
 temp.key は、10
 temp.value は、"aaaaa"
 となります。
}

このようにすると、1つのクラス定義でも簡単に構造体を利用することが可能となります。
参考にしてやってみてください。


2010年2月7日日曜日

自転車のチェーンが外れたときの対処方法

コンピュータの話ではありませんが、今日、自転車のチェーンが外れました。とりあえず、引いて家に戻りましたが、インターネットで簡単に直せることが分かりました。自転車屋さんに持っていったらお金がかかったかもしれませんが、タダで直すことができました。

後輪の歯車にチェーンの一つを引っ掛けてペダルをゆっくり回すと、次々の歯車にチェーンが噛むようになり、元通りになりました。チェーンが若干のたるみを持っているので、このような方法で直すことができます。

2010年1月26日火曜日

プログラム言語について -アセンブラ-

今日は、アセンブラについてお話します。アセンブラとは、コンピュータのCPUが動作する機械語と1対1に対応するものです。FortranやCobolと言った高級プログラム言語が人間に分かり易く設計されているのに対し、アセンブラは、機械に分かり易く設計されていると言った方が分かり易いかも知れません。
初期のパソコンでは、MS-DOSやCP/MなどのOSとアセンブラしかなく、FortranやCobolなどのコンパイラが提供されていませんでした。そのため、これらの開発環境では、場合には、このアセンブラを使ってプログラムを書いていました。
私もCPM(8ビットのパソコン用オペレーティングシステム)で、Basicインタプリターやデータ入力システムなどを開発しました。
通常のCPUでは、メモリからCPUが持っているレジスタにデータを取り出したり、レジスタの内容をメモリに書き戻したり、レジスタ上で演算(比較を含む)などを行います。
通常は、命令と呼ばれる部分(レジスタ同士の計算、メモリからレジスターへのロード、レジスターからメモリへの書き込み)とオペランドと呼ばれる部分(命令の対象となるレジスタやメモリを指定する)から構成されます。
最初にソフト会社に入った時の教育でミニコンでのアセンブラプログラム教育がありましたが、全く動作しませんでした。その後、CPMでデバッガーが会いアセンブラでのプログラミングできるようになり、最後には再帰呼び出しのプログラムもアセンブラで書くようになり、結局、昔のAPPLE IIに搭載されていた6502, Z80,インテル8086,モトローラ68000,SunのSPARCチップなどのアセンブラによるプログラム作成を行いました。
また、アセンブラでプログラムを書くようになると、それぞれのCPUの特色が分かり、その点もメリットがあったと今でも思っています。

アセンブラによるプログラムを行うには、非常に根気の要る作業で、プログラマー35才定年説も個々から出たのかもしれません。しかし、現在では、javaなどの高級言語のお陰で、私のような実際の定年近くになる老人でもプログラムが可能になっています。



2010年1月17日日曜日

プログラム言語について -Pascal-

私がソフトウェア会社に入社した1978年当時、大型ホストコンピュータのプログラム言語としては、以前にお話したFortranやCobol、PL/Iが主なプログラム言語でした。
その後、数年でパーソナルコンピュータ(パソコン)が販売されるようになり、このパソコン用の言語としてPascal処理系が搭載されるシステムが販売されました。有名なものがAPPLE Pascalですが、これは、UCSD(カルフォルニア大学サンディエゴ分校)で開発されたUCSD-PascalをAPPLE上で動作させたものになります。
なお、UCSD-Pascalについては、本ブログの
をご覧ください。
このUCSD-Pascalは、起源を辿ると、チューリッヒ工科大学のニクラウス・ヴィルトが開発したP4 Pascalを元に開発されたようです。P4パスカルは、コンパイラによって生成されたPコードと呼ばれる仮想的なマシンコードと、この仮想マシンコードで記述されたプログラムを実行するインタプリターから構成されています。ちなみに、この仮想マシンコードを処理するインタプリターを各CPUに合わせて開発することで、様々なコンピュータ上で動作させたのがUCSD-Pascalとなります。この仮想マシンコードを使った処理は、Javaに引き継がれています。

Pascalの特徴は、プログラミング作成のために必要となる制御文(for文、do-while文, repeat-until文)が用意されており、構造化プログラミングを実現するツールとなる点でしょう。また、通常のシステムプログラミングで必要となるポインターが使えることも大きな特徴です。また、変数は、基本的にオートマチック変数(手続き内だけに有効となる変数)であり、より信頼性の高いプログラミングが可能となります。
これらの強力な機能により、システムプログラミング言語としてパソコンを中心に使われるようになりました。

しかし、Pascalの弱点は、分割コンパイルによるプログラム開発(大きなプログラムを、いくつかの部分に分割して開発し、それぞれ開発した部品をリンクにより結合するプログラム開発)が、初期のPascal仕様には無かったことが弱点でした。
また、Pascalは、最初、教育用のプログラム言語から出発したことから、データ変数の扱いなど、なるべくコンピュータの処理系に依存しないように定義されており、ビット演算などの処理が煩雑であること等も弱点の一つです。

その後、パソコンなどのシステム言語として利用されたPascalは、より記述するコード量が少なくて済み、かつ、ビット演算などが簡単に行えるC言語に移行されました。

2010年1月9日土曜日

ASP.NETでWebシステムを開発してみました。


様々なWebシステムの特徴を調べるために、典型的なWebシステムをそれぞれの次のようなシステムで開発してみました。


まずは、ASP.NETを使ってみました。ASP.NETは、htmlを拡張したページをWebサーバー上に保存しておくと、IISなどのWebサーバーでは、このページのASP.NETで拡張した部分をサーバー上で処理して、htmlページを作成し、クライアントに送信するものです。詳しくは、Yawdbaのページをご覧ください。

Webアプリケーション開発に便利なタグ(カレンダー、ツリーメニュー、ログイン)が用意されていること、htmlを拡張したASP.NETページデータ作成にするための専用のエディターが用意されれいることなどにより高い生産性を実現できる点が、ASP.NETの特徴と言えます。
しかし、最近のシステム開発の潮流であるMVC(Model, View, Control部分に分割して開発する手法)には、準拠していません。上記の専用エディターでは、データベース参照や参照結果をテーブルに表示するためのルールなどまで記述する必要があります。このため、画面設計を専用のデザイナーに任せることができません。
ASP.NETでのWeb開発では、エディターを使って簡単に開発はできます(SQLコマンドを知る必要もありません)が、エディタでの操作を記録する方法がなく、内容を確認することが困難である点が欠点といえます。いずれにしても、ASP.NETで用意されているコンポーネントを熟知して利用することがポイントでしょう

2010年1月3日日曜日

プログラム言語について -PL/I-

私がソフト会社でシステムの開発をはじめた時に習ったのが、PL/Iでした。PL/Iは、IBMが開発したプログラム言語であり、それまで使用されていた科学計算で使われていたfortranと、事務計算で行われていたcobolの機能を足して、すべての計算分野で万能となるプログラム言語を目指したものです。PL/Iとは、Program Language Oneを意味しており、IBMが付けた野心的な名前といえます。PL/Iは、コンパイルに必要となるメモリなどの資源を大幅り必要となるため、あまり普及はされませんでしたが、日本IBMのユーザでは、PL/Iで書かれたプログラムが多かったと聞いています。

PL/Iは、fortranにあった様々な数学関数や算術関数が用意されていることと、cobolにあった10進数表現が導入されたことや集団項目などの構造体が導入されています。さらに、システムプログラムを開発するためにポインターや動的メモリ確保等の機能が追加されています。

ポインターや動的メモリ、オートマチック変数などがあり、当時では強力なシステムプログラム言語といえます。しかし、万能の機能を持っているためにプログラム言語が非常に大きくなっており、コンパイルに非常にに時間がかかってしまうなどの問題があり、普及しませんでした。ちなみに、2000行のプログラムをコンパイルするだけでも、メモリを大きく利用するために、投入ジョブのプライオリティが下がり、コンパイル終了までに半日ぐらいかかってしまいました。

ちなみに、C言語が使われる前には、PL/I言語のサブセットであるPL/Mでシステムプログラムが開発されていました。

Rubyの勉強その後

Rubyの勉強を始めて約2週間経ちました。本などでは、「Instant Rails」による開発方法や統合開発環境の「Eclipse」や「Aptana RadRails」を使った開発などがあります。
勉強で使用する開発環境として、「Eclipse」では、必要なプラグインなどの依存関係が難しいので、Ruby On Rails向けの開発環境として開発されている「Aptana RadRails」を使って開発をトライしました。しかし、どう言う訳か上手くいきませんでした。ひょっとしたら必要となるRubyやRuby Railsでの組み合わせで知らないところがあるのかも知れません。
そこで、仕方なく「Instant Rails」によって、簡単な社員データベースを作ってみました。感想とすると、なるほど、コーディングをあまりすることなく簡単にデータベースシステムを開発することができました。
これは、コーディング部分がInstant Railsが持っているデフォルトの動作と違うところだけをコーディングすれば良いという所がミソのようです。特に、データーベースに対する操作が、通常のSQLコマンドを介するのではなく、AR(Active Record)のインタフェースで行われており、このインタフェースで多くの標準的な操作がデフォルトとして定義している点がコーディング量を減らすのに寄与していると思います。

Ruby On Railsでは、標準的な操作がデフォルトとして定義していますが、逆に、使いこなすためには、このデフォルト動作について十分知る必要がある点が他のWebシステムと異なる点かと思います。
特に、記述方法などについて言うと、インタフェースがまだ固まっていないところもあり、バージョンによっては、Rubyの書き方が変更されている点が気になるところです。

なお、ASP.NET、RubyOnRails、Struts、 Yawdbaなどでどのように開発方法が異なるか、比較を開始しました。次は、Strutsについても勉強するつもりですが、結果については、Yawdbaのサイトに掲載する予定にしています。掲載時には、ご連絡しますので、楽しみにして下さい

2010年1月1日金曜日

明けましておめでとうございます。


あけましておめでとうございます。
昨年の立ち上げたこのブログも6ヶ月経ちました。昨年は、ブログの内容は、コンピュータの話が主でしたが、今年は、内容をもっと広げたいと思っています。あまり、頻繁にアップできませんでしたが、今年は、1週間に一回はアップするつもりですので、立ち寄ってコメントなど頂けるとありがたいです。