Rubyで外部コマンドの出力をGtk::TextViewに表示
外部コマンドの出力をパイプで取得してそのままGTKのテキストビューに表示するプログラムを書いてみました。
単純な方法でやっているので、ただ単に標準出力を表示するだけですが、
リアルタイムに出力を取得しているので、少しずつ出力されるコマンドは少しずつ表示されるようになっています。
「ruby -v」を実行して、結果(Rubyのバージョン)を表示するコードを書いておきます。
IO.popenでパイプで接続してコマンドを実行し、それからeachで一行ずつ読み出して追加しています。
すぐに終わるコマンドではあまり関係ないかもしれませんが、すぐには終わらないコマンドで、一行ではなく一文字ずつ出力されるコマンドでは修正する必要があるかもしれません。
require 'gtk2' Gdk::Threads.init Gtk.init window = Gtk::Window.new window.set_size_request(320, 240) buffer = Gtk::TextBuffer.new view = Gtk::TextView.new(buffer) window.add(view) window.show_all thread = Thread.start { IO.popen("ruby -v") { |pipe| pipe.each { |line| buffer.insert_at_cursor(line) } } buffer.insert_at_cursor("プロセスが終了しました") } window.signal_connect("delete_event") { thread.kill Gtk.main_quit } Gtk.main thread.join
Haskellコンパイラ「jhc」をビルド
Haskellコンパイラの「jhc」をビルドしてみました。
Ubuntuでやってみました。
方法は、jhcの公式サイトの http://repetae.net/computer/jhc/building.shtml ここを参考に書いてみました。
必要なライブラリのインストール
jhc自身もHaskellで書かれているので、コンパイルにGHCが必要です。
さらに、Haskellライブラリ「binary」「zlib」「utf8-string」「readline」「fgl」が必要です。
これらのライブラリは、「sudo cabal install ライブラリ名 --global」としてインストールしましたが、これが正しいのかはよくわかりません。
さらに、Ubuntuのパッケージから「libghc6-regex-compat-dev」をインストールする必要がありました。これは普通にapt-getでインストールできます。
コンパイル
まずは適当なディレクトリで「wget http://repetae.net/dist/jhc-0.7.6.tar.gz」でソースをダウンロードしてから、
「tar xzf jhc-0.7.6.tar.gz」で解凍します。
コンパイルは普通に、configureとmakeを使ったコンパイルです。
./configure --prefix=/usr/local
make
makeの最後に、全てのソースのコンパイルが終わりリンクしている時(Linkingと出てきた時)に「Killed」というメッセージが出てきてしまいましたが、jhcが出来ていたので一応成功だと思います。
インストールも普通に「sudo make install」です。
Pureの「reduce」がすごい
Pure言語には、「reduce」というマクロがあります。(PureではLispのようなマクロが使える)
これは、「与えられた式をもう一度評価する」というマクロです。一見単純なようですが、たくさんの応用ができそうです。
簡単な使い方を紹介します。
foo expr = reduce expr with a = 10; end;
このように関数fooを定義します。
この関数は、「a=10が定義された状態でexprをもう一度評価してその結果を返す」という関数です。
「foo (2*a);」とすると、a=10が定義された状態で2*aが評価され、「2*10」となり、「20」が返ります。
さらに、
bar expr = (reduce expr with a = 2; end), (reduce expr with a = 4; end);
一行にまとめたので少し読みにくいですが、こんな関数も作れます。
「bar (10+a);」で、「12,14」が返ります。
これを利用すれば、さらにおもしろいプログラムが作れそうです。
括弧ゴルフにPureで挑んでみた
「どれだけ括弧を使わずに書けるか」を競う「括弧ゴルフに、Pureを使って挑戦してみました。
括弧は、「()」も「[]」も全く出てきません。0個です。
階乗は大きい数(intだとオーバーフローしてしまうもの)も普通に出てくるので、それに対応するのに苦労しました。
「$」を使ったり、一行にまとめるのではなくwhenを使ってローカル変数を使ったりしたので、普通はこんな書き方はしないと思います。
Pureには「実は演算子として実装されている」というものが多いので、うまく使えばいろいろな書き方ができそうです。
多分、もう少し綺麗な書き方ができたと思います。
using system; limit = flip sscanf "%d" $ argv!1 if argc == 2; limit = 1 if argc == 1; limit = throw invalid_argument otherwise; fact 0L = 1L; fact n = n * fact x when x = n - 1L; end; __show__ x::bigint = init $ str x; p x = printf "%s! = %s\n" $ a, b when a = str x; b = str $ fact x; end; do p $ 1..limit;
UbuntuでD言語からSDLとOpenGLを組み合わせて使ってみた。
方法はほとんど変わっていません。
ほぼメモのような感じなので、D言語でSDLやOpenGLを使う関係の記事はまとめたほうがよかったかもしれません。
ですが書き直すのが面倒なので書いてしまいます。
前回と前々回の作業を行った後に行ったので、それを前提に書いています。
ライブラリのインストールやD言語用ライブラリの準備は前回や前々回を読んでください。
コードを書いて使ってみる
ウィンドウタイトルを設定するSDL_WM_SetCaptionはC言語の関数なので、D言語のstringやnullがそのまま使えず苦労しました。
ウィンドウタイトルの英語には自信がないので、間違っているかもしれません。
import SDL; import opengl; import std.stdio; import std.string; void draw() { glClear (GL_COLOR_BUFFER_BIT); glBegin (GL_LINE_LOOP); glVertex2d (-0.9, -0.9); glVertex2d (0.9, -0.9); glVertex2d (0, 0.9); glEnd (); SDL_GL_SwapBuffers(); } void main() { if (SDL_Init(SDL_INIT_VIDEO) < 0) { writefln("SDL初期化エラー"); return; } SDL_WM_SetCaption(cast(char*)toStringz("Using SDL and OpenGL with D"), cast(char*)0); SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1); SDL_Surface *screen = SDL_SetVideoMode(320, 240, 32, SDL_OPENGL); if (screen == null) { writefln("画面初期化エラー"); return; } glClearColor(0.0, 0.0, 255.0, 0.0); int done = 0; SDL_Event e; while (!done) { while (SDL_PollEvent(&e)) { done = e.type == SDL_QUIT; } draw(); SDL_Delay(1000/30); } SDL_Quit(); }
コンパイルには、「dmd sdlgl.d -ISDL -Iopengl -L-lSDL -L-lGL」というコマンドを使いました。
コンパイルすると「sdlgl」という実行ファイルができます。
実行すると、青い背景に白い線で三角形が描画されます。
UbuntuでD言語からOpenGLとGLUTも使ってみた。
SDLの時の方法はSDL以外にも使えそうだったのでやってみました。
D言語用ライブラリの準備
「http://shinh.skr.jp/d/porting.html」の「OpenGL」をクリックしてzipファイルをダウンロードします。
そして、ダウンロードしたファイルを解凍すると「opengl」というディレクトリが出てくるので、
同じページの「glut」をクリックして「glut.d」をダウンロードし、それをopenglディレクトリの中に入れて、
そのopenglディレクトリを、適当に作っておいた作業用ディレクトリの中にコピーしておきます。
使ってみる
今回は、http://www.wakayama-u.ac.jp/~tokoi/opengl/libglut.html のコードを元に、
http://romanchu.blog105.fc2.com/blog-entry-191.html に書かれている方法を参考にしてD言語用にしたソースをコンパイルしてみます。
import opengl; import openglu; import glut; import std.string; char** args2argv(string[] args) { char **argv = cast(char**)new char*[args.length]; for (int i = 0; i < args.length; i++) { argv[i] = cast(char*)toStringz(args[i]); } return argv; } void display() { glClear(GL_COLOR_BUFFER_BIT); glFlush(); } void init() { glClearColor(0.0, 0.0, 1.0, 1.0); } int main(string[] args) { int argc = args.length; char** argv = args2argv(args); glutInit(&argc, argv); glutInitDisplayMode(GLUT_RGBA); glutCreateWindow(argv[0]); glutDisplayFunc(&display); init(); glutMainLoop(); return 0; }
これを作業用ディレクトリに「gltest.d」で保存し、
これを「dmd gltest.d -Iopengl -L-lglut -L-lGLU -L-lGL」でコンパイルすると「gltest」という実行ファイルができます。
実行すると、青く塗りつぶされたウィンドウが出てきます。
UbuntuにD言語コンパイラDMDとDSSSをインストールしてみる
最近D言語はあまりやっていなかったのですが、なんとなくやりたくなったのでインストールしてみました。
自分が行った方法を適当にまとめてみます。
「/opt/dmd2」の中にインストールされるようになっています。
DMDのインストール
まずは、「http://www.digitalmars.com/d/download.html」から「dmd.2.048.zip」をダウンロードして、
ダウンロードしたディレクトリで
unzip dmd.2.048.zip cd dmd2 sudo mv linux /opt/dmd2 sudo mv src /opt/dmd2/src
のようにしてインストールしました。
そして、シェルの設定に「export PATH=$PATH:/opt/dmd2/bin」を追加してパスを通しました。
DSSSのインストール
次に、「http://svn.dsource.org/projects/dsss/downloads/0.78/」から「dsss-0.78-x86-gnuWlinux.tar.bz2」をダウンロードして、
ダウンロードしたディレクトリに移動し、
tar jxvf dsss-0.78-x86-gnuWlinux.tar.bz2 cd dsss-0.78-x86-gnuWlinux sudo cp * /opt/dmd2 -R
このように解凍、インストールしました。
設定の変更
一番苦労したのがここです。
一部、http://www.dsource.org/forums/viewtopic.php?t=4490 ここを参考にして設定しました。
「/opt/dmd2/etc/rebuild/default」の「gdc-posix」を「dmd-posix」に書き換えて、
「/opt/dmd2/etc/rebuild/dmd-posix」の「cmd=dmd -version=Posix -c $i」の行を「cmd=dmd -c $i」に、
「cmd=dmd -L--start-group -L-lphobos $i -of$o」の行を「cmd=dmd -L--start-group -L-lphobos2 $i -of$o」に変えました。
さらに、
「/opt/dmd2/bin/dmd.conf」の「-I%@P%/../../src/phobos」を「-I%@P%/../src/phobos」に、
「-I%@P%/../../src/druntime/import」を「-I%@P%/../src/druntime/import」に変えれば設定完了です。