ソフトウェアを作る上で、コードを書く以外に大切なこと@ニコ動

ソフトウェアアーキテクトが知るべき97のこと
Richard Monson-Haefel

4873114292
オライリージャパン 2009-10-05
売り上げランキング : 1617

Amazonで詳しく見る
by G-Tools
















右上の本の刊行記念トークセッション@ジュンク堂書店。アーキテクトってつまり現場監督?面白かったのでメモ。自己加工で正確なトーク内容ではなく雰囲気も再現されていないのであしからず。

◆紹介
鈴木雄介さん - 「アーキテクト」って?
アーキテクトとは、ソフトウェアを作る上でコードを書く以外の大切なことをやる人。それで伊藤さんや小野さんに日本語版での日本人の執筆を依頼した。仕事はSIer。在庫がないと数日で生命が危険になる医療機器のメーカーで在庫改善を提案したら役員から怒られた。

伊藤直也さん - はてぶの人。
Webアプリケーションは作れる人も多い。ただ、はてなの膨大なデータをWeb上で展開するアカデミックなデータマイニングとなるとどうしていいか分からない。両方できると強い。最近はコーディングではなく、社員数が増えたはてなのマネジメント。そのほうが全体の生産性があがるので。

小野和俊さん - 徹夜ダメの人。
以前半年ぐらいペアプログラミングばっかりやって社内を遊撃隊してたら新人にきれられて反省した。マネジメントは後悔したのでプログラマに戻ってる。エンタープライズのパッケージの会社なのでクラウド化に取り組んでる。

◆アーキテクト的な仕事へのターニングポイント
伊藤さん
以前のはてなはマネジメントがなくて、技術者が苦手なことやいやなことを避けてしまい、ユーザー登録フローみたいなお決まりごとはおざなりだった。それでも楽しくやっていたが、インフラがぼろぼろになったときに困った。データセンターいってインストールとか、誰もやりたがらないようなチーム作業のマネジメントが必要になった。

小野さん
新卒で入ったサンマイクロでアメリカでのマネージャのダグラスが強烈で、リリースできないシステムで徹夜しようとしたらスキーに連れて行かれ、3日間滑らされた。トラブルを抱えているときは頭が悪くなってて、1つを解決すれば3つの問題が解決するのに、3つの問題を解決しなければならないとなっていまう。はちまき巻いてがんばりますじゃなくて、ゆとりを持って相談してると「あれいらないんじゃない?」ってなる。シリコンバレーはすごいと思ったが、細かいものづくりは日本のほうがいいからと思って起業したのがきっかけ。

鈴木さん
アーキテクトと名乗るのは恥ずかしかった。プログラミングの反対側みたいなやつらが象牙の塔からよくわかんない絵を書いてきて、これ作れみたいなネガティブなイメージがあって、でも会社のマネジメントに関わるようになったら、仕事をうまく回すための役割として、「アーキテクト」という言葉が一番しっくりくるようになった。

伊藤さん
一年前なら依頼は断っていた。「おれはハッカーだハァハァ」みたいな

小野さん
実際の基準があいまいだけど、読んでみるとシステム設計に携わる人のぶっちゃけ話で親近感が沸いた。

鈴木さん
元々はイベントでやったのがウケて、それからwikiで集まったのが本になっている。

◆過去のソフト開発での失敗から学んだこと
伊藤さん
20代のころは「マネジメントなんていらない、プログラマーサイコー」みたいなこをブログでよく書いてたので、なかったことにしたいというのは半分冗談だが、天才プログラマーというか優秀な人が一人いればものごとは上手くいくと考えていたようなところがあったが、そういう人に上手くお願いする人がいないといけない。優秀な人がユーザーフロー書いていたりとか、組織としてなってしまう。あるいは、新人のころにオブジェクト指向にはまってぐちゃぐちゃやってしまい、先輩に引き継いでもらって土下座して謝りたい気持ちの思い出とか。

小野さん
会社設立したころ、目をキラキラさせてがんばって2年間、ずっと会社に泊まってという頃があり、自主的にやってるからいいかなと思っていたのが間違いで、身体的には疲れているからイライラしてしまったり、そんななのに徹夜をアピールしてしまったりということをブログに書いたら40万アクセスで、徹夜でぐぐると2番目でSEとしてなんなのかという。

伊藤さん
インフラでトラブって夜中に携帯にメールがきて、人力で直してという消耗戦をやってて、人を増やしたら増やしたでなんでやってないのとかおれ徹夜したのにとかもめごとになって、マネジメントが必要になった。

小野さん
全員サッカーでみんなでわーっていってがんばるけど試合には負けているという。

伊藤さん
自分がそういう立場になって分かったけど、監督は必要。

鈴木さん
SIerに勤めていると、はてな的な面にあこがれがあるんですよ。「Webサービス、自分たちでやったもの世に問いたい」じゃんみたいな。であるパートナーと組んで設計したら、これ3年くらいかかる、出資者にお返しできないってなってしまった。夢に胸をふくらませて取り組んでいても、一歩引いて冷静にみている人がいないとだめで、迷惑をかけてしまった。SIerの仕事はリリースした時点で精度が100%じゃないといけない部分があって、Webならベータ機能でもいいのものならとりあえず出してというところがあるのに対し、基幹ではリリースした途端に何億円のトランが走るなら3年かかってもやるというのもあって、そういうバランス感覚はいい経験になった。

◆マネジメント100%でないところ
伊藤さん
Webサービスの点からは、クライアントから機能を求められるわけではなく、自分達で魅力を高めていかないといけないので、家でプログラミングしていいプロトタイプができたら、会社に持ってきてチームでやったりしている。データマイニングのアルゴリズムはデータ食わしてみないと思ったような結果になるのか分からなかったりするところもある。

鈴木さん
コード書くことも日本語のドキュメント書くこともパワポ書くことも、表現の形態としてあまり違わないなって思うこともある。

小野さん
マネジメントは必要悪的なところもあって、少人数なら自由なほうが生産性も高いが、たとえばトラブル対処で再発防止策をつくってガチガチになって、機動性が失われてしまうので、バランスが結構難しい。

伊藤さん
再発防止策を作ってもその後起きなくて忘れてしまい、起きたときにはあの施策なんだっけになっているという。

小野さん
時々ライフサイクル的にこのルールはというのを棄てていくフェーズを作らないとそれだらけになってしまう。

鈴木さん
IBMが全世界で50万人の会社をどうマネジメントしてるのかという話で面白かったのは、アーキテクト職になるには試験があり、アーキテクト同士で認めればなれるというのが制度化されているという。マイクロソフトではアーキテクト職を認定するのに、マイクロソフト社員じゃないアーキテクトの人のみが試験管で、本社のレドモンドで試験を実施している。

◆よいソフトウェアを作ること、コードを書く上で大事なこと
伊藤さん
はてぶのリニューアルで思ったのは、つぎはぎだった設計を作って壊してをしまくったおかげで、大人数で開発してもぶれない形になった。ひどい経験がなくてベストな設計はどうやって分かるのか分からない。

鈴木さん
SIerとしては逆に、システムが動くところを見ることがあまりないので、使われてなんぼとか使い勝手とか、そういう悩みはあまりないのかなと思うところもある。「作ること」と「使うこと」はアーキテクチャを境目に相対していて、作りやすいからいいというのと、使いやすいからいいというののすり合わせをうまくやっていく必要がある。ひゅっとやってひゅっと動くからいいよねといってもそれを作るのに何人月なんだとかというバランス感覚はコードを書く上で大事かなと思う。

伊藤さん
ニコニコ動画のマネジメントのトップの人に、はてぶ自分でコード書いてるんですかと聞かれて、結構自信満々にそうですと答えたらダメですと怒られました。ユーザ的にはこのほうがいいが分かっていても、めんどくさかったり、無意識でもやめちゃうことが多くて、人にやってもらうようになった。ただ、5年後でもコードのことが分かりつつ人にやらせることができるかどうかどうかというと、やっぱり自分でも研鑽していかないといけない。

小野さん
会社では一度壊して作り直すようにして、情報を集めて新しい技術を使うようにしているが、シリコンバレーの技術者は実はあんまり最新情報を集めたりしていなくて、日本の方がシリコンバレーの最新情報に詳しい。最新情報を集め続けてもそれで満足してしまったりするので、作り直しのタイミングであえて新しい技術を入れてみる。それを5年後に作り直すときにも、いったんリセットしてというふうにやっている。

伊藤さん
よいユーザ体験ができるのがよいソフトウェアという意味でいうと、ユーザ寄りを心がけているというところはある。iphone持ってなくてツイッターもやってないのは、日本の携帯はまだ普通の携帯が多いから。会社見渡すとみんなiphoneだし、はてぶ使ってるのもiphoneユーザーが多いけど、あまり先鋭的にならないように意識している。はてぶを作ったときは、需要があって作ったというより、インターネット最高みたいなという信念で作っていた。であるていど流行ってふと気付いたのが、もともとリテラシーのある人がどんど加速しているだけで、リテラシーのない人があれを使って新しい体験をしたという感じにはなっていない。最近のサービスもそうで、もっと全体を押し上げるようなサービスを作ろうとするのに、あまり先鋭的な位置にいないように心がけている。

小野さん
僕は好きなことにのめりこむタイプで、ゲーム5000時間やってて親戚に心配されたりしたけど、のめりこむとコミットしたくなったり、関係ない新しいことが仕事に役立ったりする。



後の参加者の質問は省略。




関連付けと異なるアプリでファイルを実行する

まずはたとえば拡張子.txtに関連付けられたアプリケーションを探す。
wsh = new ActiveXObject("WScript.Shell");
rootTxtExePath = wsh.RegRead(
'HKCR\'+ wsh.RegRead('HKCR\.txt\') +'\shell\open\command\'
);
HKCRから取得されるのはメモ帳。
%SystemRoot%\system32\NOTEPAD.EXE %1 

HKCUではVistaや7とXPとではパスが途中から異なっている。
var commonPth ='HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer'+
'\\FileExts\\.txt\\';

if(/Windows NT 6/.test(navigator.userAgent)){
try{
var txtExeId = wsh.RegRead(commonPth +'UserChoice\\Progid');
var txtExeCmd = wsh.RegRead('HKCU\\Software\\Classes\\'+
txtExeId +'\\shell\\open\\command\\');
}catch(e){}
}else{
try{
var txtExeId = wsh.RegRead(commonPth +'Application');
var txtExeCmd = wsh.RegRead('HKCU\\Software\\Classes\\Applications\\'+
txtExeId +'\\shell\\open\\command\\');
}catch(e){}
}
取得した実行コマンド
"C:\sakura\sakura.exe" "%1" 

引数の"%1"を実際の開きたいファイルパスに置換し、そのままRun()。
wsh.Run(txtExeCmd.replace(/%1/,'開きたいファイルのパス'));






Window7 テクニカルセミナー


場所は秋葉原駅前UDXビル。参加者はベクターの登録開発者限定だ。これはなにかプレミアムなのだろうか?

ベクターとマイクロソフトの共催でWindowsアプリ開発に積極的な人が200人以上収容できる部屋の後ろまで埋まっていた。

しかし、Windowsもデビューして20年弱。写真のとおり平均年齢は30代以上、前の方の席は40代以上。Windowsとともに年を重ねてきた人達なのだろう。「トッププログラマーである皆さん」ってマイクでおっしゃるけども、目をギラギラさせた人はいなかったし、全体の加齢臭はどうしても否めない。
「この業界は20年かけて大きな会社に成長しても、MSのように激しい競争にさらされ続けています。私はそんなところも好きなんです」と、MSの方が話されていて印象に残った。

考えてみれば、Windowsアプリにiphoneアプリと同じだけの金額を払う人は多くないだろう。コード量はずっと多く、機能がリッチだったとしてもである。

解説されるWindows7の新しいUI、タッチパネル対応にしても、連想するのはiphoneのそれであり、ちぐはぐな感じがしたのは僕だけだろうか。JavaScript2とHTML5+CSSで何でもできるようになるんじゃないかというご時勢である。そこに触れられることがほとんどなかったのが、僕としては残念だ。

MicroSoftは強力な武器を持っている。世界中のオフィスの重要なファイルはMicroSoftのフォーマットによって管理されているのだ。たとえそれらがどんどんクラウド化されていこうと(MS自身、オフィスをWEBバージョンで無料公開するといっている)、アプリケーションをJavaScript2とHTML5で作成しようというときのアドバンテージは大きいのではないか?なぜWindowsでアプリというとき、コーディング負荷のあるC++やC#でなければならないのか?僕には分からない。なぜガジェットという足かせを外さないのか?powershellとかsilverlightもいいけども。クリーンインストールされた職場のPCで威力を発揮するのはやっぱり、今は見向きもされないHTAだ。






タブスライサー

空白トリム


ソース
function execSepBtn_click(){
  outDat.value = dat ='';
  var ket = sepLen.value.split(/[\t,\r\n]/);
  var nyu = inpDat.value.replace(/\r\n/g,"\n").replace(/\r/g,"\n").split("\n");

  for(var k in nyu){
    var st=0;
    if((k == nyu.length-1)&&(nyu[k] =="")) break;
    for(var i in ket){
      var en = st + Number(ket[i]);
      for(j=st; j<en; j++){
        var c = nyu[k].charCodeAt(j);
        if(0x80 <= c && (c <= 0xff60 || 0xffa0 <= c)) en --;
      }
      dat += cutBlank.checked ?
               (nyu[k].slice(st,en).replace(/^\s*|\s*$/g,'')+"	") : 
               (nyu[k].slice(st,en)+"	");
      st = en;
    }
    dat = dat.replace(/\t$/,"")+"\r\n";
  }
  outDat.value = dat;
  outDat.select();
  $(outDat).toggle().fadeIn();
}





IE8でPopBox.jsが1回しかポップアップしない件

538行目を
elem.style.zIndex = null
コメントアウトするといいらしいのでやってみたら確かに直った。んがっ




PopBoxで画像をスライドさせて下のテキストを表示する

右のプロフィール画像をクリックすると、その下レイヤを表示する。
<span style="position: relative; top: 0px; left: 0px">
<img src="<%image>" alt="<%author_name>"
class="PopBoxImageMove"
pbshowrevertimage="false"
pbshowreverttext="false"
pbshowrevertbar="false"
onclick="PopEx(this,0,60, 150,113, 6, null);"
style="z-index:101; position: absolute; display: inline;
width: 150px; height: 113px;
top: 0px; left: 0px" />
</SPAN>
<%author_name>
<a href="mailto:parabe@yahoo.co.jp">mail</a>
PopExメソッドのパラメータは以下
void PopEx(obj,newLeft,newTop,newWidth,newHeight,speed,className)






どこでもgoogle.js

クリックボードにコピーしたテキストを検索キーにして、google検索結果画面を表示します。
ショートカットをデスクトップに置いておけば、アクティブなアプリケーションの種類を問わずショートカットキーが有効なので、どこからでも実行できます。

左のファイルを適当な場所にダウンロードし、
ファイルを右クリック、ショートカットの作成でショートカットを作成。
ショートカットをデスクトップに置く。


どこでもgoogleProperty











Ctrl+Cでコピーなので、
Ctrl+Shift+Cがラク。


ExcelなりpdfなりでCtrl+Cでテキストをコピーしたら、続けてCtrl+Shift+Cを押せば検索結果画面がブラウザで表示されます。

ソース
new ActiveXObject('Shell.Application').ShellExecute(
"http://www.google.co.jp/search?ie=Shift_JIS&hl=ja&lr=&num=50&q="+
(new ActiveXObject('htmlfile').Script.clipboardData.getData('text')))






サクラエディタマクロ - カーソル位置の単語でgoogle検索

google検索は一瞬でやりたい。キーワードを念じただけで結果画面が表示されれば理想的。頭の中断は限りなくゼロに近づく。がさすがにそれは難しい。

サクラエディタを使っていてファンクションキーを1回押すくらいなら、脊髄反応で脳の邪魔をさせずにいけそうだ。調べたい単語を範囲選択する操作も頭が中断するからいらなくした。

 コードまで1行にするのは気分の問題だけど、セミコロンなし。
new ActiveXObject("Shell.Application").ShellExecute(
"http://www.google.co.jp/search?ie=Shift_JIS&hl=ja&lr=&num=50&q="+
(IsTextSelected ? GetSelectedString() : (SelectWord(),GetSelectedString())))






サクラエディタマクロ 逆インデント(複数行選択時も)

サクラエディタの逆インデントは範囲選択しないといけない。キー操作がまんどい。
このマクロは単一行なら範囲選択不要で、複数行選択ならまとめてアンインデント。
ただ、改行だけの行は削除されてしまう。
実行後のカーソル桁位置は行末。
(function(){
s = (GetSelectedString(0) ? GetSelectedString(0) : GetLineStr(0)).replace(
/^ |^\s|(\r\n|\n|\r)/gm,'$1');

switch(IsTextSelected()){
case 2: return;
case 0: s = s.replace(/\r\n|\n|\r/,'');
LineDeleteToStart();
LineDeleteToEnd();
}
InsText(s);
})();
IsTextSelected()の戻り値2はボックス選択状態で、何もせず復帰。
ちなみに、グローバルのトップレベルでreturnしても関数の外にあるといってJSのエラーになるが、
関数で全体を囲い、それ自体を最後の();でトップレベルから呼び出すようにしておけば、returnする位置でマクロ実行から抜けることができる。

0の選択なしでは行頭行末改行まで削除し、その後InsText()で挿入。
複数行選択の有無にかかわらずこれでうまくいくので、ラッキーなコードか。




三井住友ダイレクトにSleipnirスクリプトで自動ログイン

銀行サイトは何かと便利ですが、アカウントやパスワードをPCの前に持ってきて入力するのが面倒。
面倒だからと番号をそこらのテキストファイルにメモしておくのもセキュリティ上あぶない。
そこでSleipnirの自動ログインスクリプトです。

Program Files内はOSによってガードされているので、僕はこちらのほうが安心。
account1account2には契約番号、passwordはパスワードを設定します。
これを拡張子JSのファイルにしてSlepinirフォルダのscriptフォルダに置き、
Slepinirのオプション、全般の設定で「スクリプトによるクライアントの操作を許可する」のチェックボックスをオンにしてSlepinirを再起動すると、スクリプトメニューから選択して実行できます。

Sleipnirのサイトにも同様のものがありましたが、こんな感じにしています。
(function smbcDirectLogin(){
var pageURL ="https://direct.smbc.co.jp/aib/aibgsjsw5001.jsp";
var account1 ="";
var account2 ="";
var password ="";

var objSleip = new ActiveXObject('Sleipnir.API');
var wid = objSleip.NewWindow(pageURL, true);
for(var i=0,document; i<100; i++){
WSH.Sleep(100);
document = objSleip.GetDocumentObject(wid);
if(document != null) break;
}
for(var i=0; i<100; i++){
WSH.Sleep(100);
if(objSleip.IsBusy(wid) != true) break;
}
if(! document) objSleip.MessageBox(wid+"を作成できません");
else{
document.Login.USRID1.value = account1;
document.Login.USRID2.value = account2;
document.Login.PASSWORD.value = password;
document.Login['bLogon.y'].click();
document = null;
}}()
);
僕はもう長年これを使ってますが、使用は自己責任で願います。
サイトのデザインが変わるとメンテが必要ですが、
僕が使っている大体の銀行、クレジット、証券のサイトはこんな感じで使えてます。




『JavaScript: The Good Parts』

JavaScript: The Good Parts ―「良いパーツ」によるベストプラクティス
ウェブブラウザの進化と一緒にどんどん変化するJavaScript、
厳密に知らなくても書いて動かせる。
で、不可解な挙動でデバッグに苦しみ、やっぱいいかげんな言語だなと放り投げられる。

いわゆるNHK的な標準語のアナウンサー学校があれば入りたい。
ならこれはサイ本より役に立ちそうなプラクティス本。






非道器なShellExecute

//ssh.ShellExecute(".\\ap\\d2txt130r2\\xdoc2txt.exe"," -f "+pth,"","");
wsh.Run(".\\ap\\d2txt130r2\\xdoc2txt.exe -f \""+pth+"\"",0 ,true);
別環境で差分表示してみると、xdoc2txtがファイルを出す前にDFを起動してしまい、ことごとくそんなファイルありませんといわれてしまった。

画面のレスポンスといえばWindowsが蔓延ってしばらくまでは0.1秒の違いでさえストレスや快適さを感じて、動作の軽いソフトに対する原理主義的な称賛さえあったものだが、そのせいかGUIというのは外部の処理はとかく非同期なところがあって、スクリプトでGUIしようとすると風見鶏のようにくるくるとループして復帰を待つということになってしまう。XMLHTTPなんかはより下層で制御してくれるのでいいのだが、ファイルシステムとなると難儀だ。

とはいえ、Runメソッドは復帰待ちができて便利。最初からこっちを使っておくべきだった。NTの頃に大きいファイルを扱って苦労したことがあってあてにしてなかったが、今は安心して使えるようだ。




サクラエディタ - keisenPaste.js

マクロ書き直した3つめ。ファイルは右のSkyDriveのSakura Editor Macroフォルダにありまそ。

前回の派生で、範囲選択したものかクリップボードデータに枠をつけるだけのもの。

keisenPaste1.png → keisenPaste2.png

(function main(){
var s = Editor.GetSelectedString(0)
|| new ActiveXObject('htmlfile').Script.clipboardData.getData('text');
if(!/\r\n/.test(s)) s +="\r\n";
s = s.replace(/\t/g,' '); //indentのタブをスペース置換する場合。
if(s){ s = s.replace(/\r\n/g,"\n").replace(
/\r/g,"\n").replace(
/\n/g,"\r\n").split("\r\n");
}else return;
maxWdh = compareLen(s);
Editor.insText(setStr(setLength(s)));
})();
   前回とかわらない

function compareLen(s){
var m = "";
for(i in s){
var ln = bLen(s[i]);
if(m < ln) m = ln;
}
if(m % 2) m++;
return m;
}
   罫線文字が2byteなので2で割り切れないなら1++

function setLength(a){
var ln, tl = a.length - 1;
for(var i=0 in a){
ln = bLen(a[i]) || 0;
if(i == tl){;}
else if(ln < maxWdh){
var s ="";
var d = maxWdh - ln;
for(j=0; j < d; j++) s +=" ";
a[i] += s;
}
}
return a;
}
   短い行には半角空白埋め。

function setStr(a){
m = maxWdh / 2;
var k ="", s ="";
for(i=0; i < m; i++) k += "─";
var hLine = "┌"+ k + "┐"+"\r\n";
var tLine = "└"+ k + "┘"+"\r\n";
for(j in a) if(a[j]) s = s +"│"+ a[j] +"│"+"\r\n";
return hLine + s + tLine;
}
   前後左右に罫線文字を追加

function bLen(s){
if(!s) return;
var l = s.length, b = l;
function isWide(c){ return(0x80 <= c &&(c <= 0xff60 || 0xffa0 <= c)) }
for(i=0; i < l; i++) if(isWide(s.charCodeAt(i))) b++;
return b;
}
   前回と同じくbyte長。
   しかしVBSのLENB()もうそっぱちだし、powershellとかsilverlightもいいけど、

   中の人なんとかしてくれんか。

   と思ったら、.NETにjQuery採用してるぢゃないかw!w

   そうか、VisualStudioのインテリセンスにjQueryも出てくるのかw

   長いものに巻かれているうちは帝国も安泰ぢゃw






サクラエディタ - sepDataPaste.js

マクロ書き直した2つめ。ファイルは右のSkyDriveのSakura Editor Macroフォルダにありまそ。

Excelで範囲選択コピーしたものをサクラエディタに貼りつけると、
タブ区切りでガタガタになるので、イメージがつかめない。
ので、タブやカンマ区切りの表データを列幅を調節し罫線をつけて貼りつけるマクロ。

keisenPaste.png → keisenpasteSakura.png






(function main(){
lines = {
maxWidth : [],
header : "",
data : [],
count : 0
};
var s = Editor.GetSelectedString(0)
|| new ActiveXObject('htmlfile').parentWindow.clipboardData.getData('text');
if(makeCells(s)) Editor.InsText(setEachLines());
})();
   オブジェクトリテラルlinesは、
   maxWidthは各列の最大幅、headerは1行目、dataは2行目以降、countは行番号。
   範囲選択されていればそれ、されていなければクリップボードデータを取得して、
   makeCells(s)以降の処理をしたら挿入。
   Editorはサクラエディタから実行すると参照できるエディタオブジェクトで、マクロ関数が使える。

function makeCells(d){
var rowLines = d.replace(/\r\n/g,"\n").replace(/\r/g,"\n").replace(/\n/g,"\r\n").split("\r\n");
for(i in rowLines){
if(!rowLines[i]) continue;
if(!splitLine(rowLines[i])) return false;
lines.count++;
}
return true;
}
   サクラエディタは改行コードが混在するデータを扱えるので、
   セル内改行の\nもひっくるめて\r\nに統一。
   行毎に次の処理を呼び出し。

function splitLine(str){
var sep2ndLine = '"",""'; //csv format sepline
switch(lines.count){
case 0:
var sep = setColSep(str);
if(!sep) return false;
lines.header = str.split(sep);
compareCellLen(lines.header);
break;
case 1:
if(str == sep2ndLine) break;
default:
var sep = setColSep(str);
if(!sep) return false;
var d = str.split(sep);
compareCellLen(d);
lines.data[lines.count] = d;
}
return true;
}
   ヘッダ行、セパレータ行、それ以降の行でswitchして次の処理を呼び出しつつ格納。

function setColSep(str){
if(/\t/.test(str)) var colsep = " ";
if((/,/.test(str)) && (!colsep)) var colsep = ",";
if(!colsep) new ActiveXObject("WScript.Shell").popup("区切り文字判定できず");
else return colsep;
}
   行毎にタブかカンマかの区切り文字を判定して返す。

function compareCellLen(arr){
if(! lines.count) for(var i=0 in arr) lines.maxWidth[i] = bLen(arr[i]);
else{
var ln = [];
for(var i=0 in arr){
ln[i] = bLen(arr[i]);
if(lines.maxWidth[i] < ln[i]) lines.maxWidth[i] = ln[i];
}
}
}
   行毎に呼ばれるここで各セルの幅をmaxWidthと比較して大きければ格納。

function setEachLines(){
var hline ="", dlines ="", sline ="";
hline = attachWidth(lines.header).join("|") +"\r\n";
for(i in lines.data) dlines += attachWidth(lines.data[i]).join("|") + "\r\n";
sline +=setSeprateLine(lines.maxWidth).join("|") + "\r\n";
return(hline + sline + dlines);
}
   次の処理で空白埋めした後にパイプ文字を挟んで結合。

function attachWidth(arrCol){
for(var i=0 in lines.maxWidth){
var colWth = bLen(arrCol[i]) || 0;
if(colWth >= lines.maxWidth[i]) continue;
var strBlank = "";
for(j=0; j < (lines.maxWidth[i]-colWth); j++) strBlank += " ";
if(!arrCol[i]) arrCol[i] ="";
arrCol[i] += strBlank;
}
return(arrCol);
}
   maxWidthになるまで半角空白で埋めて各列の幅をそろえる。

function setSeprateLine(arrColumn){
var arrDash = new Array();
for(i in arrColumn){
var strDash = "";
for(j=0; j < lines.maxWidth[i]; j++) strDash += "-";
arrDash[i] = strDash;
}
return(arrDash);
}
   セパレート行も幅に合わせて作成

function bLen(s){
if(!s) return;
var l = s.length, b = l;
function isWide(c){ return(0x80 <= c &&(c <= 0xff60 || 0xffa0 <= c)) }
for(i=0; i < l; i++) if(isWide(s.charCodeAt(i))) b++;
return(b);
}
   JScriptのlengthプロパティはUNICODE文字に対するものなので、byte長を返すため。

長い。処理するデータ量に比例してもっさりしていく。




サクラエディタ - pathJump.js

マクロ書き直した。ファイルは右のSkyDriveのSakura Editor Macroフォルダにありまそ。

var extNam = ["txt","log","sh" ,"csh","dat","ini","sql","js"];
var hogePth = new RegExp("\\\\hoge","i");
   OSの関連付けを無視してサクラエディタで開く拡張子と、
   アクセスを禁止したいパスの正規表現キーワード。URIでもおk

(function setPathString(){
sh = new ActiveXObject("WScript.Shell");
var s = Editor.GetSelectedString(0);
var p = s ? s : Editor.GetLineStr(0) ;
var reg0 = /(?:.*?)([A-Z]:\\|\\\\[1A-Z])(.*?)(?:(?: |\s){2,}|[<>:\|"])(?:.*)/i;
p = p.replace(reg0, "$1$2").replace(/\r|\n/gm,"");

return hogePth.test(p)
? sh.popup("このパスはアクセスできません。\n\n"+ p)
: jump(p);
})();
   関数自体を(func~)();のように括っておくと呼ばれなくても読み込み時に走る。
   ので、中でvarした変数のスコープはプライベートで使えて読みやすくなる。
   reg0はカーソルの範囲選択が面倒で、タグジャンプみたいに行から見つけてジャンプさせたかったので、
   パスを取得する正規表現。サクラエディタのgrep結果画面で
C:\Program Files\sakura\pathJump.js(39,19)  [SJIS]:~
   なら行列位置の(39,19)ごと取得。

function jump(p){
var fs = new ActiveXObject("Scripting.FileSystemObject");
var reg2 = /(.*?)(?:\(|\s{2,}?)(\d+)(?:[,]*|[\s]{2,})(\d*)(?:[\s\)]*)(?:.*)/;

if(fs.DriveExists(fs.GetDriveName(p))) {
var d = fs.GetDrive(fs.GetDriveName(p));
if((d.DriveType == 3) && (hogePth.test(d.ShareName) != -1))
return sh.popup("このパスはアクセスできません。\n\n"+p);
}
if(fs.FolderExists(p)) sh.Run('"'+ p +'"');
else if(reg2.test(p)) {
if(fs.FileExists(p)) return sakuraOpen(p);
var fileP = p.replace(reg2,"$1");
var linNm = p.replace(reg2,"$2");
var colNm = p.replace(reg2,"$3");
sh.exec(Editor.ExpandParameter("$S")+' "'+fileP+'" -X='+colNm+' -Y='+linNm);
}
else if(fs.FileExists(p)) sakuraOpen(p);
}
   reg2はサクラエディタのgrep結果書式だった場合に行列位置を取得。

   処理の順序が塩梅で、ドライブ名が取れたら共有名を取得してアク禁パスかチェック、
   フォルダならRun()でフォルダウインドウ、
   grep結果の書式ならExec()で行列位置を渡してサクラエディタで実行、
   それ以外でファイルパスなら拡張子チェックへ。

   この順番が変わるとアホな挙動になってしまう。


function sakuraOpen(p){
for(var i in extNam)
if(new RegExp("\."+extNam[i]+"$","i").test(p)) return Editor.FileOpen(p);
new ActiveXObject("Shell.Application").ShellExecute('"'+ p +'"');
}
   設定された拡張子でなかった場合、デスクトップシェル環境のShellExecute()におまかせ。






軽くてシンプルなpopbox.js

仰々しいアニメーションがなく動作も軽くていい感じ。
とりあえず右のprofile画像に設定。クリックすると動作。

scriptタグ
<script src="./PopBox.js" type="text/javascript"></script>
<script type="text/javascript">
popBoxWaitImage.src = "./spinner20.gif";
popBoxRevertImage = "./magminus.gif";
popBoxPopImage = "./magplus.gif";
</script>

CSS (拡張子.curはFC2ブログではアップロードできないので、_cur.txtとした。)
.PopBoxImageSmall
{
border: none 0px white;
cursor: url("./magplus_cur.txt"), pointer;
}
.PopBoxImageLarge
{
border: solid thin #CCCCFF;
cursor: url("./magminus_cur.txt"), pointer;
}

ブログのprofileプラグインのHTMLを変更
<img src="<%image>" alt="<%author_name>"
pbsrc="./o_rly_thumbig.jpg"
class="PopBoxImageSmall"
onclick="Pop(this,50,'PopBoxImageLarge');" />
imgタグに直接onclikのイベントハンドラを設定することになるが、ここで画像ごとにいろんなオプションを変えることができる。


popbox.jsのサイトはPopBox! - Javascript Image Magnification
参考サイトはPopBoxの使い方 - ARK-Web SandBox Wiki





while(aho.atEndofStream)

笹部 政宏
笹部 政宏
mail




フリーソフツ
Category
はてブ
Monthly Archive
New Entry
New Comment
New Trackback
RSS
Copyright © Kittens flewby me All Rights Reserved.