LINQ to EntitiesのWhereとFirstに別々に条件を与えると並び順がおかしくなる
本日の災難RubyとPostgreSQL
- VACUUMって部分的にできるの?できるなら毎晩ちょっとずつ実行するようにする。
- 代替機を用意し、その間にVACUUMを済ます。代替機にたまった履歴は破棄。
- システム完全停止。VACUUM FULL実行。終わるまで待ってもらう。
[root@localhost ~]# free total used free shared buffers cached Mem: 2075444 2021844 53600 0 21848 1702788 -/+ buffers/cache: 297208 1778236 Swap: 2031608 112 2031496
IsolationLevel.ReadCommittedが安全なケース
C#のプロパティに初期化の方法があればいいのにと思った
C#のプロパティは宣言と一緒に初期値指定することはできない。フィールドと組み合わせるか、コンストラクタで初期化するとかしないといけない。
class Person
{
string _Name = "名無し"; // フィールドでやるか
public string Name
{
get
{
return _Name;
}
set
{
_Name = value;
}
}
public Person()
{
Name = "名無し"; // コンストラクタでやるか
}
}
これまでは値をセットしたときにイベントを起こすとか、設定ファイルと連動させるときとかに使ったことがあったくらい。
もしかしたら次期バージョンではできるのかなと思って、「C# プロパティ 初期 .net framework 4.0」とかで調べてみるけど、無さそうですね。
そのかわりちょっと興味をひく記事を見つけました。
[C#]自動プロパティの必要性
[C#]自動プロパティの必要性(その2)
出水さんという方のコメント「アセンブリ公開するのがわかっていれば、もともとフィールドでは置かないですしね」
なるほど、先日からCOMを使っているので意味分かります。インターフェースにフィールドは置けないんですよね。メンバ変数みたいなのをCOMに公開したければパブリックプロパティを使う必要があります。
インターフェースに初期化データを置くというのも変な気がするので、その辺で初期化は導入されないのかもしれないですね。詳しいことは知りませんが。
DataGridViewをActiveXコントロールにラップしてTcl/Tkのウィンドウに埋め込む(2)
前回に引き続き、イベントの定義をやってみました。
DataGridViewのボタンセルが押されたら、そのセルの行・列番号を引数にして、Tclのプロシージャをコールバックするということがしたい。
ソリューション一式: SimpleDgv.zip
まず、メソッドと別にインターフェースを用意して、InterfaceTypeをComInterfaceType.InterfaceIsIDispatchにします。
[Guid("1AE7D7D7-02EF-4d70-B7F5-71CE046FAEA9"), ComVisible(true), InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
public interface ISimpleDgvDispatch
{
void ButtonClick(int col, int row);
}
そして、クラスの属性にComSourceInterfaces(“ISimpleDgvDispatch”)を追加し、クラスにButtonClickイベントを定義します。
[Guid("29E1BC35-88D3-47f0-997D-B889CA25E135"), ComVisible(true), ClassInterface(ClassInterfaceType.None), ComSourceInterfaces(typeof(ISimpleDgvDispatch))]
public partial class SimpleDgv : UserControl, ISimpleDgvInteface
{
public delegate void ButtonClickDelegate(int col, int row);
public event ButtonClickDelegate ButtonClick;
protected void OnButtonClick(int col, int row)
{
if (ButtonClick != null)
{
ButtonClick(col, row);
}
}
}
ビルドするとCOMとして公開されました。
Tcl側のコード
proc ButtonClick {col row} {
tk_messageBox -type ok -message "Callback Col=$col, Row=$row"
}
optcl::bind $dgvObj ButtonClick ButtonClick
さあ、どうでしょう?
イベントを実行したC#側で例外が発生しました。例外テキストからはSystem.RuntimeType.InvokeDispMethodに渡されるcultureが不明なものであったということだろうと解釈できますが、だからといってどうすればよいというのでしょう?
DISP_E_UNKNOWNLCIDとはなんぞや?ググっても文字通りの説明しか出てきません。
AssemblyInfo.csでCultureInfoを指定したりもしてみたが、何も変わらない。
これで丸1日試行錯誤したものの、全く原因も解決法も分からず途方にくれました。
どうしよう。引っ込みがつかない。
2009/9/8 -- 追記: 成功
.Net Framework フォーラムで質問したらjzkeyさんが回答をくれました。
動くようになったoptclのバイナリとソースを置いておきます。
http://yyamasak.drivehq.com/devel/src/tcl/lib/optcl3010t-bin.zip
http://yyamasak.drivehq.com/devel/src/tcl/lib/optcl3010t-src.zip
optclがビルドできるようになったので、とりあえずBase64でのやり取りで妥協したマルチバイト引数の件も調べれば何とかなるかもしれないという希望が出てきました。
DataGridViewをActiveXコントロールにラップしてTcl/Tkのウィンドウに埋め込む(1)
2009/9/2 -- 追記: とりあえずC#の側で解決しました。
byte[] b = Encoding.Default.GetBytes(s);
string u = Encoding.UTF8.GetString(b);
要するに、TclはUTF-8をデコードして送ってるのに、C#はシステムのデフォルトエンコーディング(Shift_JIS)としてエンコードしてるようなのです。
だからその逆をたどってやればよいわけで、まず文字化けした文字列をShift_JISとしてバイト列に戻します。これをUTF-8エンコードしてやることで、本来の文字列に戻してやることができるという理屈です。ただし、これはもともとUTF-8で送ってくるクライアントにしか対応できません。2行目が決めうちだからです。
2009/9/2 -- 追記: やっぱだめ
うまくできたと思ったのはひらがなだけで、漢字やカタカナは一部が文字化けしてしまいました(例: 選択 -> 選・)。
ここによれば、一度間違って変換されたものは可逆性を失うようです。
http://dobon.net/vb/dotnet/string/getencoding.html
最初から不可逆なんだからC#で直すことはできないってことになる。
あとはTclからそもそもShift_JISで送れるようにするか、base64でASCIIとして送って、デコードするかしかなさそう。
2009/9/2 -- 追記: 成功
やっぱりbase64でやることにした。いちいち変換しないといけなくてめんどいけど、しょうがあるまい。
Tcl側のポイントは、マルチバイト文字を含む場合は一旦バイナリに変換しないといけないこと。encoding converttoを使う。
C#側はShift_JISのASCII部分だけ使うので、情報の損失がなくなった。返すときは任意のエンコーディングでかまわないようだが、Tcl側で対称性を持たせるためにシステムデフォルト(Shift_JIS)で返すようにした。
Tcl側のコード(エンコーディング省略でシステムデフォルト)
proc dec {s} {
::base64::encode [encoding convertto $s]; # Tcl -> C#
}
proc enc {s} {
encoding convertfrom [base64::decode $s]; # C# -> Tcl
}
C#側のコード
namespace Extension
{
public static class StringMethod
{
public static string Dec(this string s, Encoding encoding) // Tcl -> C#
{
var b = Convert.FromBase64String(s);
b = Encoding.Convert(Encoding.Default, encoding, b);
return encoding.GetString(b);
}
public static string Enc(this string s) // C# -> Tcl
{
var b = Encoding.Default.GetBytes(s);
return Convert.ToBase64String(b);
}
}
}
- イベントの定義(ボタンクリックとか)
- クリップボード操作(CSV/TSVプレーンテキスト)
- その他もろもろ
TkTableのバインディングを修正した
TkTableはdllで配布されていますが、ヘルプに説明のあるデフォルトのバインディングはlib/Tktable2.9/tkTable.tclに書かれているようです。
このファイルは特にデモアプリなどで使われているわけではなく、単にカスタマイズする人のために内部の実装を見えるようにしたものだと思われます。
TkTableはオプションで-selectmode extendedを指定することでドラッグによる範囲選択ができるようになるのですが、セル領域とタイトルセル領域にまたがってドラッグした場合、選択領域がばらばらになってしまうという問題がありました。
最新の2.10に添付されたtkTable.tclも全く変わってなかったので、修正してみました。ただ、過去の選択部分だけをクリアするような処理を、全域クリアに変えてしまったので、パフォーマンス的には問題ありの可能性もあります。ためしに3000行×50列とかでやってみたところでは全く問題ありませんでした。
--- C:/Tcl/lib/Tktable2.9/tkTable.tcl Tue Aug 25 20:01:59 2009 +++ C:/devel/tcl/tktable/tkTable.tcl Fri Aug 28 18:59:51 2009 @@ -433,26 +433,54 @@ if {[catch {$w index anchor}]} { return } scan $Priv(tablePrev) %d,%d r c scan $el %d,%d elr elc - if {[$w tag includes title $el]} { - if {$r < [$w cget -titlerows]+[$w cget -roworigin]} { - ## We're in a column header - if {$c < [$w cget -titlecols]+[$w cget -colorigin]} { - ## We're in the topleft title area - $w selection clear anchor end - } else { - $w selection clear anchor [$w index end row],$c - } - $w selection set anchor [$w index end row],$elc - } else { - ## We're in a row header - $w selection clear anchor $r,[$w index end col] - $w selection set anchor $elr,[$w index end col] + + set titlerowend [expr {[$w cget -titlerows]+[$w cget -roworigin]}] + set titlecolend [expr {[$w cget -titlecols]+[$w cget -colorigin]}] + if {$r != $elr} { + if {$r < $titlerowend} { + if {$elr >= $titlerowend && $r >= $titlerowend} { + set elr $r; # turn aside while selecting title row area + } + } else { + if {$elr < $titlerowend && $r < $titlerowend && $elc >= $titlecolend} { + set elr $r; # turn aside while selecting non-title row area + } + } } + if {$c != $elc} { + if {$c < $titlecolend} { + if {$elc >= $titlecolend && $c >= $titlecolend} { + set elc $c; # turn aside while selecting title col area + } + } else { + if {$elc < $titlecolend && $c < $titlecolend && $elr >= $titlerowend} { + set elc $c; # turn aside while selecting non-title col area + } + } + } + $w selection clear all + if {[$w tag includes title $r,$c]} { + if {$r < $titlerowend} { + if {$c < $titlecolend} { + ## We're in the topleft title area + if {$elc >= $titlecolend} { + $w selection set anchor [$w index end row],$elc + } else { + $w selection set anchor $elr,[$w index end col] + } + } else { + ## We're in a column header + $w selection set anchor [$w index end row],$elc + } + } else { + ## We're in a row header + $w selection set anchor $elr,[$w index end col] + } + set Priv(tablePrev) $elr,$elc } else { - $w selection clear anchor $Priv(tablePrev) - $w selection set anchor $el + $w selection set anchor $el + set Priv(tablePrev) $r,$c } - set Priv(tablePrev) $el } } }
Tcl/TkからC#へ
大学でC++に挫折して、プログラマはあきらめていた私はサークルのホームページでPerl/CGIを使ったのをきっかけに再びプログラミングに手を染めることになりました。
それでも仕事で使えるレベルではないだろうと、会社に入った時点ではプログラマになることは断っていたのですが、会社のCRM立ち上げに携わった後に部署がなくなり、開発部にまわされました。
最初にやったのがカメラのPTZ制御プログラムにPELCO-Dプロトコルを追加するというC++の小さな案件でした。それはそれっきりで、次にやったのがTcl/Tkのタッチパネル式のGUIアプリケーションをベースにした開発案件でした。それ以来、3年ほどWindowsアプリケーションをTcl/Tkで作ることになりました。
Tclの自由度は高く、XOTclなどでオブジェクト指向言語のようにも使えます。C#のクラスはプロパティやメソッド以外にイベントというメンバを持つことができるのですが、これだってTclからすればさして特別な機能ではありません(コンテキストのキャプチャは確かに難しいですが)。Ruby on RailsのActiveRecordのようにスキーマを自動的にマッピングする機能はType-safeな方法では実現できないので、C#には同様のライブラリは存在しません(全てを文字列として扱えばよいだけなので、不可能というわけではないです。誰もやらないというだけで)が、Tcl/Tkでコンセプトを真似た簡易版を作って使っています。
しかし、Tcl/Tkの言語本体はそこそこのスピードで進化していくものの、ライブラリ群は放置されてるものが多いです。また、2002年くらいを境に日本語の書籍の発行は途絶えています。オブジェクト指向拡張はあるものの、Rubyみたいに自由度の高いXOTclにはActiveTclのIDEやデバッガが対応していません。
Tclは世間のうわさに反して優れた言語だと思うし、そこそこライブラリも充実してはいるのですが、やはり完璧なアプリを作るに当たって、いろいろと問題があるのは否めません。
BLT Toolkitはすばらしい拡張ライブラリですが、Tcl/Tkの最新版に対応していません。stubに対応すべくGeorgeさんががんばって更新しているようですが、依然完成のめどが立たない状況が続いてます。
ほかにも結構重要なライブラリがちょっとしたバグを残したまま放置された状態です(TclUDP, Tktableとか) 。
teapot化されたライブラリをEXEにラップするにはTclAppをバージョンアップしないといけないし。
新規開発に関しては既にTcl/Tkをあきらめて、C#を採用しています。Tclの自由度に比べれば堅苦しさは否めませんが、.NET Frameworkなら高品質なGUIが開発できるので、安心してお客さんに見せられます。
Tcl/Tkには印刷ダイアログを表示する機能がありません。DataGridView並みに高度なGUIがありません。TkTableやTablelistがあるじゃないか、というかもしれませんが、これらはDataGridViewに比べて非常にプリミティブです。
大学の研究室や社内で使うならまだしも、簡単にGUIを作れるというのは、現代においてもはや売り文句にならない気がします。
C#などのGUIを生かしつつTclの既存アプリを再利用することはできないのでしょうか?これについてはいろいろと調べてきましたが、なかなか有効な手段は見つかりません。WindowsであればCOMの仕組みを使うことで何とかいけるみたいな話(optcl)はありますが、果たして実際にやった人はいるのでしょうか?
エクスポート関数はともかく、引数の型が構造体だったりして、構造体のメンバがさらに構造体だったりしたら、どうするの?とか。
C++の方が相性はいいだろう。MFC DataGridというのが使えたらいいけど、クラスのインポートってできるの?とか。
TclBridgeというのは?高いなあ。ちゃんとメンテされてるの?
Eagleは?Tclの再実装?うーんそういうことじゃないんだよなあ。
じゃあ何ができたらいいのでしょう?
ネイティブのTclに.NETのクラスライブラリをインポートして、publicなクラスや構造体を自由に操作したい。これだ!
私にCの知識と遊んでいても給料払ってくれる社長がいたら多少貢献できると思うのだけど。
・・・いや、無理。私では力不足です。
こうしてネットのところどころでこういうボヤキを書いているのは誰かが作ってくれるかもとちょっと期待してるからなんですが、まあ、そんな都合よくはいかないよな。。。日本語だから外人読めないし。
夢の対決 投手ロボVS.打者ロボ
これはたしかにすごいけど、投手ロボの立場が微妙だなあ。
仮に150キロの球を投げられるようになっても大リーグの投手にはかなわないけど、
そのボールを100%打てる打者の方がレアだから、打者ロボの方が先に人間を超えてしまう。
これでは、技術的には高度なはずの投手ロボの注目度が低くなってしまう。
だから、さらに発展させて三本指でキャッチするロボットを作って欲しい。
三本指で150km/hのキャッチボールとなると、まさにロボットって感じがする。
それに両方とも対等だからどちらかが注目度が低くなって悲しむこともないし。
http://headlines.yahoo.co.jp/hl?a=20090724-00000097-san-soci