ラベル mumble の投稿を表示しています。 すべての投稿を表示
ラベル mumble の投稿を表示しています。 すべての投稿を表示

2009/05/10

ソースコードのハイライト-業務連絡

久しぶりにサンプルソースを書いていて、気になりだしたのがソースのハイライト・ツール。

これまでgoogle-code-prettifyを利用していたわけですが、VBのソースのハイライトが美しくないので以前から気になってはいたのですよ。

どれどれと思って本家をのぞいてみたら、だいぶバージョンアップされていました。「早速、使ってみよう」と思って、javascriptやcssのアップロード先として便利に使っていたGoogleのPageCreatorに行ってみたら…。

えーっ! Σ(゚Д゚;≡;゚д゚)

Google Page Creator is no longer accepting new sign-ups.

お前もか、ブルータス(←GoogleNotebook愛好家)。

PageCreatorの類似品としてgにはSiteができたもんねー。SiteはSiteで結構便利機能満載なんですが、プレーンなjavascriptとかのアップロードはできないんですねよね。…多分、コンテンツは作らないのに、データだけおいて、外から呼びだしている私みたいな輩がいるから?(´・ω・`)

というわけで現在ログインはできても、更新作業ができないPageCreator。立ち退きムード満載ですね。

他にゆくあてもないので、ソース類は諦めてガジェットに突っ込むことにしました。

そしてついでなので思い切ってSyntax Highlighterへ浮気することにしました。

なぜなら行番号を出すのも簡単で、「view plane」のモードまであって実に高機能だから。

でもちょっと、「ついで」にしては思い切りすぎだったかな。(ーoー)y~~~

言語ごとにclassをつけていくのが面倒くさかったよ。VB系にC#、ColdFusionにJavaFXにコマンド系。正直、どの言語を当てればOKなのかわからないものもちらほらあったりして、その点はprettyprintはテキトーすぎてラクチンでしたねぇ。

追記:<br />タグ問題

Syntax Highlighterを導入したら、私は今後もう使わないかも…なマクロのサンプルソース、「EmEditorのマクロ 選択範囲へ改行タグ」で、ダブルクオーテーションに囲まれた<br />がどーしても表示でず、改行されてしまった(リンク先、サンプルソースの23行目とか30行目)。

「google-code-prettifyのときはヘーキだったのにー?!!コードとしてのbrで、しかもタグは16進数も使っているのに改行されちまうのさー!?」とモヤモヤとしていたら。

本家のこの記事みてなんとなーくわかっちゃった。ウチの場合、改行キー等、全部タグは手打ち(私の場合エディタのマクロ…)なので、むしろdp.SyntaxHighlighter.BloggerMode();の1行は不要なのですよ。なので、この一文をコメントアウト。するとどうやらうまくいったような気がします。…それとも他で影響でるかな?(ΦωΦ) 

2008/12/18

Bush's Boot Camp

このニュースは凄いな…、と思っていたら。このニュースのパロディ、靴投げゲームが各国版であれこれでているみたいですね。

マトリックス映像がツボだったので、Wiredあたりのまとめ記事をご紹介しておきましょうかね。→ブッシュ靴投げ事件、ゲームやアニメで大人気:「マトリックス・ブッシュ」も


なんというか、ゲームのストーリーは靴を避けるというストーリーのようですが。靴が当たってもスカッとするところが良いのではないでしょうか。

…それにしても、よくブッシュもあのスピードで咄嗟に避けましたよね。二足も。フィットネスばかりやっているだけのことはありますね…。

2008/09/04

VM in VM / POWERS OF TEN

小飼弾さんのところで、VM in VMの記事を読みました。

OS X の VMWare上の、 Windows XPに入れた Virtual Box 上で Ubuntu を走らせた図があり、ちょっとこれにはウットリ。

合わせ鏡で、鏡の中に鏡が映りこみ、その中にまた鏡があって…、の不思議さに近いイメージですよね(もっとも合わせ鏡は有限みたいですが)。

宇宙の外側にはまた宇宙があって、その外側には…、とか。ダレダーレみたいな感じで、ミクロの世界にもやっぱり「世界」があって、その「世界」をまた「宇宙」にしている「世界」があって…とか。

昔からとりとめもなく、そういうことをよく想像していたので、つい、VM in VMのキャプチャ画像にウットリ、仮想化ってこういうこともできちゃうんだ…、とココロをざわつかせていたわけです。すると、そんな私の様子をみていた知人が「POWERS OF TEN」という映像を紹介してくれました。タイムリーすぎて、なんだか個人的にめちゃめちゃクリーンヒット。ステキすぎるよ、この映像。(*´艸`*)

Chrome雑感

Chrome、やっぱりなんだか面白いですねぇ…、このブラウザ。じわじわとその面白さを感じてきました。

Ω Ω Ω

ChromeのUIを見た瞬間、まず「表示領域が広い!」と思ったわけですが、これにはブラウザ基盤な思惑、伏線を感じますよね。Webサイトベースで作業をするなら、表示領域こそが大きい方がいいに決まっていますから。Googleのウェブサービスを思い浮かべた場合、機能はすべてブラウザの表示領域の中にあり、ブラウザ自身の機能はそこまでゴテゴテとは不要──そういう割り切りをこのレイアウトからは感じました。

それに[プロセスがタブごとに独立]×[アプリケーションのショートカット作成]あたりは、Webサイト← →デスクトップの乗り入れっぽい感じ、ですかね???

[アプリケーションのショートカット作成]からChromeを起動すると、まるでデストップアプリであるかのようにアドレスバーを見せないレイアウトからもその辺の意図を感じますし、それに加えて[プロセスがタブごとに独立]していることも考え合わせると、殆どデスクトップアプリの座を狙っている…、としか言いようがないような感じですよね。そもそもGoogle Gearsとも統合されているみたいですし…。なんだか準備万端?このところAIRやJavaFXがブラウザから飛び出してきたわけですが、やっぱりそういう流れを思いっきり意識しているんだなぁ、と思いました。

ちなみにChromeはV8 JavaScriptあたりが目玉なんだろうと思うわけですが、これは今後もGoogleはしばらくは今みたいな感じでJavaScript大活躍な路線でいく、ということなんでしょうね。

2008/06/02

FAT32 ファイル数制限のワナ

何十万件という画像ファイルをを外付けHDDへリネームしながらコピーする──というバッチ処理をしていたわけなのですが、途中で止まる…。

うーわー、私どっかで書き間違えた?

と思ってリネーム・ツールのロジックを調べるわけですが、理屈は通っていて、どうも原因がわからない。というわけで、デバッグモードでリトライ。

再び停止。しかも停止するのはどうやらマッタク同じ画像ファイルのコピー作業ときたものです。

コピー元の画像になんらかの制限がかかっているようでもないし、コピー先のフォルダもちゃんと存在している。どこがおかしいんだろう、と思って、とりあえず

  • 手作業でそのファイルをリネームしてコピー先のディレクトリにコピーする→エラー。
  • 違うディレクトリにコピーするとコピー可。
  • 結論:どうやらロジックのミスではない。

むむむ、と思って、外付けHDDのファイルフォーマットをみると、あろうことかFAT32。FAT32ってなにかファイル数とか制限なかったっけ?と思って、拒否してくるディレクトリのファイル数を見てみると21,844件。…あれ?

FAT32のファイル制限数ってもう少しなかったっけ?──と思ってMSサイトへとんでみると、以下は MS-DOS の 8.3 形式に準拠するファイル名をつけた場合に、ディレクトリ内に保存できるファイル数ですということで、65,534件の数字が出ている。

「でも私のつけているファイル名は8.3形式のファイル名ではないなぁ…」と思って更にヘルプを読み進めると、ファイル名が 13 文字以上の場合は、さらにもう 1 つディレクトリ エントリが使用とあって、その下に実際のファイル名と利用されるディレクトリエントリの一覧がある。65,534=21,844×3だし、原因はこれか…。

というわけで、なんだか8.3形式(しかも大文字で)のワナにハマった話でした。うっかり忘れそうなのでUP。

2008/05/24

MSのWebサービス

23日にOffice Live Workspaceの日本語ベータ版が公開されたみたいですね。早速使っている方とかいるのでしょうか。使用感はどうなんでしょう(今のところ自ら人柱になる気なし。すいません)。

MSっ子と言っているわりに、Docsに対抗する(?)この話題を完全にスルーしていました。先週MS絡みのイベントへ行ったので、かろうじで意識していたくらいの感じです。「私ってMSのLive ID(!!ここにえびはらくんがいるとは…)絡みののネタに疎いんだなー」という自覚をもったのも、ごくごく最近のことですし…。そのことに気づかないほど、これまで完全にスルーしていたわけですね。

というわけで、Live IDは会社のアドレスでアカウントを取得したことがあるような気がするものの、「気がする」というコトバが端的にあらわしているように、マッタク使いこなしていない感じです。MS的には、Googleをヨコににらみつつ、多分、この辺に力を入れてきているであろうに、とことん無関心な私。うはは。ダメな感じですねー。私が…、というより、MSっ子でさえも、そんな感じにさせてしまっているWeb関連でのMSが。だからこそのYahoo買収騒動とかなんでしょうけれど。

そもそもWeb絡みでは、個人的にはMSとはビギナー時代からかなり無縁な感じでした。IE自体使うことが稀ですからね。VSユーザーではありますが本業ではWinフォームばかりを相手にしていますので、IEを使う必然もなく、ブラウザは自分の好みで使えたわけですね。というわけで、IE以外のブラウザとはなにかと相性の悪かったMSサイトへ行くのは億劫で、自然とWeb周りではMSのサービスは避けていたわけです。

一方、Googleの方との付き合いは検索に始まり、メールもgmail、DocsやNoteなどを愛用、ブログまでついでにBloggerという状況です。gmailアカウントを一旦とってしまうと、他のGoogleのサービスのアカウント取得も敷居が低いですから、興味本位でごちゃごちゃ試している間に、日常ツールの一つとして気がつけば使いまわしているわけですね。結果として、わざわざMSでアカウントをとってどうこうする気にもならなずに、第二の「悪の帝国2.0」が提供してくる環境に、すっかり入り浸りなGoogleライフが展開されてゆくという次第(…これはこれでヤバいっス)。

「ExcelラブならSpreadSheetsじゃなくて、Office Live Workspaceへ乗り換えろ!」と突っ込まれそうですが、既にDocsを使っている身としては、Excelにラブはあっても(MS信者ではないですが、Excelには苦いも辛いも含めて自分の中にラブがあることは確か)、正直なところかなりビミョーだなと。Office製品群を抱えているMS的にはSoftware Plus Serviceというスタンスをとらざるを得ないのでしょうが、Bookをダイナミックに加工したいときには、ローカル環境のExcelで加工してからSpreadSheetsへアップロードすればいいだけの話なので、SpreadSheetsユーザーとしては特に不足を感じていないわけです。VBAこそ使えませんが、SpreadSheetsではExcelで仕込んだ関数なども一応使えますしね。

イシカワさんには「MSっ子ならば、ストイックにMSを極めて」とからかわれていますが、こちらとしては結果としてMS製品に囲まれていただけで、なにかとMSを叩く人々の存在に対するからかい半分・自虐半分くらいで、MSっ子と云っているだけですので。実質はスタンドアローン的にはMS、Web関連はGoogle、といった単なる新旧「悪の帝国」使いです。あしからず。

とはいえ、迫っているビル・ゲイツの第一線の引退には、一抹の寂しさも感じています(この辺の心情は、MSっ子?)。ビル・ゲイツというギーク率いるMSが、なにかと巨人扱いされて、後続のギークたちにやたらと目の敵にされていた時代。これはこれで結構いい時代だったんじゃないかな?とも思いますし。これだけ目の敵にされる「巨人」も、なかなか今後は出づらいんじゃないかという気もしますしね(Googleもいまや巨人ですけど、気がつくと「隣人」みたいなキャラですからね…)。まーアンチMSの方々がどう思われているのかは知りませんが、「アンチMS!!」と騒いでいた時代はそれはそれで、巨人の姿がハッキリとしていて、結構楽しくはなかったですか?

2008/05/07

CurrentProject.Connectionの謎

再びAccessVBA教本ネタから。今回はADOの接続部分についてです。

Dim cn As ADODB.Connection
Dim rst As ADODB.Recordset

Set cn = CurrentProject.Connection
Set rst = New ADODB.Recordset
rst.Open "SELECT * FROM TB_ログ ORDER BY ログID", cn, adOpenForwardOnly, adLockReadOnly
Do Until rst.EOF
    rst.MoveNext
Loop
rst.Close
cn.Close

Set rst = Nothing
Set cn = Nothing

なんだかこのサンプルソースを見ていて違和感を感じたわけですね。違和感の部分はConnectionで、オブジェクト変数cnについて注目してください。まず、

Set cn = CurrentProject.Connection

自分自身の接続のインスタンスをSetでcnに渡している──この部分はいいでしょう。既にmdbファイルという自分自身は実体化しているわけですから、改めてNewして、インスタンスを生成する必要性は感じません。

さらにいうならば、CurrentProject──自分自身のことですから、既に接続がOpenされ済みとみなしていいわけで、改めて接続をOpenする必要がないという理屈もナットクできます。

そういう解釈で、上記ソースを眺めていると、Loopの後、

cn.Close

に違和感を感じるわけです。OpenしていないのにCloseしている、という部分で「あれ?」と思って立ち止まったわけですが、Openしていない理由(=CuurentProjectの接続だから)を考えると、CurrentProjectなのに、cn.Closeしちゃっていいいのだろうか?──という疑問も沸いてくるわけです。

CurrentProjectなのだから、CloseせずにそのままSet cn = Nothingするものだと予測しながらソースを読んでいたのに、Closeする必要があるというのはどういうことなんだろう(SetでNothingすること自体には疑問は持っていません。Setはメモリアドレスの代入にすぎませんから、「オブジェクト変数cnに入ったメモリアドレスをNothingするんだろうなぁ」というくらいのものです)。

過去の自分のソースをみても、CurrentProject.Connectionでセットされたオブジェクト変数は皆ちゃんとCloseしているので、教本サンプルソースのミスというわけでもなさそうです(証拠のソース。ちなみにこれを書いていたときは踏襲元も思い出せないくらいのはるか過去からの踏襲/慣習で、なーんにも考えていなかったんです)。

ちなみにmdbが複数個存在していて、別のmdbからもうひとつのmdbの接続するときや、VB6.0からAccessへADO接続する際には、

Dim cn As ADODB.Connection
Set cn = New ADODB.Connection
cn.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Password='';User ID=admin;Data Source=" & MDB_PATH
cn.Open

で接続して(MDB_PATHは接続したいMDBのパスの入った変数だとします)

cn.Close
Set cn=Nothing

で終了するわけです。OpenとCloseをセットで使っていますし、この記述に対する疑問は特にはありません。

問題なのはCurrentProjectの接続です。Openせずに、Closeする。Openしない理由は予測できるとして、接続をCloseしてもCurrentProjectに影響しないAccessの接続って一体、どーなっているんだ?──と思って、今回改めてじっくりとヘルプを調べてみました。

すると、Connection プロパティのメモに

Connection プロパティは、実際にはアクティブなデータベースに対する ActiveX データ オブジェクト (ADO) 接続のコピーへの参照を返します。このため、Close メソッドを適用したり、Connection オブジェクトのメソッドやプロパティを使って接続を変更しようとしても、カレント データベースとの接続を保持する Access の実際の接続オブジェクトに影響を与えることはありません。

と書いているではありませんか。

接続のコピー!!

そうだったのかー。

CurrentProjectの一意の接続そのものではなく、その複製を受け渡していただけなんですね。しかもおそらく接続をOpenしたままでの複製です。だからOpenせずに、CloseしてもOKなんですね。「複製の受け渡しとは安全設計なんだなぁ、そもそもConnectionプロパティはReadOnlyだし、かなり用心部深いよね。でも考えてみればここまで用心するのも、道理といえば道理だな」──と一人でナットクしつつ、すっかり習慣化して、いまやとくに疑問にも思わずスルーしていた自分に打ちのめされました。足元のこと、わかってないわ…。

2008/05/06

VBAのわかりにくさ

故あってAccessVBAの基礎編ネタを見直しいるのですが…。改めてAccess単体で見直すと、わっっっかりにくいですねぇ、やっぱり。

Access的にはユーザーに優しくするために色々なことを「隠蔽」しているのでしょうが、「隠蔽」しているが故に、「実はこれもこれも根っこは一緒なんだよねー」という原則ルールが見えづらい。

私の場合、クラスを理解するまで、いろいろな事が「謎」でした。VB.NET(VS2003)へ移行してから初めて、それまで「お作法」として捉えていたSetなんかの意味もようやくナットク、色々なことが一気にスッキリ、シンプルに見えてきたんですね。

そんなこんなでVBAユーザーからスタートしている自分を振り返ってみると、VBAでは「クラス」を隠蔽しているから、VBAからはじめるユーザーはいろいろな事がわかりづらいだろうな、と思うわけです。

たとえば他のクラスモジュール(Accessの場合、FormやReportとかしかありませんが)や標準モジュールから開いているフォームを操作したいときに、

Forms!フォーム名!コントロール名

とか

Form("フォーム名").Controls("コントロール名")

とかで突然表現しちゃうのってどーなのヨ?

Accessだって、Formクラスを継承して、新しいフォームクラスをユーザーが定義して、インスタンス生成をいるのに過ぎないだろうに、その辺のあれこれが、VBAの場合、すべて隠蔽されちゃっているわけです(これはVS2005にも当てはまりますね。私はVS2003をいじって、「Formって、Formクラスを継承したこーゆークラスを定義していたってコトだったのか」と、とても腑に落ちたのですが、2005からはVB6.0ライクになってこの辺が隠蔽されるようになりましたからねー…)。

Accessの場合、FormやReportオブジェクトについては、暗黙のインスタンスの生成をAccess側で勝手にやってしまっているのでしょうが、VBAがスタート地点で、コード先にありきだと、この辺が見えてこなくて、混乱の元になっていくんですよね。

自分を振り返ってみても、制御構造類などは見ればわかるものはいいですが、「こう書けばこう動くらしい」というみようみまねで書いていたオブジェクト変数の類は、長らく一種の不思議ボックス状態でした。あわせてSetステートメントもわかりづらい「呪文」でしたね。

DAOやADOなどでSetを使うこと──特にRecordsetなどの、自分でNewと書いているSetのイメージは、何度となく書いているうちに、自分なりにイメージは形成されてはいました。とはいえ、その「理解」も、今思えば、「New」の部分の「インスタンスが生成される」という感覚・イメージの部分だけで、Setの「メモリアドレスをオブジェクト変数に代入している」という役割の部分は、わかっていなかったわけですが…(この辺、我ながらホントに大混乱/未整理状態ですよねー。こんな状態でよく書いていたなー…)。

というわけで「お作法的」にしか飲み込めていなかった私にとって、かなりビミョーだったのが、NewをしないSetステートメント の存在です。Access単体で使うADOで云うならばCurrentProjectだとか。既に開いているFormやReportなどもそうですね。

Dim frmF_001 As Form
Set frmF_001 = Forms!F_001

frmF_001.txtData = "01"

Set frmF_001 = Nothing

というようなオブジェクト変数へ参照させる書き方は、当初、躓いていました。

F_001が開いたタイミングで「暗黙のうちにインスタンスが生成されている」とは明確に考えておらず、「Setステートメントなのに、なんでNewしないんだろ…?」と不思議だったわけです。いろいろな事が悲しくなるくらい、つながって見えていませんでした。

まーそれでも間違った書き方をしていればデバッグでエラーが出るので、デバッグ機能にダメ出しをくらい数をこなしているうちに、「ダメな理由をぼんやりイメージ/理屈を考える」積み重ね、Recordset等で書いているNewとの差を考えてみた結果、「mdbやフォームが既に開いているからには、CurrentProjectやFormなんかは、新しくNewしちゃいけないんだろうな」という感覚程度ならありましたけどね。

当然、継承関係も明確にはわかっていませんでしたので、

Dim frmF_001 As Form_F_001
Set frmF_001 = Forms!F_001

frmF_001.txtData = "01"

Set frmF_001 = Nothing

こうも書けるカラクリもイマヒトツわかっていませんでした(「Form_F_001」という型は、インテリセンス機能で出てくるので、そういう型が存在していること自体は、Accessをいじっているうちにわかるわけです)。断片的な情報から「Formという型がForm_F_001の親玉なんだろうな」というザックリとしたイメージはもってはいましたが、長らく「理論よりもコード先にありき」な状態だったので、それらはコードから自分なりに読み取ったイメージ/予測/解釈にすぎません。

VBAからはじめたユーザーにとっては、親切設計がすぎるがゆえに、いろいろな事が唐突な変形にしか見えないんですよね。フォームのことを「クラスモジュール」と呼ぶことは知っていても、自分がクラスの一部分を書いているという自覚も当時はありませんでしたし…。

これがclassの書き方を知ってからは、それまでのモヤモヤしたイメージ/理屈が、劇的に自分の中では一気に鮮明になったわけですね。

「クラス」と「インスタンス」の関係を知ったときの私の感想といえば、プラトンのイデア論に似ているなぁ、というものなのですが(洞窟の中で焚き火をして、その後ろで踊っているのがイデアで、洞窟の壁にうつる影法師は人間の住む世界だ、というあれですね。周囲からは同意を得ることはできませんでしたが、その関係性は似ていますよね???)。クラスが隠蔽されているVBAの世界は、私にとって影法師のみを見せられているようなものでしたね。

2008/05/05

Basicのお誕生日

5/1はBasicの44歳のお誕生日だったらしいですね。

私が最初に触れたプログラム言語も、学生の頃にちらっと触れる機会のあったBasicといえばBasicです。授業の内容は殆ど覚えてはおらず、妙に地味な印象しか残っていません。毎週のように課題が出され、なにがしかレポートにし、計算とグラフくらいしか描いていないような…。

うーん、どんな言語だったっけ?──と思って本棚をみたら、ちゃんと当時の授業のレポートがごっそりでてきました…(照)。久しぶりに当時のレポートに載せているBasicのコードをみてみると(レポートは課題の出題内容、考察とコード、および結果出力で構成されているので、レポートだけで大体なにをやろうとしたのかはわかります。言語の仕様は教科書がないのでコードから読み取るほかありませんが)、

  • インデントがなく、全部大文字(小文字やインデントはなかったんでしょうかね?)。
  • 配列の変数宣言ではDIMとか書いてありますが、数値型等では明示的な変数宣言もせず、型宣言もしていませんね。
  • FOR NEXTの呼応はあるようですが、IF文はEnd IfがなくTHENの後には、いきなりライナンバ(驚)。
  • IF文も含めて、GOTO文やGOSUB文など、ラインナンバが必須みたいな言語だったんですねぇ。
  • ところでこのラインナンバ、番号がぽんぽん飛んでいるので、エディタ機能ではないようなフシがありますが、もしかすると手入力だったのでしょうか?(手打ちでもしないと、切番などへは調子よく飛べませんからねー。ありうる)

いまのVBにこれらの面影あるか?と云われると、多少あることはあるような気もしますが、かなり変身したものですね。別物といえば別物だし、でもCの系譜にある言語よりは、1行ずつのセンテンスでみれば近いようなところもあるし…。

いずれにせよ、コマンド等も少なく、言語としてやけにシンプルだなぁという印象です(教師の方がマトを絞っていただけなのかもしれませんが。多少のアリゴリズム等をやらせたかったのではないかという形跡もありますし…)。

手元に残っているレポートに載っている範囲では、数値型と文字列型オンリーなのでクラス/オブジェクトのようなものも登場してきませんし、行番号でどーにかしようということ自体、わりとあり得ない感じの驚きはありましたが(←見事に綺麗さっぱり忘れていました…)。

VBはこの辺が始祖なんだなぁ、と思うと、VBユーザーとしては歴史も感じてちょっと面白いレポートです。

2008/04/27

買ったわー

GWはGeekWeek…。本日、マシンを買ってきました。ひさしぶのマシンのお買い物ですから、ついつい店員さんに根掘り葉掘り、部品ひとつひとつについて、訊いてしまいました。

見れば欲しくなるので普段は見ないようにしている…、というのもあって、ハードはマッタク詳しくないんですよね。ぽんぽん新しいCPUやらが出てくるし、グラフィックス系の部分もよく知らないし、Vistaもいじっていませんし…。ここ数年流行している光沢液晶も、いまだに使ったことがありませんし。

「完全に時代遅れだなー」という自覚があるので、ここぞとばかりにハテナ?と思っていたことはがんがん質問。

「ハードをいじるのことが、この人、かなり好きなんだろうな」という感じのハードへのラブが伝わってくる人で(「ナカを開けるとこのコはキレイなんですよー」と思わず嬉しそうに云う様は、まるで「内臓がキレイですねー」と嬉しそうにいう外科医のよう)、気兼ねなく質問できてヨカッタです。で、このオタな感じの店員さんは、「見た目より実をとれ」的な解説をする人で(さすがにあれだけ質問すれば、私の価値観を見極めますわね)、なんだかんだでディスプレイもノングレア液晶をプッシュされ、ノングレア液晶に…。

「光沢なんてただの飾りです!えらいヒトにはそれがわからんのですよ。映り込むのに!」

…みたいな?

あのツルツルした華やかさにふらふらと気持ちは傾いていたのですが、職場の蛍光灯が明るすぎたりして、常にディスプレイの「反射」には悩まされている日常があるので、「映り込み」の話を聞いて光沢はアッサリ断念。

省スペースのデスクトップが欲しかったので(≠ノートで。この数年ずーーーーーっと家でも職場でもノートだったので、なんというか飽きました)、まー満足です。OSはXP(今回は一応、Vistaのダウングレードで購入。XPはProfessionalなのでIISも使えるわー←所詮なにかとMSっ子)、CPUはCore2Duoとかがいいなーと思っていて(要はCPUが2つ以上ってところに拘っていた)、省スペース、の3つが必須条件。となると、殆ど選択肢がなかったところはありますが…。

お届けは29日の午前中デス。たのしみーー。

え、機種は?…秘密デス。

2008/04/05

Webアプリのバッチ処理

こんばんは。なにかとスタンドアローンのじょにです(←ちょっとヤケ)。

普段私はバッチ処理系なものを作ることが多いので、大量データを一気に加工するシーンはよくあります(でもMax60万件くらい。まーそんなもんです。Accessなので)。バッチ処理といえども、流して帰る…、という悠長なことはなかなかやってはいられませんので、なんであれ、待ち時間(処理時間)はなるべく短くすることは常に気にかけています。その際、まず私が考えることは、アプリからDBへのアクセス回数を減らこと。

DB設計も絡んでくる話だとは思いますが、手っ取り早い手段としては、

  • コード等が入っているマスターテーブルをハッシュに入れて、いちいちエラーチェックやら情報付加の為にマスターテーブルにアクセスしにいかない。
  • ぶんぶんLoopさせているところは、SQL一本で一挙にカタをつけられないか考える(Loopの回数を減らす)。

あたりでしょうか。

ADO.NET であれば、テーブルをDataSet(メモリ常駐型のデータ表現)へ展開させるので、自然とそれほどDBへはアクセスしなくてすむようになりましたが(もっともメモリに展開してからの書き方は色々で、書き方次第かなり速度に差は出ます。DataViewに突っ込んでRowFilterを使うよりハッシュを使った方が早いとか、リレーションシップを生成した方が早いとか)、Access単体の時はADO/DAO接続なので、インデックスの張り方、Dictionary関数とSQLの使い方に比重がかかってきます。その為には、メモリでもワークテーブルでも使えるものはなんでも使おうとします。

ところがWebのお作法は少し違うようですね。

近頃近所でアワアワしている人が、テストサーバーでWebアプリからよくCSVファイルをテーブルへ登録する実験を行なっています。登録したい件数が多すぎて(といっても4万件くらい?)、1回でアップロードできないので、その原因を探っているとのこと。テスト環境のColdFusionからかえってくるエラーメッセージはメモリーオーバーです(なんでメモリーオーバーのエラー表示???)。そんなこんなで、現時点で本番環境で速やかにできることといえば、CSVファイルを分割して、ちまちまアップロードすることくらいなんですね。あまりにそれでは手間ヒマがかかりすぎるということで、うまいことソースに修正を加えたいらしいのですが…。

実験してみてわかったことは、一見胡散臭そうにみえたCSVファイルの読み込み、INSERT文自体は4万件であろうとも、実はほんの数秒の処理であること。負荷の原因は、どうやらCSVファイルに対するエラーチェックだということです。で、そのエラーチェックのソースがどうなっているかといえば、1件1件エラーチェックする為に、次々、コード表を持っているテーブルを見に行っては値のチェックを行なっている。え。


4万件×何回テーブルを見に行っているの?


担当者は「Oracleだから沢山アクセスがあってもダイジョーブ」とか云っていますが、それってホントのことですか?この辺のことは簡易DBのAccessユーザーの私には正直わかりませんが、仮に1行につき10回DBを見に行ったとすれば、あっという間に40万回の連続ワザ。ホントにそれでヘーキなのでしょうか。なんであれ、ラウンドトリップ回数なんてなるべく少なくするべきものなんじゃないの???

Webの世界だと、色んな人が色々なテーブルを参照したり更新していたりいるし、アプリケーションサーバーでパワーの要ることをやったり(ハッシュとかも私のようにばんばん使っていると、一人分のメモリ消費×同時アクセスしている人数なので、あっという間にサーバーのメモリを消費してしまうわけですね)、色んなレコードに対して一挙にどうこうすると、Webを使っていた他の人が困っちゃう…、という発想があるから、ロックをかけるレコードはなるべく少なく、ちまちま1件ずつレコードを見に行くのがまずは基本のようですが。

CSVファイルの登録なんてバッチ処理なんだし、ある程度のコード表ならいちいちDBへアクセスしにいかずにメモリで持っていた方が断然早いし、既存データとの重複チェックを行ないたいなら、ワークテーブルに一端入れて、SQLで一発チェックした方が手っ取り早い気がするんですけど(或いはテーブルに入れてステータス管理とかでもまぁいいけど、インデックスとか張っちゃったりしていると問題ありそうなので、ワークテーブル)。ワークテーブルにもセッションみたいなものを入れられるフィールドを1列作っておけば、ワークテーブルに入ったデータのうち、どのセッションで利用したデータかの識別はできるわけだし──とか考えちゃうわけですが、なんらかの「失敗」がおきて残っちゃったワークテーブルのデーターをいつ削除するんだ、とか色々あって、そういう考え方自体危険なのかなぁ…、と無知なだけにモヤモヤ。

普段、スタンドアローン寄りのアプリばかり作っているので、この種の「バッチ処理」の実装部分で私はそこまでメモリの消費を気にしたり、同時アクセスしているメンバーのことをあまり考えていません。複数人で使うLAN内で使ってもらうようなアプリに「バッチ処理」を載せるときには、DBへアクセスしている人が自分以外にいないかをチェックする機能をつけて、「バッチ処理を行なう人は現時点で一人」という環境を作ってから、バッチ処理を実行させたり。「運用」とセットで考えると、単体のプログラムの外側で簡単に解決できちゃうことも多いですから、その辺で無理のないような回避方法を考えるとか(←1本のソフト単体でなんでもかんでもどうにかしようとはあまり思っていない。人の動きを簡便にすることは念頭にありますが)。

私の使っているDBはAccessですし、同時アクセスの人数はもともと少なく、それが通ってしまう素朴な世界に住んでいるので、考え方も「素直」なんですよねー。Web界隈に生息するイシカワさんと話していても、この辺からしていつも距離を感じます。想定条件のあまりの違いに、私ってスタンドアローンなんだなー、Winアプリなんだなー、としみじみ思うわけですね。

まーなにはともあれ、とりあえず、1回のアップロードで全部登録することを最優先に考えるなら、処理時間は無視して、5,000件くらいごとに、スリープさせるロジックをループの最中にいれちゃえば、殆ど今のソースを変えずに、全部登録できるんじゃないかなーというのが私の見込みです。どこでメモリーオーバーをおこしているにせよ、ファイルを小さくすれば通るロジックであることは確かなので、ときどきスリープして、ある程度のかたまり毎に処理を完結させてしまえば、どうにかなるのではないかなーという仮説。根本的な解決にはなりませんが、うまくいっているロジックを大改造するよりは安全・お手軽だし、ファイルをちまちま分割してからアップロードする現状よりは、黙って待つ方がラクチンだと思うし。

なんだか誰も信用してくれずに実験すらしてくれないんですけど(カウントして余りがゼロになったときにスリープするだけなのに!!)、実験してもらえないほど的外れな仮説なのでしょうか?なにかとマイノリティの自覚はあるけどさ…(悲)。

2008/03/30

OOP再考

■ところで私、OOPについて理解していないんじゃん?

VB6.0→VB.NET(VS2003)へ移行した当初は、OOP関連の書籍を読んだりして、わりとマジメにモヤモヤしていたものの、いつの間にかVB.NETでの表面的な書き方にすっかり慣れてしまって、

  • クラスは機能単位にまとめられてベンリだし
  • スコープの管理もなんだかラクチンだし
  • 全てをクラスで書くというシンプルさがいいではないの

というあたりで満足してしまっていたわけですが…。

移行当初に「差分プログラミングだ!」と思って、Formを継承するという大技にでて苦い思いをして以来(「VisualBasic」なのにVisualな環境ではなくなってしまい、ボタンの位置をズラしたくても、ソースに戻らねばならず大変なことに…。理屈を考えるとそりゃそーなんですけど)、すっかり懲りて、自分自身がコードを書く際には、継承、抽象クラス、Interfaceという三種の神器は、私の中ではまとめて「なかったこと」になっていたんですね。せいぜいヘルプを読む際に、その知識を生かす程度でした。

ところが最近、別件でサーフィンをしていたら、「俺のOOPの理解がどう間違っていたかのふりかえり」の記事がふと目にとまり、

クラス = 構造体 + 関数みたいにムリに構造化プログラミングの考え方で見ようとしてはいけない。でないと、オブジェクトを入れ替えることで実装を切り替えられる、という技術によって非常に柔軟なコードが書けるようになる不思議が中々理解できないんじゃないかと思う。

という一節が妙にココロに引っかかってきたんですね。私もクラス = 構造体 + 関数って捉えてない?捉えているよね?と自問自答…。

あらためて「OOPってナンだっけ。とりあえずデザインパターン本あたりから読んでみる?」という気になって、数年前に挫折したあたりからのやりなおし計画発動です。

■OOPやりなおし計画発動 ~ デザインパターン本を読む

4774115797
技術評論社 2002-09
売り上げランキング : 24748
おすすめ平均 star

Amazonで詳しく見る

やりなおし計画の第一歩として、「Javaデザインパターン徹底攻略 」とうい本を手にとってみました。

サンプルソースはホントにパターンの骨だけが書かれているこの書籍。非常に短いセンテンスでパターンを紹介しているので、読みやすく、それぞれのクラスの関係性については、よく見えてくる本でした。

ただサンプルソースは短いだけあって、ホントに骨だけ。具体性には欠けていて、この本を読んだからといって、すぐさま「おお、確かにこういうシーンで使うと超ベンリだよね!」という感じにはなれませんでした。

前半のパターンでは「こんなコードを、デザインパターンでこんな具合にシンプルに!」という、デザインパターン以前のサンプルソースがついていて、ナットクしやすかったのに、後半では何故かデザインパターン以前のサンプルを端折りだしていますしね…。このAfter、Beforeの対比は、是非、全部のパターンにつけて欲しかったですね。

というわけで、パターンの作りは見えたものの、この本を読んだからといって「すぐさまデザインパターンを自分のソースに…!」とはならず、「まー、いずれ使うかもね…」くらいの感じではあったわけですが…。

23パターンをつらつらと見ていて、強く印象づけられたのは次の2点。

  • ポリモーフィズムを使いまくり。
  • ポリモーフィズムを利用して、IF文での判定を減らしている。

「IF文って嫌われている?まぁ処理に名前はついてないからね…」と思いながら、ひたすらポリモーフィズムを利用するパターンを読み続けているうちに、今更ながらに、「ポリモーフィズムってこういう風に使うのか…」という「気づき」はありました。ポリモーフィズムを利用した書き方なら、結構ラクに今の自分の書き方に取り入れられるかも…、という「気づき」でもあります。

■ポリモーフィズムについて実践考

ポリモーフィズムを使うことを前提に、一つの機能について大雑把に整理しなおしてみると、次の3つの階層に切り分けることができます。

  1. データを具体的に加工したりする階層
  2. Aのレベルのクラスのメソッド等を順序よく操る階層
  3. Button.Clickのイベントの辺りで書いたりするクライアントプログラムの階層。

A階層のデータを操る部分は、データが変わるたびにソースを書かざるをえません。でもB階層は単なるメソッド呼び出しの手順なので、意外と一緒だったりすることが多いんですよね。データは変わっても、それを扱う順序は変わらない。

もともと汎用的なツールを作っているときは、データ(画像とか)を直接処理するAの部分は固定で、Bの部分を作り変えることが多く、自然とこの 3階層に切り分けて書くことが多かったわけなのですが…(とはいえ、この場合は、Bの部分の書き換えなので、ポリモーフィズムは利用できませんが…)。

それとは逆の場合には、これまで主に2階層で書いていました。業務によって仕様の違うデータを処理する部分では(値を加工してテーブルを入れたり出したりするような作業とか)、A+Bが一体となっているクラスαを作って、Cからαクラスの、順序を管理しているメソッドを呼び出す…、という書き方です。Button1のクリックに対応するのはαクラス、という1対1の関係で、αクラスのメソッドを順番にみていけば、ストーリーの大筋は終えてしまう、という書き方。

ただこのB的な「順序を管理しているメソッド」の大部分は、別のクラスからのコピー&ペーストの世界です。このコピー&ペーストのメソッド部分を、別クラスに出して、3階層で切り分けてみると、A階層のクラスをひたすら作り変えている、というカタチになるなぁ、と今回改めて気がついたわけです。


もう少し具体的に考えていきましょう。たとえば、CSVファイルのDBへのインポート機能を考えると、

  1. ファイルのパスをゲット。
  2. テーブルにデータを突っ込む。
  3. インポートしたデーターのエラーチェックを行なう。
  4. エラーがあればレポートの出力。

シチュエーションによって多少の差異は出てくるにしろ、大筋はこんな流れになります。

ということは…。

  1. 定型的なメソッドをInterfaceで宣言
  2. A階層のクラスでInterfaceをImplements。
  3. B階層のクラスはInterfaceで宣言したクラスを操作する。
  4. クライアントプログラムとなるC階層では、BのクラスをNewするときか、別メソッドを作るかして、Bのクラスへ、引数としてAのクラスを渡す。

InterfaceをImplementsしているA階層のクラスを、データに沿ったカタチで複数作っていけばいいわけですね。クライアントプログラムでは、扱いたいデータを処理しているA階層のクラスをひとつ選んで、ひたすらBのクラスへ引数として渡せばいい…。

データを入れたり出したりのバッチ処理は、頻繁に書いているものの、フローのバリエーションはいくつかに絞れそうですし…。そのバリエーションの数だけ Interfaceを作って、Interfaceを操作するBも作ればいいわけですから。作ってしまえば、あとはひたすらAの部分を書いていくだけ、と。

ポリモーフィズムを連荘で見せつけられて、自分の今のソースへの当てはめ方も見えてくると、「なーんだ、そっかー、簡単じゃん」という気になってきました。…私、騙されています?それとも、今更…、ってところなのでしょうか。

memo

VBユーザーだけどOOPならJava本でしょ、やっぱり

私はVB2005ユーザーですが、OOP本はなにかとサンプルソースがJavaの本が多いので、「Javaをある程度読めないと、OOP本は読めないぞ」と思って、VB6.0→VB.NET(VS2003)への移行当時、覚悟を決めてJavaの入門書を一通り通読しました。で、Javaの入門書を読みながら思ったことといえば、

「VB.NETの参考書よりも、Javaの参考書を読んだ方が、クラスのお作法についても、なんだかわかりやすい」(ナニソレ)

Java本が質・量とともに豊富なのに比べて、.Net系の良い参考書は、今でも「コレ!!」といったものがないですからね。VBユーザーといえども、Javaの簡単なサンプルソースくらいは読めないとツライご時世なのです。

とはいえ、今回私が読んだ「Javaデザインパターン徹底攻略」程度の簡単なサンプルソースであれば、わざわざJavaの入門書まで戻らなくても、ある程度、クラスのお作法に慣れている人であれば、非Javaユーザーの人でもつらつらと読めるのではないかと思います。共にOOP志向の言語で、大筋は似ていますから…。

ちなみにVB2005とJavaとの差異の部分は、VBという言語仕様のOOP志向への中途半端さ加減を感じる部分でもあります。例えばVBの場合、Interfaceにアクセス修飾子をつけられます。「ちょっとマテ。そこでpublic以外のアクセス修飾子をつけられる余地があるのは、どういうことなのさ?ポリモーフィズムを利用しようと思っても、不完全な可能性が…」この種の方向性の中途半端さ気がつくとなんだか気持ち悪くてムズムズしてきます。…あぁ神サマ、どーして私はVBユーザーなのでしょーか。この気持ち悪さを忘れるくらいの、自分の言語に対するLoveが欲しい。

memo2

Matzのにっき→2003年のOOPの記事リスト

Rubyは触ったことがないのですが、内容的にはなるほどなるほど。「オブジェクト指向は難しい」のオブジェクト指向の嬉しさの違いや、「(その2)」のオブジェクト指向のシンプルさについては、拙い書き方ながらも、これまでクラスを書きはじめてから感じていたことだったので、「あぁこの嬉しさの違いは私にもわかるなぁ」と共感(嬉)。

「継承は悪か」のま2さんのツッコミ記事は今の自分にはタイムリー(2003年の記事で、世間的には5年も前の議論なわけですが…)。

4. で実際問題として,手続きが変わるより,データ形式が変わることの方が多い。したがって,実際問題としてオブジェクト指向の方が威力を発揮する。

オブジェクト指向は「データ中心」の産物で,「データ中心世界」では強い。そこでプログラミングの対象が「データ中心世界」なのか「手続き中心世界」なのかが重要だということです。結局オブジェクト指向とは「ものの見方」なのですね

まさに!!ってところですね。

2008/03/13

モリス

ミックさんのところでプロジェクト杉田玄白(翻訳版青空文庫?)の話が出たところで。

そういえばミックさんたらモリスの翻訳もやっていたんだっけ、と思い出しちょっとうきうき。ちょっとずつ読んでいこうかな。

モリスは直感的にスキ。でもせいぜいこれまでのところ「ユートピアだより」位しか読んでいませんので。

原文の方も折角なのでトライするかの…。

2008/03/12

終端文字のようなセミコロンの話

SQLの終端文字のようなセミコロン。

Oracleではどうやらシステム変数で変更できちゃうみたいだし(デフォルト=セミコロンというだけの話なのねー)、どうやら標準SQLではないというのはなんだか衝撃でした。ものの本では大抵、終端文字然としてSQLの文末には「;」がありますからねー。

で、このセミコロンの話をS師匠と話していたところ、「そうだよ、だから.Netで書くときはパラメーターでイチイチ定義する書き方もやっているんだよ」と云われて、そういえば、DB絡みのクラスを書きはじめた当時、そんなようなことを云われたなー、ということを思い出しました。

アプリを作る際には、SQLのWHERE部分に対して、変数なりで条件を受け渡します。検索画面であったりするなら、テキストボックスで知りたい値を入力するわけですが、その際「0;DELETE FROM TB_USER」とか入力されて、それがまかり通るようなソースを書いていると、あっという間に、システムは逝ってしまうわけですね。こわー。

そういう意味ではSQLの終端文字を受け付けないODBCはある意味、安全ってコト?(うーん、でもODBCとDBの組み合わせによっては終端文字OKな場合もあるのかなー?ありそうな気もするなー)

航海日誌

航海日誌試運転中。

日々のエラー記録簿、備忘録。

Ω Ω Ω
なにかとgoogleユーザーなので、とりあえずBlogger。

ついでにPage Creatorとかも利用しちゃったりして(ソースコードに色をつける為、javascript類をUP)。

でもTBとかデフォルトで設定できないんですね。blogとしてそれはどうなの?Backlinksってナニそれ?

gmailでおなじみのラベル機能は魅力だけど、googleなんだし、過去ログを探すときは検索した方が速いカモネ?