Kuinでポリモーフィズムできるか実験
昨日Kuin1.00がリリースされましたね。
ということで早速使ってみました。
と、その前にKuinってなんぞや?という人もいると思うので軽く説明。
ってか抜粋。
プログラミング言語Kuinは、「HSP並みに作りやすく、C++並みに実用的な言語」というコンセプト
で制作された、究極の言語です。 Kuinの主な特徴について以下に列挙します。
・ オブジェクト指向でありながら、可能な限りシンプルで解りやすい設計
・言語設計の美しさより、実用面での美しさを重視
・ポインタ、イテレータ、テンプレートなど、ややこしい概念はすべて排除(代替機能を用意)
・動的メモリは自動で解放されるので、解放処理が不要
・豊富な標準ライブラリ(3D描画なども簡単)
・コンパイル速度が爆速
・64bitネイティブ機械語を生成するので、実行速度も速い
・何もプログラムを書かなければ、自動でHello World!!になる
製作者はいわずとしれたくいなちゃん(@b2)
さて、ドキュメントにポリモーフィズムとかそこらへんのこと全然書かれていないので
使えるのかな?とか疑問に思ったので試してみた。
結論から言うと使えて以下の様な感じになる。
class Hoge() func method() do Dbg@Log("hoge") return end func end class class Foo(@Hoge) +func method() do Dbg@Log("foo") return end func end class func getInstance(id :int) : @Hoge if (id = 0) return #@Hoge else return #@Foo end if end func func Main() var a: @Hoge :: @getInstance(0) do a.method() do a :: @getInstance(1) do a.method() do Kuin@Stop() end func
迷った点はグローバルスコープのものはすべて@で修飾しなくちゃいけないということでしょうか?
関数やクラスも@で修飾しないといけません。それさえ気をつければあとはドキュメントにしたがって
直感どおりかけます。
ぱっと見気持ち悪いですがなれるとスラスラかけて良い。
次作るゲームにはKuin使おうと思う。
はてなのハイライトはやくKuinに対応しないかな...
巡検に来ています
こんにちは。いかろです。
一ヶ月更新しないというのもあれなので書く←
実は現在清澄演習林にいます。
学科の巡検で実地の地質図をつくるというもの
基本的に鍵層となる広域に追跡可能なテフラを探しそれから断層などの構造を推定していきます.
と口で言うのは容易なのですが
テフラを同定するの大変です。
ヒルも沢山。
帰ってきたらまた細かく書きます(じゃないと月あと数分で終わってしまう...
Phusion PassengerでAliasで設定できない理由
Redmineで最初Aliasでやろうとしてコケました。なんでだろ?と思ってソースコードを追ってみた記録。
Phusion Passengerの公式サイトを見てもRailsBaseURIで設定、シンボリックリンクを張れと書いてあるのでどうやらPassenger自体の仕様のようです。
どのサイト調べてもこうしろとはかいてあるけどなんで?というのは書いてない...
だれも気にならないんだろうか?それとも常識なんだろうか?...
いずれにせよわからないのはきもちわるいのでソースコードを追ってみることにしました。
Passengerフォルダ内のext/apache2/Configuration.cppに
AP_INIT_TAKE1("RailsBaseURI", (Take1Func) cmd_passenger_base_uri, NULL, OR_OPTIONS | ACCESS_CONF | RSRC_CONF, "Deprecated option.")
というRailsBaseURIを定義していそうな部分を見つけました。
このAP_INIT_TAKE1はマクロで第二引数にディレクティブを処理する関数のポインタが来るようです。
そこで次にcmd_passenger_base_uriの実装を探します。
cmd_passenger_base_uri(cmd_parms *cmd, void *pcfg, const char *arg) { DirConfig *config = (DirConfig *) pcfg; if (strlen(arg) == 0) { return "PassengerBaseURI may not be set to the empty string"; } else if (arg[0] != '/') { return "PassengerBaseURI must start with a slash (/)"; } else if (strlen(arg) > 1 && arg[strlen(arg) - 1] == '/') { return "PassengerBaseURI must not end with a slash (/)"; } else { config->baseURIs.insert(arg); return NULL; } }
と定義されていました。これを見てみるとDirConfig構造体のBaseURIsにパラメータを代入しています。
そこでDirConfig構造体の定義を探し見るとBaseURIsはstd::set
またコメントに「Per-directory configuration information.」とあるのでディレクトリごとの設定を保持する構造体のようです。
insertしているのでRailsBaseURIが複数回現れた場合は上書きされるのではなく追加されます。
次に実際にどう使われているのか調べてみます。
名前的にDirectoryMapper.hが怪しそうなので眺めているとDirectoryMapperというクラス内のautoDetectメソッド内に
/* Find the base URI for this web application, if any. */ const char *baseURI = findBaseURI(); if (baseURI != NULL) { /* We infer that the 'public' directory of the web application * is document root + base URI. */ publicDir = docRoot + baseURI; } else { /* No base URI directives are applicable for this request. So assume that * the web application's public directory is the document root. */ publicDir = docRoot; }
という部分がありました。Railsのpublicディレクトリを決定する動作のようです。
baseURIがnullではない場合
publicDir = docRoot + baseURI;
という処理が実行されます。
baseURIはなにが入っているか調べるためfindBaseURIメソッドの定義を見てみたところ、リクエストを解析してBaseURIの集合の中にマッチするものがあれば
それをchar*にして返すという処理をしていました。
ここでなぜAliasで設定できないかという理由がわかりました。
docRootはおそらくApacheのDocumentRootディレクティブで指定された文字列が入り、baseURIはRailsBaseURIで指定されたディレクトリがはいるのでAliasで設定されていてもpublicDirには影響を及ぼしません。
そのためRailsBaseURIで指定してあげる必要があります。
また、Aliasはリクエストが届いた際に振り分ける機能なためAliasを張ったディレクトリに対してRailsBaseURIを指定しても、
Passengerのほうはあくまで実際のファイルシステム上のフォルダを参照するためうまく働きません。
ということでシンボリックリンクをはってRailsBaseURIで指定してあげないといけません。
ということでした。
MySQL Connector/C++を導入してみた
MySQL Connector/C++を入れる機会があって少し悩んだのでメモ。
公式からソースコードをDLし*1makeするとmysql.hとerrmsg.hがみつからないと言われる。
ぐぐってみるとこれらはmysqlには含まれず、mysql-develに含まれるらしいので
sudo yum install mysql-devel
としてインストール。
そしてふたたび
cmake . make clean sudo make sudo make install
とすることでインストールできた。
念の為動作確認を行う。(ユーザ名・パスワードは適宜変更してください。)
#include<memory> #include<mysql_connection.h> #include<mysql_driver.h> #include <cppconn/resultset.h> #include <cppconn/statement.h> int main(){ auto driver = sql::mysql::get_mysql_driver_instance(); auto raw_con =driver->connect("localhost", "mysqluser", "mysqlpass"); auto con = std::shared_ptr<sql::Connection>(raw_con); auto raw_stmt = con->createStatement(); auto stmt = std::shared_ptr<sql::Statement>(raw_stmt); auto raw_res = stmt->executeQuery("SHOW DATABASES"); auto res = std::shared_ptr<sql::ResultSet>(raw_res); while (res->next()) { std::cout << res->getString("DataBase") << std::endl; } }
コンパイルは
g++ -lmysqlcppconn -std=c++0x main.cpp
とlibmysqlcppconnの場所を教えてあげないといけない。
コンパイルできたら実行してデータベース一覧が表示されれば成功。
ちなみにMySQL Connector/C++を叩かなくてもWt::DboというORマッパーが存在するのでそちらを利用したほうが通常は捗るような気がする。
*1:ユーザ登録しなくちゃいけなかったりとひじょーにだるい。めったにDLしないからパスワードとか忘れるし...改善して欲しい
起動スクリプト(httpd)を読んでみた
シェルスクリプトの勉強がてら/etc/init.d/httpdを読んでみました。
. /etc/rc.d/init.d/functions if [ -f /etc/sysconfig/httpd ]; then . /etc/sysconfig/httpd fi
この部分で別の関数などを定義したファイルをインクルードしています。
正確には.コマンドは実行中のシェルと同じシェルで実行するというコマンドなので実行された段階で読み込まれ、他の言語で言うところのインクルードされたようにみえています。
読み込んでいる/etc/rc.d/init.d/functionsはinit.dでつかう汎用的な関数をまとめたものです。
また、/etc/sysconfig/httpdはhttpdを制御するための定数を定義したファイルとなっています。(デフォルトではすべてコメントアウトされていました。)
if文ではこのファイルがあるかどうかを-f演算子でチェックし、存在すれば読み込むという処理をしています。
HTTPD_LANG=${HTTPD_LANG-"C"}
ここでは言語の設定をしています。${HTTPD_LANG-"C"}の部分はHTTPD_LANGが定義されていればその値を
されていなければ"C"を返します。
それをHTTPD_LANGに代入することでデフォルトで"C"で設定ファイルで設定されていればそっちを優先するということをしています。
INITLOG_ARGS=""
これはコメントによるとmod_sslを使う際にパスフレーズが要求されたのがlogに残るのを防ぐために設定するようです(英語自信ない...)
ただinitlogが非推奨になっていて使われていないようなのであまり関係ない部分な気がしました。
apachectl=/usr/sbin/apachectl httpd=${HTTPD-/usr/sbin/httpd} prog=httpd pidfile=${PIDFILE-/var/run/httpd/httpd.pid} lockfile=${LOCKFILE-/var/lock/subsys/httpd} RETVAL=0 STOP_TIMEOUT=${STOP_TIMEOUT-10}
先ほどと同じようにディレクトリやファイル、タイムアウト時間などデフォルトの設定を設定しています。
これも設定ファイルで設定されていればそちらを優先します。
次にstart,stop,reroadという起動スクリプトの根幹部分の関数定義が来ます。
start() { echo -n $"Starting $prog: " LANG=$HTTPD_LANG daemon --pidfile=${pidfile} $httpd $OPTIONS RETVAL=$? echo [ $RETVAL = 0 ] && touch ${lockfile} return $RETVAL }
start関数は名前の通り起動処理をします。
echo -n $"Starting $prog: "
echoの-nオプションは最後の改行を出力しないというオプションです。
また$""という形式になっていますがこれはこの部分が翻訳対象であることを明示しています。
翻訳データ自体は/etc/rc.d/init.d/functionのTEXTDOMAINでよみこみ先が指定されています。
LANG=$HTTPD_LANG daemon --pidfile=${pidfile} $httpd $OPTIONS RETVAL=$?
ではhttpd本体をdaemon関数(/etc/rc.d/init.d/function)を用いてデーモンとして起動しています。
また、--pidfileオプションでPIDファイルの出力先を決めています。また最初のLANGの部分でhttpdを起動する言語を指定しています。
またRETVALはreturn valueの略語のようでそのとおり$?で前のコマンドの終了コードを代入しています。
echo [ $RETVAL = 0 ] && touch ${lockfile}
つぎにechoで改行を入れ、そのあとの部分でRETVALが0ならばロックファイルを生成する(orタイムスタンプを更新)という処理をしています。
ロックファイルは起動スクリプト内のどこにも存在をチェックしている部分がないのでおそらくhttpd内部で処理をしている気がします。
stop() { echo -n $"Stopping $prog: " killproc -p ${pidfile} -d ${STOP_TIMEOUT} $httpd RETVAL=$? echo [ $RETVAL = 0 ] && rm -f ${lockfile} ${pidfile} }
次はhttpdを停止するstop関数です。
基本的な流れとしてはstopしていることを表示し、killprocによってプロセスを殺します。
そして正常に殺せた場合はlockfileとpidfileを削除します。
reload() { echo -n $"Reloading $prog: " if ! LANG=$HTTPD_LANG $httpd $OPTIONS -t >&/dev/null; then RETVAL=6 echo $"not reloading due to configuration syntax error" failure $"not reloading $httpd due to configuration syntax error" else # Force LSB behaviour from killproc LSB=1 killproc -p ${pidfile} $httpd -HUP RETVAL=$? if [ $RETVAL -eq 7 ]; then failure $"httpd shutdown" fi fi echo }
つぎは設定ファイルを読み込むreload関数です。
if ! LANG=$HTTPD_LANG $httpd $OPTIONS -t >&/dev/null; then
の部分ではhttpdを-tオプションをつけ実行して結果を捨てています。
- tオプションをつけると文法チェックをしてくれるのでこのif文では
文法エラーがあったらthenの部分を実行します(!で結果を反転させているため)
RETVAL=6 echo $"not reloading due to configuration syntax error" failure $"not reloading $httpd due to configuration syntax error"
の部分を実行します。この部分では返り値を6とし文法エラーがある旨を出力します。
文法エラーがなかった場合
LSB=1 killproc -p ${pidfile} $httpd -HUP RETVAL=$? if [ $RETVAL -eq 7 ]; then failure $"httpd shutdown"
の部分でkillprocによりhttpdにHUPシグナル(子プロセスは殺すが、親プロセスは殺さない)が送られます。
そしてその結果を見て成功かどうかを表示します。
関数の定義が終わると引数によるパターンマッチを行なって適切な関数へのディスパッチをおこなう処理に入ります。
case "$1" in start) start ;; stop) stop ;; status) status -p ${pidfile} $httpd RETVAL=$? ;; restart) stop start ;; condrestart|try-restart) if status -p ${pidfile} $httpd >&/dev/null; then stop start fi ;; force-reload|reload) reload ;; graceful|help|configtest|fullstatus) $apachectl $@ RETVAL=$? ;; *) echo $"Usage: $prog {start|stop|restart|condrestart|try-restart|force-reload|reload|status|fullstatus|graceful|help|configtest}" RETVAL=2 esac
第一引数でパターンマッチを行なっています。start,restart,reload(force-reload)は基本的に先ほど定義した関数を組み合わせているだけです。
condrestartはプログラムが実行中であるかどうかを判定して実行中である場合のみ再起動、gracefulはapachectlに丸投げしています。
また、それ以外の場合はマッチするものがなかった旨を表示します。
最後に
exit $RETVAL
として終了します。
bashはすごく奥が深そうです...
さくらVPSでKernel再構築
最近サーバ関係の記事が多いですね。実はインフラエンジニアのバイトをはじめまして鯖触るようになって色々と勉強してます。
さて、ふと見たら昨日LinuxのKernel3.9.5(stable)がでてたのでさくらVPSにいれてみることにしました。
面倒なのでrootで作業しちゃいます(良くないですね
とりあえずソース・コードの入手。展開。
#wget https://www.kernel.org/pub/linux/kernel/v3.x/linux-3.9.5.tar.xz #tar Jxvf linux-3.9.4.tar.xz
tarで一応一覧表示してますが、べつにいいやって場合はvオプション外してもいいかもしれません。(一応出力しといたほうがなんかあったとき便利かなと思うけどこれに関しては今のところ使ったことないし...)
さて、一から設定するのも面倒なので現在のカーネルの設定を基本的に引き継いでコンパイルします。
#uname -r 2.6.32-358.6.1.el6.x86_64 #cp /boot/config-2.6.32-358.6.1.el6.x86_64 ./config #make oldconfig
これのunameでは現在のカーネルを表示しています。私の環境では2.6.32-358.6.1.el6.x86_64でした。これをコピーします。
そしてoldconfigオプションを付けてコンパイル。これで現在の設定を引き継いでコンパイルしてくれます。
色々と聞かれるので答えていきましょう。ちなみにわたしは途中でつかれてEnter押しっぱなしにしてましたw(というわけであんまりkernelをビルドする必要性がない感じ...)
READMEをよむと新しく追加された項目だけ質問してくれるsilentoldconfig、新しい項目はデフォルトのにしてあとは設定ファイルに従ってしてくれるolddefconfigなんてオプションがあるのでそっちをつかったほうが良かったのかもしれません。
あとはmakeしてインストールします。このときmake modules_installを実行する前に以前のkernelのbackupをしといたほうがいいよって書かれているので気になる人はしときましょう。
make make modules_install make install
という感じでとりあえずおわりました。
次にbootローダでデフォルトで起動するように設定します。下の方に3.9.5のkernelがあるのでそれが何番目かを数えて/boot/grub/menu.lstの中にdefault=数字って部分を変更します。この時0から数えることに注意してください。(わたしの環境では0番でした。普通にすれば一番先頭に追記される気がします)
これであとはrebootします。しばらくまってからsshでつなぎuname -rとすると3.9.5と表示され確かに更新されていることがわかります。
案外すんなりできてしまいましたね。次するときはオプションもしっかり指定できるようになりたい...
グリーン関数の導出
物理やってるとグリーン関数なるものがよく登場しますね。
ポアソン方程式
のような方程式を解くときに使うあれです。
ただ解けはするんだけどなんか気持ち悪いなーとか思っていて、パルスって説明もちょっと納得いかず色々とこねくり回してたらそれっぽい感じの説明思いついたので書いておきます。(正しいかは保証しません)
方程式
でについて解くことを考えます。ここでは微分を含むような線形作用素だとします。
行列とベクトルみたいな感じで両辺からの逆作用素をかけてあげると
となり、形式的にはが求まりました。が、逆作用素の実体が不明なのでこれを求めます。
微分の逆演算なので積分になりそうです。とりあえず以下のように仮定してみましょう。
積分になるだろうという予測、そしてたんなる積分ではなくなにか関数Gも含むだろうという予測です。
あとはGをもとめればいいだけ(存在するのかというのもホントは証明しないといけないですけど)ということですが、
積分が含まれていて余計にややこしくなったように見えます。
今Gを積分から取り出すのにデルタ関数を用います。
とおいて代入してみましょう。
めでたく積分の中からGを取り出せましたね。
あとはを両辺にかけて
という方程式をとけば良いだけです。ポアソン方程式の場合はフーリエ変換して逆変換してあげれば出ますね。
この方程式に出てきたGのことをグリーン関数と呼びます。