トップ «前の日記(2008-10-26) 最新 次の日記(2008-10-28)» 編集

日々の破片

Subscribe with livedoor Reader
著作一覧

2008-10-27

_ SQLのDSL

自分のふりかえりは上に書いたので、他の発表者のセッションで印象的だったのはというと、桑田さんのマクロならクォート一発な処理をDSLとして……というやつなのだが、聞いているときはおもしろかったが、考えてみるとちょっと違うのではないだろうか。

マクロのエラーは(多くの場合)単なる文法エラーだが、DSLのエラーはアプリケーションエラーにできるからだ。

ということはどういうことか。

まず、SQLは別に文字列で書けば良いというのがある。埋め込みパラメータがあるかどうかにかかわらず。効率も良いし、それがネイティブインターフェイスだ。

わざわざそれを元の言語に組み込もうというからには、そこに何かのメリットがなければしょうがない。

そのメリットが何かといえば、書き間違いに対する手厚いケアではないかと思う。他に何かあるか? (ソースの見てくれというのはある)

としたら、ここに書き間違いがあるということが、一発でわかるような仕組みが良い。

それがマクロで可能なのか、というあたり。

_ HTA+dRuby

aikeさんのexelsv.htaを見ていて、ちょっと気になったのでいじってみた。というか、さっそくこういうのを作れるってのはすごいなぁ。かくありたいね。

気になったのは、「ブラウザに制御が戻らないや」のところ。いや、確かに戻らないし、逆に戻すとrubyを離れるのでdRubyが今度は動けない。だから正しいのだけど、HTMLのレンダラで、しかもScriptHostだということは、Windowsオブジェクトを持つということで、つまりはsetIntervalとsetTimerが利用できる。

というわけで、あまりかっこは良くないのだけど、次のように、シャットダウンボタンをつけることも可能。ついでに統計情報をちょっと取ってみるようにしてみたり。

<html>
<head><title>Excel Server</title>
<script language="RubyScript">
# ver 0.2 (correct ex order of counts, see #c01)
require 'drb/drb'
class ExcelServer
  def initialize
    @excel = WIN32OLE.new("Excel.Application")
    @excel.Visible = true
    @excel.SheetsInNewWorkbook = 1
    @book = @excel.WorkBooks.Add()
    @book.Application.DisplayAlerts = nil
    @sheet = @excel.Worksheets(1)
    @@singleton = self
  end
  def put(cell, str)
    count('put')
    @sheet.Range(cell).Value = str
  end
  def get(cell)
    count('get')
    @sheet.Range(cell).Value
  end
  def count(m)
    e = Window.document.getElementById("#{m}call")
    e.innerHTML = (e.innerHTML.to_i + 1).to_s
    end
  def shutdown
    Window.clearInterval($timer)
    Thread.new do
      close
    end.join
    Window.setTimeout(Proc.new{Window.close}, 1000, 'RubyScript')
  end
  def close
    @book.Close()
     @excel.Quit()
  end             
  def self.instance
    @@singleton
  end
end
 
def server_start()
  Window.resizeTo 400, 300
  uri = "druby://localhost:12345"
  DRb.start_service(uri, ExcelServer.new)
  $timer = setInterval(Proc.new{sleep(0.2)}, 200, 'RubyScript')
end
</script>
</head>
<body onload="server_start" language="RubyScript">
<h1>
 <center>
  <input type="button" onclick="ExcelServer.instance.close;Window.close" value="shutdown" language="RubyScript"/>
 </center>
</h1>
statistics
<table>
 <tr><th>method</th><th>call</th></tr>
 <tr><td>put</td><td id="putcall">0</td></tr>
 <tr><td>get</td><td id="getcall">0</td></tr>
</table>
</body>
</html>

setIntervalを使う場合は、最初はインターバルをうんと長め(5秒とか10秒とか)にしておいて、デバッグが終わってから本来の長さにすると良いです。というのは、タイプミスなどがあると、あっというまにブラウザクラッシャー状態になってしまうからです。

#途中でcloseメソッドを共通化したくてシングルトンに無理やりしたのでおかしいけど気にしないように。いくらでもnewできるし。

#追記:aikeさんの指摘箇所を修正

#追記2:@timerってどう考えてもバグ。あとで修正予定。→直した。グローバル変数を使う

本日のツッコミ(全2件) [ツッコミを入れる]
_ aike (2008-10-28 03:46)

さすが!そうそう、こういうことがやりたかったのです。<br>当日実演されたsamples\hta\evlog.htaもソースを読むと<br>setTimeoutを上手いこと使ってますね。<br><br>ところでgetメソッドの<br> @sheet.Range(cell).Value<br> count('get')<br>は上下入れ替えないとセルの値ではなく<br>カウンタ値が返っちゃう気がします。<br><br>また機会がありましたら札幌にいらしてください。

_ arton (2008-10-28 08:20)

これ、いいですね。dRubyで遊ぶときって、コンソール×2で切り替えてやっていたのですが、サーバーをHTAにすると最初にサーバーを実行しておいて、あとからクライアントを実行するというのが1つのコンソールでできるので、目からうろこでした。<br>>カウンタ値が返っちゃう気がします。<br>ありがとうございます。文句なしのバグです。修正しました。


2003|06|07|08|09|10|11|12|
2004|01|02|03|04|05|06|07|08|09|10|11|12|
2005|01|02|03|04|05|06|07|08|09|10|11|12|
2006|01|02|03|04|05|06|07|08|09|10|11|12|
2007|01|02|03|04|05|06|07|08|09|10|11|12|
2008|01|02|03|04|05|06|07|08|09|10|11|12|
2009|01|02|03|04|05|06|07|08|09|10|11|12|
2010|01|02|03|04|05|06|07|08|09|10|11|12|
2011|01|02|03|04|05|06|07|08|09|10|11|12|
2012|01|02|03|04|05|06|07|08|09|10|11|12|
2013|01|02|03|04|05|06|07|08|09|10|11|12|
2014|01|02|03|04|05|06|07|08|09|10|11|12|
2015|01|02|03|04|05|06|07|08|09|10|11|12|
2016|01|02|03|04|05|06|07|08|09|10|11|12|
2017|01|02|03|04|05|06|07|08|09|10|11|12|
2018|01|02|03|04|05|06|07|08|09|10|11|12|
2019|01|

ジェズイットを見習え