目次へ

プログラミング編

無職の奥様がUNIXマシンで何をやるのか。一番手っ取り早いのがプログラミングでしょ。WindowsじゃVisualナントカ言うのがクソ高いのにくらべて基本的にどのツールもタダだし、Helloと書かせることができれば何かしらの満足感が得られるわけで・・・。 そんなわたしは主にPerlとJavaを勉強中ですが、やはりプロには考えられないような素人間違いや、プロなら当たり前だが素人には考えられないようなTipsに感激したりしています。そこで、特集するほど大がかりじゃないけど、プロには書け(るんだろうが書く気にもなれ)ないプログラミング覚え書きのようなものを思いつくままここに書くことにしました。同じような初心者の人のお役に立てば幸いと思います。新しい記事ほど上に来る積み上げ方式

/どんと来い!NullPointerException(2) /サンプルアプリにCDショップはやめたほうがいい/tryでもcatchでもとにかくreturn/Javaで文字列をぶつ切りに/JSPも落とし穴だらけ/ResultSetは一つでもループ/大文字小文字の罠/htmlとtextの相互変換(Perl)/どんと来い!NullPointerException(1)/Delphiを始める(4)プロジェクトファイルの正体/Delphiを始める(3)カエルガチョー本にも案外ついていける/Delphiを始める(2)福音サイト/Delphiを始める(1)闇夜に鉄砲/Javaで久しぶりに思い知ったこと/SQL文をかますプログラムの泣き所/SolarisでのPopUpMenu/苦労しましたJDBC/チラリズム/ちょっとRubyに寄り道/ファイルリストを作る(4)でもホントにできてんのかなあ〜ヘヘヘ/ファイルリストを作る(3)成長する配列/ファイルリストを作る(2)再帰でも繰り越すもの/ファイルリストを作る(1)再起不能のワケ/ バッファ馬鹿一代/セミコロンのエラーと思いきや/地獄までセミコロン1個/のに子式フィボナッチ/ のに子式ソート/ ワニの穴にダイブ/

どんと来い!NullPointerException(2)

さて、再びNullPointerExceptionとの遭遇だ。JDBCアプリケーションの勉強をしていたとき、教本のサンプルを真似して自分で打ったプログラムを実行しようとしてこうなった。
どうやらその発生元は以下のようであるらしい。

public void release(){

try{
rs.close();
stmt.close();
dbConn.close();
}
...(後略)

ひじょーによくある、DB接続の後処理だ・・・

よく考える。NullPointerExceptionというのは、要するに「nullなものを無理に使おうとしている」ということだ。ここでそのエラーが起こったのであれば最も考えられるのは、

成立もしていない接続を閉じようとした

ということではないか?つまり接続が成立していない?・・・接続に関する部分を見る。ドライバクラスの指定は・・・

あ。アプリケーションのWEB-INF/libフォルダにJDBCドライバファイル(mm-mysql.jar)入れるの忘れてた。

入れたら今度はさっくり動いた。NullPointerExceptionという大げさぽい名前にビビってはいけない。またこういうことがあったら紹介するつもりである。

2002年12月15日

ページ先頭に戻る


サンプルアプリにCDショップはやめたほうがいい

Jakarta Strutsの勉強を始めた。教本のサンプルはレストランの予約受付アプリだった。わたしは俺アプリにしたかったので、いきなりシチュエイションをCDショップの注文受付に変えて、構造そのものはそのサンプルをそっくり真似したつもりだった。だがなぜかエラーが出る。Setterが見つからない、というエラーだ。

Strutsの詳しい構造説明は多くの優秀な教本やチュートリアルサイトにあると思うので割愛するが、問題は
cdTitle
という、CDのタイトルを指定するプロパティ名にあった。

Strutsにはいくつか決まりがあって、プロパティのsetterメソッド、getterメソッドの命名規則もそのうちにある。その規則は、

「該当プロパティ名の先頭を大文字にすること」である・・・というふうに、教本を見てわたしは、理解した。

レストランの予約受付アプリでは、プロパティshopNameのsetter,getterはそれぞれsetShopName, getShopNameとなっている。なるほど上の規則にのっとっている。さてわたしのCDショップの場合は・・・

setCDTitle

としてしまっていたのである。明らかに、もとがCDという大文字の品目を扱うゆえのうっかりミスだ。本当は、

「該当プロパティ名の先頭だけを大文字にして、あとは先に宣言したプロパティ名と全く同一であること」

だったのだ。つまり、setCdTitleとしなければならなかったのである。

当たり前のことではあるが、もし想定したシチュエイションがCDShopではなくBookStoreであれば、こういう問題はまず起こらなかったであろう(setBookTitle...)相変わらず、何の気なしに非常に自分自身に不利な選択をするのに子である。

2002年12月15日

ページ先頭に戻る


tryでもcatchでもとにかくreturn

親切なんだかよけーなお世話なんだかわからないjavac君はよく、こっちでテキトーに作ったメソッドについて「このメソッドは例外をスローするはずだからtryでcatchしろ」と言ってくる。それは素直にやればいいんだが、問題は戻り値がvoidでなく具体的にある場合だ。

public String mightThrow(){

try{
methodmightthrowex();//何かテキトーに例外をスローするメソッドを使っていると想定
String message="This process throws exception.";
return message;
}
catch(exception e){e.printStackTrace();}

}

でいいと思ったら、今度は「戻り値がないス」と言われる。
正解は、

public String mightThrow(){

String message;

try{
methodmightthrowex();//何かテキトーに例外をスローするメソッドを使っていると想定
String message="This process throws exception.";

}
catch(exception e){e.printStackTrace();}

}

return message;

だった。うーん。まあ。熟練者の方には「なにたりまえなこと言ってんだヨ」をお叱りを受けるかも知れないが、結構わかんないところだ。
try節の中にあるものは、それが失敗したときに全部チャラになるらしい。だからreturnはtryもcatchも踏み越えた最後に置かなければならないし、戻り値となる変数の宣言はすべてに先だって行われなければならないんですね〜。間違えたことないですか?

2002年11月23日

ページ先頭に戻る


Javaで文字列をぶつ切りに

日付を表すシリアル番号「20021123」から「2000年11月23日」という表現を作成したい。
それには、8文字の文字列の先頭から0番目-3番目、4・5番目、6・7番目をそれぞれ取り出せばよい。Perlでは正規表現やsubstrなどの関数でかなりチョチョイのチョイ感が高かった。JDK1.4からは正規表現が扱えるようになったので、同様にできるのか?でもそれよりもっと昔からあるのがcharAt(index)メソッドで〜。
dserial="20021123"の場合
month=dserial.charAt(4)+dserial.charAt(5)
とすればいいのよネ〜と思ったのが、甘かった

char charMonth[]={dserial.charAt(4),dserial.charAt(5)} ;
String month=new String(charMonth);

としなければなりませんでした。偉そうに詳しい説明はできないが!だが、これで所定の目的は達せられた。

2002年11月23日

ページ先頭に戻る


JSPも落とし穴だらけ

データベースで検索を行うための検索キーワードを入力するJSPを作成していた。だが値を送信してもデータが帰ってこない。エラーメッセージはない。いろいろ調べてみるとつまりはNullデータが帰ってきていることがわかった。さらにじたばたしているうちに気がついた。
今まで、成功したあるJSPのソースをコピペして加工して他のいくつかのJSPを作っていたが、今気分一新のつもりで最初から書き直したのだった。書き直したといってもSun ONE StudioのJSP新規作成ウィザードを使ったからその分のテンプレートは・・・

あ。日本語サポート関係のコードを全くつけてなかった。

そう。検索キーワードとして送信したのは日本語のデータだったのだ。

<%request.setCharacterEncoding="EUC_JP" %>

では効果なし。

<%@page contentType="text/html;charset="euc-jp"%>

で、ようやく値が帰ってきた。いや〜、ごくごく単純なミスだったけど、データベースとの接続ができてないのかデータの送信が行ってないのか、DBアプリの作成ではなかなかわからないことがあるからなー。例外処理とかコマメに置いとけばいいんだろうけど。

2002年11月23日

ページ先頭に戻る


ResultSetは一つでもループ

JavaプログラムでSQL検索をかます。もともと要素をひとつに絞るための検索で、ゆえに得られる結果はいつでも一つだけだ。だったら

ResultSet rs=stmt.executeQuery(selectStr);
String identical= rs.getString("column");

とやって実行しようとすると、エラーになる。「ResultSetの範囲外です」みたいなメッセージだ。正解はちゃんとループを作らなければならないのだった。

ResultSet rs=stmt.executeQuery(selectStr);
while(rs.next()){
String identical= rs.getString("column");
}

なるほどね。

2002年11月23日

ページ先頭に戻る


大文字小文字の罠

家計簿等のプログラムでよく使うのが、日付を20021116のようなシリアル番号で表すことだ。プログラムで本日の日付を取得すると、それぞれのプログラム言語において日付の特別な型になっているので、これを文字列型に直さなければならない(数値型にしたければ、一度文字列型に直したものを使えるから)
Javaではどのようにしたらいいだろうか。

public String void main(String[] args){

Calendar todayCalendar=Calendar.getInstance();
Date today=todayCalendar.getTime();
SimpleDateFormat serialformat = new SimpleDateFormat("yyyyMMdd");
String serial =(String)serialformat.format(today).toString();
System.out.println(serial);

}

実は、このyyyyMMddがクセモンだ。最初APIの説明をよく見ないで
yyyymmdd
とやっていた。プログラムを実行すると

20025016

はあー?50月って何よ!・・・システムの時刻設定などいろいろ調べる。果ては使ってるForteを疑い始め、同じソースをコンソールからjavacコマンドでコンパイルして実行してみた。すると

20025916

59月!?やっぱりおかしい上にさっきと値が違う!・・・・だがもう一度java.text.SimpleDateFormatをよく研究してわかった。小文字のmは現在時刻の分を表すのだ!だから、さっきForteで実行したときは20時50分、そのあとコンソールから実行したときはその9分後だったというわけ!

2002年11月16日

ページ先頭に戻る


htmlとtextの相互変換(Perl)

さて、久しぶりにPerlだ。javaみたく$を忘れたり、if文の後にカッコを忘れたりと最初結構じたばたしたぞッ。だがそれはいい。実は

テキストファイルの内容にタグをつけてhtml形式に直したり

html形式のファイルからタグをとってテキスト形式に直したり

することが急ぎ必要になって、やっぱり超太っ腹言語Perlでやったのだ。改行の処理でときどき予期せぬ改行記号が増えたりするがなんとか行った。
ヘッダと改行記号だけの単純なhtmlファイルに限るだろうけど・・・。あんまり工夫はないので、たぶん、Javaでも少し修正すれば同じようにできるんじゃないだろうか。
これを利用すれば、ウェブブラウザはつけるくせにガンとしてテキストエディタをつけないどこかのモバイル用クソったれOSでテキストファイルを見たい場合や、テキストエディタしかない場合にhtml形式のファイルを見るとタグがうぜ〜とか言う場合、結構便利ではないかと思った。

2002年05月08日

ページ先頭に戻る


どんと来い!NullPointerException(1)

Javaをいろいろいじくっていろいろエラーを出しているうちに、近頃NullPointerExceptionというものがわかるような気がするような気がしてきた。
どーも、そのほとんどは、配列に要素が入ってないのに配列を処理しようとした、という状況で出るみたいなのだ。
その状況が一番よく出るのは、配列要素を他のメソッドで取得しようとするときではないだろうか。

わたしがそれを体験したのは、Cookieを取得するServletを作ろうとしたときだった。そのページにアクセスした回数というCookieである。このServletではまず

Cookie[] cookies=request.getCookies();

として、前回までのアクセス回数のCookieを取得し、それに1を足して返す、という仕組みだが、これで実行するとNullPointerExceptionが出た。

理由は、最初のアクセスのときは、まだCookieが生成されていないので、配列cookiesは全部nullだ。それを処理しようとしたからなのだ。

だから、こう直した。

  1. Cookieの取得を試みる。
  2. Cookieがあれば [if(cookies != null && cookies.length>0) ]それを処理する。
  3. Cookieを(再)生成する。elseなしのifなので取得できれば再生成、できなければ新生成となる。
これで、果たして見事に動くようになった。 もー、ポインタなんて言われるとCとか思い出してビビりまくってしまうが、もう怖くないぞ! ・・・別に配列でなくても、nullなものを処理しようとするってことなんだろうが、配列って一度に複数の値を扱うから間違いも起こりやすいのだろう。

2002年4月29日

ページ先頭に戻る


Delphiを始める(4)プロジェクトファイルの正体

だがカエルガチョー本でとうとうつまづいたところがあった。「プロジェクトファイルはこう書きます」っていうけど・・・それ、どのウィンドウに書くのさ?
わからなくてほとんどやけくそで.dprというファイルをテキストエディタで開いてみた。

開けた。

カエルガチョー本の例に似た感じのコードが書いてある。しばしボーゼン・・・だが考えてみればjavaだって何だって初めはテキストファイルじゃないか。
そしてそれはBorlandのヘルプにちゃんと出ていた。メニューから「プロジェクト-ソースを表示」を選ぶと、Unitウィンドウと一緒のエディタウィンドウに出てくるのだ。
ヘルプには「このソースはBorlandのほうで自動的に調節するので、プログラマはいじってはなりません」とあるが、いじってみたらちゃんと動いた。
初めて3日目、よーやくBorland Delphiの使い方がわかってきた。まだ何をやろうという目的はないのだが、Windowsの鼻面をつかんでブイブイ引き回せるだけでも楽しい。

2002年4月13日

ページ先頭に戻る


Delphiを始める(3)カエルガチョー本にも案外ついていける

こうして勇気づけられたわたしは、ヤマネコ本とカエルガチョー本をそれぞれ、落ち着いてもういちどよく見てみた。
すると、ヤマネコ本の最初のほうのプログラムは、GUIではなくコマンドラインから実行するコンソールアプリであり、「新規作成」で「その他」からさらに「コンソールアプリケーション」を選べば、作れることがわかった。
さらに、「カエルガチョー本」は、180選+20選が全て、小さいが独立したアプリケーションで(エーアイ出版のサイトからたどって行けばこれらすべてのサンプルアプリのダウンロードができる)、Borland Delphiで作ったもので、意味がわからなくてもとにかくこの通りに打っていけばそれぞれ何かできるようだということがわかってきた。
よしよし。本はこれ以上買わなくても何かを習得することができそうだ。

2002年4月13日

ページ先頭に戻る


Delphiを始める(2)福音サイト

こりゃ「Borlandで初めてのDelphi」みたいな本を、今度の休みにでも買いに行くかと思うが、わたしは待てない女。
どこかで初心者のためにチュートリアルを公開してくれているところはないかな・・・・

あった。その名も「Delphi FAN」!

CDプレイヤーアプリケーションを作るというチュートリアルだ。初心者がいきなりハード制御かッ?!と思ったが、そこはちゃんと「難しそうな課題だが、実はとてもカンタンなのだヨ」と書いてある。
スクリーンショットをふんだんに使って、環境設定からファイルの保存のしかたまで、とても丁寧に説明してある。クリックひとつ違えず(たぶん違えてるぞそれわ)これに従っていくことにした。よし、一応できたぞ。
はじめてのDelphiアプリケーションをドキドキで実行してみる。CD-ROMドライブのフロントパネルが配置されたフォームが現れた。よし、これでCDを演・・・
気がついたことがある。それは、今とっさにDelphiを入れたこのデスクトップは、開発用ということでダンナ様が組んだマシンで、サウンドボードは入れてない・・・
あが。と思った。だが、テはあった。フロントパネルのイジェクトボタンをクリック。

ガチャコン、とCDトレイが出た。おおー!

あこがれのDelphiの初めての実行結果だった。これで大いに勇気づけられた。yuhtaさんどうもありがとうございました。

2002年4月13日

ページ先頭に戻る


Delphiを始める(1)闇夜に鉄砲

某アプリケーションのSDKのトライアル版をゲットした。VBかDelphiで動くという。VBでは動いた。だがDelphiではどうか?
Delphi。それはわたしにとって長年のあこがれだった。ギリシャ神話の香りのするその名。その本体がObject Pascalというもので、今話題のKylixはそのLinux版であるということを最近知った。
N88Basicで一行一行処理を書くことしかできなかったわたしの周りで、オタクな少年たちが「これからは構造型言語のパスカルだヨ」と「カル」にアクセントを置いてうそぶいていた、あの青春時代のせつない思い出がよみがえるような気がする。
そんなわたしを後目に、夫は会社で計器を動かすのに必要なんだヨと言ってフツーに使っている。そして2冊の本を持っている。

「Delphiクイックリファレンス」 Ray Lischner著、(株)オライリー・ジャパン発行
「Delphi6 プログラミングテクニック裏技180選+新機能20選」 金井利美男 著、エーアイ出版(株)発行

前者は、ヤマネコらしい変わった動物が表紙なので、「ヤマネコ本」と呼ぶことにした。
後者は、ガチョーらしきトリの背にカエルが乗って空を飛んでいるイラストが表紙だ。ガチョーがWindowsで、カエルがDelphiということなのか?・・・「カエルガチョー本」と呼ぶことにした(くどい)

Borland Delphi6をダウンロードしてきてインストールする。そして起動。
・・・・

2,3年前、初めてMS-Accessを立ち上げたときの、あの茫漠感と寂寥感が再び。なにせDelphiについてはなーんにも知らない。GUI開発ツールだからOKボタンとかラベルとかを適当にフォームに配置してプログラムがどうなるか見ていけばわかるんじゃないか、くらいに思っていたが。
Unit1って何・・・

2冊の本を見てみるが、program?library?dll?・・・GUIツール側のどの部分に相当するのかさっぱりわからない。
そりゃあんた、コードを一字も書いたことも読んだこともないヤツがいきなり「クイックリファレンス」と「裏技テクニック」の本で勉強しようったってムリ・・・

2002年4月13日

ページ先頭に戻る


Javaで久しぶりに思い知ったこと

 練習のために他人様のJavaのソースをまねして打っていたが、これをjavacするとエラーが出る。一番困ったのが、
このクラスはabstractクラスでなければなりません、ゆえに初期化することはできません」というのだ。
なければなりませんったって・・・interfaceは実装してるしスーパークラスを継承してるけど(すごいプログラムだな、他人様のだけど)、抽象クラスは知らないぞ。それにこれ自身が抽象って言われても・・・
だが他の雑魚エラーを整理し、メッセージをよく読んでみると、ああ〜わかった〜。
interfaceをimplementするってことは、そのinterfaceが持っているメソッドをとにかく全部実装しなければならない。中身は{}と空白でもいいから、名前借りるだけだから(悪徳商法の誘いみてえだな)・・・
そのつもりが、そういう「空白メソッドオンパレード」の中で、ひとつメソッド名のスペルミスをしていた。直したらちゃんとコンパイルできた。
機械には致命的でも、人間には単純なエラー、というのはこれまでもいくつも経験してきたがこれもそうだな。

2002年4月13日

ページ先頭に戻る


SQL文をかますプログラムの泣き所

なんでもないことですが、PerlにしろJavaにしろたぶんPHPでもrubyでも、SQLデータベースにアクセスするプログラムでは当然、中でSQL文を書いてかましますな。
その場合、また当然、そのSQL文は文字列として扱われますな。
すると、コード自体をデバッグしても、文字列についてはやはり当然ながらノーチェックですな。
ゆえにそれでCGIなどをかまそうとした場合、SQL文が間違っているとエラーになるわけで。もちろんそのためにSQLエラーを表示させるようにプログラムを書くべきでありますが、エラーメッセージがSyntax Error or Access Deniedなどと書かれるとついアクセス権問題に振り回されて実はスペルミスだったことに気づくまですごい苦労したとか。
ないですか?わたしだけ?!

2002年3月1日

ページ先頭に戻る


SolarisでのPopUpMenu

今まで書くのを忘れていたが、Javaの勉強は、ゼロからコードを書いていくワニ本の他に、Forte本、JBuilder本なども使ってやっている。
Forteの初心者本で、PopUpMenuを使う練習をした。ところがサンプルコードをそのまま書いて実行してみてもメニューが出てこない。同じコードをWindowsでコンパイルして実行するとちゃんと出る・・・実はこの本はWindows対応なのだ。UNIXじゃダメなこともあるのかな、とそのままにしておいた。
ところが、ワニ本でもPopUpMenuを使うプログラムが出てきた。だが避けたくはない。マウスでパネル上に線を書いたり、カット・コピー・ペーストなどの操作ができるようにする非常にためになりそうなサンプルだからだ。
てことはまーたWindowsでやれってかよ。ヤだよ。というわけでネットを訪ねて古きも新しきも探してみた。検索ワードSolaris, PopUpMenu。するとおや、
あるJava使いのお方のJava日記のページがヒットした。
見てみると、UNIXのマウスに右クリックを認識させる方法がバッチリ書いてある。
そこで、前できなかった、上のForte本のPopUpMenuのサンプルコードを開きそれを書き加えてみた。
まだできない。だがさらにわたしは前から、どうしてこのサンプルではイベントがMouseReleasedであってMousePressedでないのか疑問に思っていた。 上のお方の日記でもMousePressedにイベントを割り付けてある。
そこでMousePressedに割付けなおしてみた。
できるじゃん〜
「あでゅう」様とおっしゃるのでしょうか。どうもめるし〜めるし〜。近頃、トラブルをネットで解決法を見つけてシュートできることが多い。情報提供者のみなさまに感謝するとともに、わたしのトラブルも要するに「なにがなんだかよくわからないトラブル」から、より具体的なものになってきたのネとひそかに自負。

2002年2月12日

ページ先頭に戻る


苦労しましたJDBC

ワニ本も(練習問題があまりむづかしくなってきたので、心機一転後回し(威張るな)したこともあって)だいぶ進んでいよいよ「SQLデータベースとの接続の巻」になった。
そこに書かれたサンプルコードを実行するためには、JDBCドライバはてめえで使えるようにしておけ、とある。そりゃそうだろう。SQLにはMySQLを使うことにした。理由はPostgreSQLではJDBCドライバは自身のソースファイルの中にあり、コンパイル時にオプションをつけておかなければならないらしいのに対し、MySQLはあとから別個に、jarファイルの形でゲットして展開すればいいみたいだからだ。
これでまずBladeにMySQLをインストールする。詳細は別ページである。
次に、別にrootでアクセスしてもいいんだろうが、一応ヒラユーザnonikoにデータベースへのアクセス権を与えておく。ここでもいろいろ苦労したが、こうしたMySQL操作法は、今に「MySQLチャレンジ」というページを立ち上げる予定なので、そのときに詳述予定(ていうか教本見れば書いてあるんだけど)。
さて、問題はSQLに接続するJavaアプリでの、ドライバのURLの指定だ。御家庭ではどうしたってローカルホスト上での接続になる。その場合は、
jdbc:mysql://localhost/<データベース名>
と指定しなければならない。いくらローカルホストでも省略はまかりならぬということだ。あとスラッシュスラッシュを忘れてはならない。
実はワニ本ではPostgreSQLへの接続に際し、ローカルホスト上での接続ではホスト名は省略できるとある。それでMySQLでも省略したのだが、それが通用しなかったのだ。その場合、
No suitable driver
というエラーメッセージが出るので、てっきりドライバのインストール法や設置場所に問題があるのかと思っていたが・・・これがドライバの問題ではなくURLの書式の問題であることを書いておいてくれたのは、ある外人さんのページだった。たぶんこんな極東の島国の主婦の存在など空気中のウィルスほどにも感じないであろう外人さん、どうもありがとう。おかげさまでJavaでデータベースに接続する勉強が進行しそうだ。

2002年2月12日

ページ先頭に戻る


チラリズム

 図形などを表示させるJavaアプリで、表示させるオブジェクトを別のクラスファイルで作っておいて、あとはJBuilderでフォームを作ってここに呼び込んで表示させるようにした。だが、「いつ、つまり何のイベントで、このオブジェクトを呼び込むか?」
最初、thisにWindowOpenedのイベントを割り当てた・・・すると実行直後の一瞬だけオブジェクトが表示されすぐに消えてしまう。
結局、contentPaneに対してMouseClickedのイベントを割り当てることにした。実行すると何もないフォームが現れるが、つついてみるとオブジェクトが出てくるという。
 別のアプリでは、実行するだけではいつまで立っても何も表示されないが、マウスでウィンドウの大きさを(大小どっち方向でもいい)変えればオブジェクトが表示されるというのもあった。始めての実行時に偶然それをやったために表示されたが以後全然ダメで、どうしてさっきできたのができないの〜とさんざん悩んだのだが・・・たぶん一度ウィンドウの再描画をしなければならないというからくりなんだろうが、repaint()メソッドをどこに突っ込んでも自動更新はしてくれなかった。ゆえにこれを実行するには必ず一度マウスでウィンドウの大きさを変える必要が・・・

どれもこれもダサいアプリだが、まいっしょ。練習だし。

2002年2月12日

ページ先頭に戻る


ちょっとRubyに寄り道

今月号のUNIX USERがRuby特集だった。
そこで、さっそく、Javaを少しお休みして試してみる。「少し」というのは、
「新たにRuby本などを買うことをせず、UNIX USERの記事だけを、勉強しつくすか難しいので途中で挫折するかするまで」である。
Rubyのプログラムは同誌付属CDにソースファイルがあったが、実はなんともう一つの俺バイブル「SUN World」付属の、NSUGお手製パッケージダイジェストにSparc用バイナリがあった!
使わせていただかない手はない(会員だし)。ズバーッと(CD-ROMを)入れてピュ〜とインストーラが立ち上がってRubyってのにチェックいれたらあらまあ全行程15秒で使用可能!いーねやっぱりSparcマシンは。さすがにもうインストールそのもので一喜一憂する段階は卒業しましたものホーホホホ(生意気)。
さあ最初の起動です。記事に示されたとおりに、コマンドライン上でスクリプトを直接起動する。

ruby -e `print "Hello, world!\n`

・・・「エラーです。printというコマンドは・・・」

え。
おお。記事の印刷がちっちゃくてよく見えないまま(老眼か)なんとバッククォーテーションを打っていた。
わざわざめんどくさいことを・・・この前Perlでdateとか呼び出すのに使ったのを曲解していたんだろうな・・・
シングルクォーテーションに直して、ようやくちゃんと表示できた。このように、わたしとRubyの出会いもいきなりヘボい初対面に終わった。
そのあとは、この「純オブジェクト指向言語」の発想のすごさのようなものに感動しながらいくつかの小さなプログラムを、お手本をまねて打ってお手本通りの結果が得られたと喜んだりしていたが、3部構成の第3部でいきなりむずかしくなって予想どおりJavaに戻ることができた。Javaのほうが落ち着いたら(落ち着くのか)また初心者本でも買って勉強しますんで。

2002年1月22日

ページ先頭に戻る


ファイルリストを作る(4)でもホントにできてんのかなあ〜ヘヘヘ

こうしてリストアップされたファイルについて、容量を足しあわせてやればいいのだが・・・サブディレクトリごとの計算値も出すという課題が残っている。
それにはこんな方法を考えた。
ファイルツリーを末端から見ていって(ちゃんとディレクトリとファイルでソートしたから配列の最後の要素ほどツリーの末端ということになるヨ)、そのファイルの親ディレクトリが前のファイルの親ディレクトリと同じうちは、fflengthという変数にファイル容量を足しあわせて行って、
親ディレクトリ名が代わったところで、
それまで持っていたfflengthの容量を、総容量を得るためのtflengthに渡す。
fflengthを初期化する。
今度は新しい親ディレクトリの名前と、次のファイルの親ディレクトリの名前を比べる。
・・・これは、実はスレッド掲示板でファイルツリーを構成するのと同じ考え方だ。だが向こうはルール無用のPerl、こっちはJavaだからそのままはいかない。もっともこっちにはgetParent()というメソッドで親ディレクトリ名は取得できる。
これでどうにかそれらしい結果は出た。もっともホントに数値的に正しいのかどうかはまだわからないー。でもいろいろ勉強なったしいいか。

全体のコードはこれです。書き方ちげーよと思った方、noniko@mail.goo.ne.jpまでアドバイスください〜。

2002年1月22日

ページ先頭に戻る


ファイルリストを作る(3)成長する配列

それには、同じ方法で、ファイルリストを引数につけてやることで、最終的にその配列に全ファイル名がおさまってくれるかどうか見れば、この方法が妥当かどうかわかりやすいだろう。バッファ馬鹿一代の面目躍如たるところである(ホントか)
だがこれはもっと難しそうだ。Perlと違ってJavaは配列の大きさを定義しなければならないし、配列と配列を足しあわせて大きい配列を作るなんて、できるのかな?今のところはそのやり方を知らない。
だが日曜の夜寝る前におトイレで気がついた(寝るときもおフロもおトイレもこのことばかり考えている)。
配列も引数にして繰り越してやれば。
そしてメソッド内で、新たな配列を作る。
この配列は繰り越してきた配列よりファイル数ぶんだけ大きな要素数で定義され、繰り越してきた配列の中身を全部入れて、されに今取得したディレクトリ内のファイル名を追加して、そいつを再帰メソッドに繰り越してやるのだ!
具体的に書くと、
public static string[] listdir(String dirname, String[] filelist)
というメソッド。今度は戻り値として配列を返すのだ。
メソッドの中で
String[] currentlist= new String[ filelist.length+今回取得したファイルの数]
ディレクトリの数は入れないヨ。
ということは、一度今取得したディレクトリ内の構成要素をファイルと(サブ)ディレクトリに分けて、数を数えておかなければならない。
このcurrentlist配列にfilelistの要素全部を入れておく。
それから今取得したディレクトリ内の構成要素を1個1個、ファイルだったらcurrentlistに入れ、ディレクトリだったら
currentlist=listdir(そのディレクトリのフルパス、filelist)
と条件分岐する。全部処理し終わったら最後に
return currentlist;
で、終わる。
一方main関数のほうでは、まず
String[] filelist=new filelist[1]
Perlと違って、要素ゼロの配列って作れないんだもーん。この0番目の要素には適当に文字を入れておく。「directory+args[0]+":"」
みたいなのがいいかも。で、
String[] finallist= listdir(args[0], filelist)
と渡してやる。こうして得たfinallistの要素をmain関数の中で書き出して見ると・・・
おお!できた!メソッドの中でファイルとサブディレクトリをわけたから形式もきれいだ!

2002年1月22日

ページ先頭に戻る


ファイルリストを作る(2)再帰でも繰り越すもの

まず、ディレクトリ内の全ファイル名をとにかく表示させるだけの方法で再帰を試した。
public static void listdir( String dirname)
と宣言するメソッドだ。得たファイル名はさっさと
System.out.println(dirname+"/"+listarray[i])
で表示させる。もしディレクトリだったら、
listdir(dirname+"/"+listarray[i])
で再帰さしてやる。これで、表示はできた。
だが問題はファイル容量の合計を出さなければならないということだ。どうする。相当悩んだ。
なぜなら、このメソッドの中でたとえば
long flength
を定義してそこにディレクトリ内のファイル容量を計算して入れるとする。
だが再帰したメソッドの中でこいつは再び定義しなおされてしまう。今までの計算結果はチャラになってしまうのだ・・・
そこで半信半疑やってみたことがある。それは、繰り越す容量を引数としてメソッドにつけてやるということだ 。
mainメソッドの中で
long tflength=0
と初期化しておいて、
public static void listdir( String dirname, long tflength)
とやるのだ。
で、各ディレクトリ内のファイル容量についてはメソッド内で新しく
fflength
などの名前で定義し、足しあわせる。で、
tflength=tflength+fflength
とそのぶんを加えてやって、
listdir(dirname+"/"+listarray[i], tflength )
と再帰させてやると、tflengthは初期化されずに繰り越せるのではないか?
テストケースでやってみたが・・・とにかくエラーにはならないで、tflengthがだんだん増える形で出力される。 でもホントにできたかどうか?数字だけじゃわからない〜

2002年1月22日

ページ先頭に戻る


ファイルリストを作る(1)再起不能のワケ

これもよくありそうな問題だが、あるディレクトリのファイルの容量を計算するプログラムを作りたい。
だが、 UNIXでは、任意のディレクトリの容量はそのサブディレクトリの容量までは加味されないようなのだ。
ゆえに、ディレクトリの中身を調べ、そこにサブディレクトリがあれば、それをまた調べなければならない。
すなわち、ディレクトリの中のファイルオブジェクトとその容量を調べて足し合わせるメソッド中で、ファイルオブジェクトの中にディレクトリがあったらそれに対して自分自身を再帰的に呼び出すようにするのだ。
それを作ってみたらどーもうまくいかない。だが調べているうちにそれは再帰以前の問題であることがわかった。Javaではディレクトリの中のファイルを調べるのに、

File d = new File(dirname);

と、ディレクトリ名dirnameからファイルオブジェクトdを作り、これに対して

String[] listarray= dir.list();

とやって、ディレクトリ内のファイル、サブディレクトリの名前の配列を得る。
だが、このとき出てくるファイル名のリストは全部ファイル名だけ、つまり相対パスだから、それをまたファイルオブジェクト化してディレクトリかどうか調べたり容量を調べたり次のメソッドの引数として使ったりするには、「フルパス」に立て直さなければならない、ということに気づかなかった。
つまり、それらの短い名前を持つファイル名は存在しないことにされてしまい、処理が全然すすまなかったのだ。
ファイル名を全部dirname+"/"+listarray[i] に直すと、ちゃんとループしてくれた。
ちゃんとプログラムに、isexist()などで、それらのファイルの有無を調べる措置を付加しておけば長く悩むこともなかったんだろうが・・・もちろん、そういう措置はプログラムの本筋ができてからとか思っていたワケ。急がば回れだな。

2002年1月22日

ページ先頭に戻る


バッファ馬鹿一代

ファイルの入出力の練習。指定したファイルの最初の10行を書き出す・・・これは楽勝だ。
だが、最後の10行を書き出す・・・これはちょっとめんどくさいゾと思った。
まず、ファイルの内容を一行ずつ読むのには、readLine()メソッドが使える。そこで、int linecountという変数を用意して、一行ずつ読むたびにインクリメって行けば、ファイルの行数が得られる。そこでファイルの行数分の配列を用意する(大きさ不定の配列は、Javaでは用意できないのだ)。文字列を要素とするその配列に、もう一度readLine()で一行ずつ読んでいって、一行分の文字を一文字列として入れていく。で、配列の(要素数-10)番目から最後までの要素を書き出せば・・・
なんとかできた。だがそれを夫に話すと、Javaはほとんどやっていない夫に「それってEOFから逆読みしてきゃよかったんじゃないの」と言われた。

キャ〜

そういえばワニ本でもいろんなプログラム例でさかんにEOFを探していたっけ・・・「ま、常々おまえはアルゴリズムが弱いな」と言われた。
だが、いつもこんなふうなのだ。のに子ソートも、のに子フィボナッチも。あと、Perlでいろいろなものを作るときなどもっとひどい・・・とにかく配列を作る。そこにとりあえずデータをたたき込む。それからゆっくりそこから要素を取り出して吟味する・・・
そう。奥様は「これで安心」が大好き。「とにかくこの分は配列に取り分けてしまえばいいわ」。
バッファ馬鹿である。「ま、いんじゃないの。商売でプログラム書いてるんじゃないし、最近のパソコンのスペックは十分だから」と夫に言ってもらったが・・・

2002年1月10日

ページ先頭に戻る


セミコロンのエラーと思いきや

ワニ本はさらに難しくなり、もはや写経の心境である。もし難解なエラーメッセージが出たらどうしようと思いながらコンパイルしてみる。
すると 「セミコロンがありません」というメッセージ。そのあとにはたいてい連鎖反応的に「カッコがありません」「型がありません」「文がありません」「クラスが見つかりません」が続く。だからこのセミコロン問題さえ片づけば、後のかなりの数のエラーが解消できるはずなのだ・・・けど、どの文にも、セミコロンはついてるはずなのに?ボーダイなソースの一行一行を何度調べても・・・
実は違った。ある場所で、クラスのメンバ変数を表すため

ClassName.Membername

と表記すべきところを、このピリオドを一個落としていたのだ。そこで ClassnameMembername と二つの中途半端な文として扱われ、セミコロンがない、カッコがない・・・ということになったのだ。いろんなエラーのパターンを経験値にしなければならないと思った。

2001年12月30日

ページ先頭に戻る


地獄までセミコロン1個

ワニ本、基礎を理解するという1章はわりとわかった感じだが、第2章でいきなりわからなくなりはじめた。
2ページにもわたるプログラムにいきなり突入され、サルのように打ってみたが、コンパイルできるし結果は出るのだが期待していたものと違う。
そこでサンプルファイルをオライリーのサイトからダウンロードさせてもらい、今自分が打ったものと比べてみた。
お手本ファイルには注釈がたくさん入っていて比べにくいので、それらをはずしていったらなんとこっちもおかしくなった。
それもコンパイルできないなどという全くダメな状態だったらカッコをひとつ間違って消したなどが考えられるが、わたしが打った方の中途半端な結果と全く同じ中途で全く同じ半端だ。
原因はやがてわかった。このプログラムには「空のループ」というものがある。

for(条件)  //ここは空のループです;

みたいなふうに注釈つきで書かれていた。この部分で、最後の;というのを、注釈とともに消してしまっていたのだ。
Javaでは(Perlでもだ)複数行にまたがらない限り {} を使わない。だからわからなかったのだ。
空のループは、どうやら「配列みたいなものの要素の一番最後を得るために作業を何もしないで要素番号だけ送る」みたいな意味があるようだ(詳しくは実際に本をお読みください)。

for(条件);

としたところ、期待通りの結果が得られた。くわばらくわばら。

2001年12月30日

ページ先頭に戻る


のに子式フィボナッチ

有名な「フィボナッチ数列」。q(n)=q(n-1)+q(n-2)、ただしq(0)=q(1)=1というものだ。最初の20個の要素を表示してみる。
これものに子オリジナルっていうか自分の頭だけで考えてみる。配列を使ってみよう。
だが、最初「文がありません」というエラーが出た。なんだろう?よく調べると原因は、main関数の
中で配列を宣言していたことだ。配列はクラスのトップで宣言しておいて、mainでそれを使うようにしたらうまく行った。
メソッドfib(int x)中で、配列に要素20個を全部計算して入れておいて、呼び出されたときのxに応じたftable[x]を返す。
mainでは、i=0から19まで、fib(i)をprintする。
この方法で、やっとできた

2001年12月30日

ページ先頭に戻る


のに子式ソート

任意の数値配列を小さい順に並べる「ソート」プログラム。本にはとても洗練された方法が書いてあって、どういうしくみなのか紙と鉛筆で10分以上考えなければならなかった。わたしにはこーいう発想はできない。だったら自分流にやるとしたらどうするか、考えてみた。

7つの整数を並べ替えることにする。
まず、オリジナルの大きさ7の配列origtableと、それを並べ変えて置く同じ大きさの配列sorttableを用意する。

origtable=[5, 2, 3, 7, 9, 8, 6]
sorttable=[ , , , , , , , ]

origtableから最初の数を持ってきて、まずsorttableの第0番目に置く。

sorttable=[5, , , , , , , ]

origtableから次の数を持ってくる。sorttableの第0番めの数とくらべる。
origtableの数のほうが大きければ、そのままsorttableの後におく。
そうでなければ、sorttableの第0番目をひとつ後ろにずらし、origtableの数を今のsorttableの位置に置く。

sorttable=[2,5, , , , , , ]

・・・
origtableからi番目の数を持ってくると、
sorttableにはi-1個の数が並んでいる。この0番目からi-1番目までの数を試す。
もし、origtable[i]がsorttable[j]より小さければ、
sorttable[i-1]番目からsorttable[j]までを一つずつ後ろにずらし、sorttable[j]の位置にorigtable[i]を入れる。
i-1番目まで試して小さくなければ、sorttable[i]の位置にorigtable[i]を入れる。
これでsorttable[x]を戻り値にする。

1時間かかったができた!メモリも時間も食うだろうが、のに子的思考回路に沿ったやり方だ。

2001年12月30日

ページ先頭に戻る


ワニの穴にダイブ

「Java超入門(Jamsa,K著、アスキー出版局発行)」をなんとか終えたわたしは、次の段階に進もうと考えた。そこでも少しレベルが高く、しかし高すぎず、目的と結果の是非がわたしにもわかるようなサンプルプログラムがいくつもあるような本をいろいろ探した結果、やはりオライリーの本となった。
「Javaプログラムクイックリファレンス」(Flanagan,D著、原題JAVA Examples In A Nutschell)というものである。表紙の動物はワニだ。ハナを上に向けてなんとなくラブリーだ。こいつが各章の最初にも控えめに顔を出して、それを見ると何か励まされたような気がする。
そこで、前者をジャムサ本、後者をワニ本と呼ぶことにした(いいのか)
ジャムサ本ではブラウザに結果を表示させるアプレットが中心だったが、ワニ本はほとんどスタンドアロンプログラムである。
各章には練習問題がついているが、「初めてのPerl」のように解答がついていない。それが少し不安だ・・・要するに、結果が出ればそれで正解、というのだろうが・・・でも始めることにした。このおびただしい量で結構むづかしそうな練習問題を「ワニの穴」と呼ぶことにして・・・

2001年12月30日

ページ先頭に戻る