Ruby on HTA
少し触っただけだけども、HTA + ActiveScriptRubyにぐっときた。
VisualuRubyよりも、もっともっとサクサク簡単なGUIを作りたいときに便利っぽい。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="jp" lang="ja-JP"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <title>サンプル</title> <script for="window" event="onload" language="RubyScript"> @window.resizeTo(400, 100) def btnOk_onclick @window.document.getElementById("lblOutput").innerHTML = "Hello World!!!" end </script> </head> <body> <input id="btnOk" type="submit" value="OK" onclick="btnOk_onclick" /> <span id="lblOutput">...</span> </body> </html>
ちょっとめんどくさい
イベントハンドラを定義したり(onclick="...")するのが面倒なんで、うまいことできないか考え中。
んで、とりあえずidが付いている要素にイベントハンドラを定義するような仕組みを作ってみた。
ついでにHTAにスタイルを設定してもっとネイティブのアプリっぽく。
hta-support.rb
class HTASupport # イベントハンドラ一覧 EVENTHANDLERS = [ "onblur", "onfocus", "onchange", "onselect", "onselectstart", "onsubmit", "onreset", "onabort", "onerror", "onload", "onunload", "onclick", "ondblclick", "onkeyup", "onkeydown", "onkeypress", "onmouseout", "onmouseover", "onmouseup", "onmousedown", "onmousemove", "ondragdrop" ] def initialize(window) @window = window set_event_handler end # idを持つ要素すべてにイベントハンドラを設定します def set_event_handler body = _d.getElementsByTagName("body").item(0) set_event_handler_recursive(body) end # idを持つ要素すべてにイベントハンドラを設定します def set_event_handler_recursive(elem) # Element以外だったら終了 return if elem.nodeType != 1 id = elem.getAttribute("id") if id != "" EVENTHANDLERS.each do |name| handler_name = "#{id}_#{name}" elem.attachEvent(name, Proc.new { if methods.include?(handler_name) __send__(handler_name) end }) end end # 子要素も処理する elem.childNodes.each do |i| set_event_handler_recursive(i) end end # windowへのショートカット def _w @window end # window.documentへのショートカット def _d _w.document end # window.document.getElementByIdへのショートカット def _e(id) _d.getElementById(id) end end
sample.rb - このファイルに処理を実装する
require "hta-support" class Sample < HTASupport def btnOk_onclick _e("lblOutput").innerHTML = "HelloWorld!!" end end
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="jp" lang="ja-JP"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <title>サンプル</title> <style> body { background-color: ButtonFace; } </style> <script for="window" event="onload" language="RubyScript"> require "sample" Sample.new(@window) @window.resizeTo(400, 100) </script> <hta:application applicationname="サンプル" version="1.0" singleinstance="no" showintaskbar="yes" navigable="no" windowstate="normal" border="dialog" innerborder="no" borderstyle="normal" contextmenu="yes" selection="yes" scroll="no" scrollflat="no" caption="yes" icon="explorer.exe" sysmenu="yes" maximizebutton="no" minimizebutton="yes" /> </head> <body> <input id="btnOk" type="submit" value="OK" /> <span id="lblOutput">...</span> </body> </html>
はまりどころ
openが何かの名前と衝突してるっぽくてうまく使えなかった。
そのときはKernel.openとすれば期待通りに動作する。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="jp" lang="ja-JP"> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <title>サンプル</title> <script for="window" event="onload" language="RubyScript"> @window.resizeTo(400, 100) def btnOk_onclick open("a.txt", "w") do |f| f.puts "aaa" end end </script> </head> <body> <input id="btnOk" type="submit" value="OK" onclick="btnOk_onclick" /> <span id="lblOutput">...</span> </body> </html>
ORって遅いのね
ひさしぶりに、とあるシステムのパフォーマンスをチューニングしてみた。
Ludiaで全文検索インデックスを使ってみたり、ORM任せにしないで自前でSQLを書いたりで、だいぶさくさく動くようになったっぽい。
知らなかったことがあったのでメモ。ORって遅いのね。
同じ結果を返すようにUNIONで組んだSQLと比べると、36倍程度の差があった。
以下で使用しているテーブルの行数はだいたい
products ... 9万件
product_specs ... 50万件
-- 2.16秒/70件 SELECT DISTINCT a.* FROM products a inner join product_specs b on b.product_id = a.id WHERE a.title @@ 'テスト' OR b.value @@ 'テスト' ORDER BY date desc
-- 0.06秒/70件 SELECT a.* FROM products a WHERE a.title @@ 'テスト' UNION SELECT a.* FROM products a inner join product_specs b on b.product_id = a.id WHERE b.value @@ 'テスト' ORDER BY date desc
ちなみにORもUNIONも使わずに、片方の条件で検索をかけると0.03秒。ORは本当に遅すぎ。
こんなに違うと、さすがに体感にもだいぶ差が出た。
VAIO type P ファーストインプレッション
実は1月末に注文していたtype P。
予定では2月下旬に発送予定でしたが、2月17日には発送の連絡があり、2月18日に届きました。
type Pについては既に他のブログやニュースサイト語られてはいますが、備忘録的な意味で残しておきたいと思います。
デスクトップ
上の画面はセットアップ直後のデスクトップ。
メーカー製PCは久しぶりに買ったけど、前に買ったLavieよりシンプルな気がする。
それでも変なガジェットとかはあるけどさ。
タスクトレイも、ひどいことにはなってない。左から順に
- Bluetooth (無線で外部機器と接続)
- PlaceEngine (無線LANの電波で位置情報を把握)
- McAfee (ウイルス対策ソフト)
- VAIO Update (VAIOのソフトウェア更新)
- Windowsサイドバー
- (なんだっけこれ、わすれた)
- ノイズキャンセリング
だったはず。たしか。
起動
電源OFFからの起動は遅いけど普通の遅さ。おーそーいーってほどじゃない。
会社で使ってるCore2DuoのVistaよりは遅い程度。
スリープからの復帰は2〜3秒。
これを常用するとおもう。
休止状態からの復帰は体感でだけど起動と同じ〜起動よりも時間がかかる印象。
絶対とは言わないけど、使わないとおもう。
インスタントモードの起動は10秒くらい。
早い。けどもたぶん使わない。詳細は次で。
インスタントモード
ローカルにあるファイルしか再生できないっぽい。
ほかのPCでファイル共有してあるファイルは再生できない。(とおもう)
type Pには音楽や動画を置かないで、別のPCにある動画や音楽を再生する、っていう用途には使えないっぽい。
おれはそういった使い方がしたかったので、おそらく現状のインスタントモードは使わない。
ウェブはFirefoxで見れるけど、フォントがフリーフォント。たぶん。汚い。
そしてブラウジングが遅くてイライラする。
これらの点、アップデートで改善されるかなあ。
ネットワーク接続
クライアントマネージャVをインストールして、AOSSで無線LANを設定。難なく接続できた。
http://buffalo.jp/download/driver/lan/clmg5.html
インターネット
標準のIE7だと遅すぎてイライラした。
要カスタマイズ。
メディア再生
VAIO Media Plusはインスタントモードと同じで、ほかのPCでファイル共有してあるファイルは再生できない。(きがする)
要カスタマイズ。
そのた
初回セットアップ完了後には常駐しなくても、起動すると常駐設定になるソフトが結構あったきがする。
「VAIO モバイル TV」とか「VAIO Media Plus」とか。
そういうところはマイナスかな。面倒くささ的な意味で。
結局どうなの
性能が出ないのはわかりきったことだったので、「やっぱりかー」とか「お、意外といいかも」といった印象でした。
快適に使うためにはカスタマイズが必須だと思います。
標準のレイアウトフレームが不満なので、簡単なレイアウトフレームを作ってみる
背景
おれは仕事用のツールをrubyで作ることが多いんだけれども、近頃はプロジェクトメンバに使ってもらうツールを作る機会も増えてきた。
自分で使うならまだしも、使ってもらうとなるとCUIでは不親切。GUIを作りたい気持ちが出てくるもんだ。
そこで、前々から存在は知っていたけれども使ったことがなかった、VisualuRubyに手を出した。
イベントを拾うのはらくちん
イベントを拾うのはホントにらくちん。
[xxx_clicked]等のメソッドを定義するだけでイベントを拾える。VBちっくで超らくちん。
そこで本題
思い立って、コントロールの幅や高さを変えないレイアウトフレームを作ってみた。
また、中に入っているコントロールのサイズにより、レイアウトフレームのサイズを拡張する。
なんとなくHTMLちっくなレイアウトができる。
まだ実戦投入はしてない(そもそもVisualuRubyもまだ実戦投入はしてない)けれども、なかなか便利そうだから公開してみる。
もうちょいらくらくにできそうな気がするので、やる気がある限り突き詰めてみる。
ソース
#!ruby -Ks $KCODE="s" require "yaml" require "vr/vrcontrol" require "vr/vrlayout2" class MyLayoutFrame < VRLayoutFrame attr_accessor :padding def w @_vr_lw end def h @_vr_lh end def initialize super @padding = 4 end end class MyHorizLayoutFrame < MyLayoutFrame def _vr_relayout x = 0 @_vr_layoutclients.each do |i| i.move(@_vr_lx + x, @_vr_ly, i.w, i.h) x += i.w + @padding @_vr_lw = x @_vr_lh = [@_vr_lh, i.h].max end end end class MyVertLayoutFrame < MyLayoutFrame def _vr_relayout y = 0 @_vr_layoutclients.each do |i| i.move(@_vr_lx, @_vr_ly + y, i.w, i.h) y += i.h + @padding @_vr_lw = [@_vr_lw, i.w].max @_vr_lh = y end end end class Form < VRForm def construct # # メモ # 位置はレイアウトフレームが決めてくれるから、 # addControlではサイズのみを指定すればよい(位置はx=0, y=0でよい) # addControl(VREdit, "edit", "", 0, 0, 120, 24) addControl(VRButton, "button", "検索", 0, 0, 50, 24) @lm1 = MyHorizLayoutFrame.new @lm1.register(@edit, @button) addControl(VRText, "text", "", 0, 0, 400, 200) @lm2 = MyHorizLayoutFrame.new @lm2.register(@text) addControl(VRButton, "xxxbutton1", "機能1", 0, 0, 100, 24) addControl(VRButton, "xxxbutton2", "機能2", 0, 0, 100, 24) addControl(VRButton, "xxxbutton3", "機能3", 0, 0, 100, 24) @lm3 = MyHorizLayoutFrame.new @lm3.register(@xxxbutton1, @xxxbutton2, @xxxbutton3) @lm = MyVertLayoutFrame.new @lm.register(@lm1, @lm2, @lm3) self.caption = "レイアウトフレームのテスト" self.move(0, 0, 408, 286) end end VRLocalScreen.start(Form)
P5Q-EにVine-4.2はダメだった。CentOS-5.2は大丈夫。
表題のとおり。
友人からP5Q-Eを安値で譲ってもらったため、この土日を使ってサーバ機のハードウェアを換装した。
それに伴い、OSも再インストールすることにした。
OSには今と同じVinelinuxの4.2を使おうとしていたんだけども、どうにもインストール時にHDDを認識してくれない。
最初にeSATAで接続したHDDにインストールしようとしていたのだけど、それが原因でもなく、SATAに接続してチャレンジしたけどダメだった。
原因はlinuxに詳しくないのでよくわからないんだけども、ICH10RとかMarvellの、SATAコントローラのドライバが無いみたい。
半日格闘した末、あきらめてCentOSの5.2をインストール。
こちらはすんなりeSATAで接続したHDDを認識してくれた。
DB移行して、SVN移行して、APP移植して。
結構な大仕事でしたが、案外すんなり移行できました。
どうなることかと思いましたが、とりあえずよかった。