とても単純なWebサービスを一時間で作った

作ったもの

md.nyaocat.jp

http://md.nyaocat.jp/?url=(マークダウンファイルのURL)

これでMarkdownファイルをhtmlに変換して表示してくれる. あまりセキュリティ考えてないので悪いところがあったら教えてください.

ソースコード

Github nyaocat/md.nyaocat.jp

実質1ファイルのみで非常に単純.

工程

  1. お名前.com のレコード設定で md.nyaocat.jp を設定した
  2. Github にリポジトリを作った
  3. サーバでCloneしてコード書き始める(コミット履歴
  4. Twitter にURL載せてみる
  5. 指摘してくれたアカンところをちょいと修正

反省点

この程度のものも作ってみると1時間かかってしまうんだな,ということがわかりました.

エラーチェックやレコード設定,Github にリポジトリ作る部分が本質的な部分じゃないのに複数の サイトにアクセスして設定する必要があって面倒でした.

あと,Javascript よくわかってなくて Javascript正規表現使う方法とか調べながら書いてたのが良くありませんでした.

これの今後

  • サーバ側でなくクライアント側で変換させる
  • CSS 自分で用意する
  • 見出しをピックアップして目次メニューつけたりすると良いかも
  • 第一レベルの見出しごとにプレゼンテーションになるようにすると便利かも

(Lua)読み取り専用テーブルモジュールを本気出して作った

Lua readonly module (https://gist.github.com/nyaocat/7380582)

このモジュールを介して作成されたテーブル・ユーザーデータのフィールドは絶対に変更出来ません. (debugライブラリを除く)

他の類似モジュールとの違い

いくつか "Lua Read Only" で検索しても似たのが出てくる.

  • newproxy を使用してるので rawset でも変更できない
  • getmetatable されても変更出来ない
  • メタメソッドも全て対応
  • #演算子対応
  • pairs,ipairs,next に半分対応
  • メンバ関数経由でのみ更新可能

これらを全部満たすリードオンリーテーブルモジュールはぱっと検索した限り見当たらなかった

サンプルコード

ERROR! とコメントされた行でエラーが発生します

readonly = require "readonly"
arr = readonly.readonly {3, 9, 7, 4}
print(arr[2]) -- OK
arr[1] = 98   -- ERROR!


t1 = readonly.readonly {
  val     = 10,
  getVal  = function(self)         return self.val   end,
  setVal  = function(self, newval) self.val = newval end
}
t1:getVal()   -- OK
t1:setVal(20) -- ERROR!
t1.val = 30   -- ERROR!

t2 = readonly.readonly2 {
  val     = 10,
  getVal  = function(self)         return self.val   end,
  setVal  = function(self, newval) self.val = newval end
}
t2:setVal(20) -- OK
t2:getVal()   -- OK
t2.val = 30   -- ERROR!

for k, v in ipairs(arr) do end -- ERROR!
for k, v in pairs(t2)   do end -- ERROR!
for k, v in readonly.ipairs(arr) do end -- OK
for k, v in readonly.pairs(t2)   do end -- OK

readonly(tbl) は与えられたテーブル,ユーザデータを読み込み専用にして返します.

readonly2(tbl) はメンバ関数経由での更新のみを許可します.

readonly(), readonly2() で作成された読み込み専用テーブルは標準の next, pairs, ipairs で使用出来ません.

代わりに, require("readonly").next, require("readonly").pairs, require("readonly").ipairs を使用して下さい.

これらの関数はこのモジュールで作成された読み込み専用テーブル意外のテーブルに対しては標準の next, pairs, ipairs を使用するため, これらの関数で標準の関数を置き換えても問題ありません.

フィールドが更新出来ない以外は元のテーブルと全く同じようにアクセス出来ます. __index を用いてLuaでクラスを表現している場合でも問題ありません.

このモジュールは Lua5.1 で実行してもグローバル変数にモジュールをセットしません. これは Lua5.2 での一般的なモジュール挙動と合わせたためです. local readonly = require "readonly" として実行してください.

このモジュール自体は Lua5.1, Lua5.2 両方で動くはず(多分)です.

このファイルを単体でlua readonly.luaとして実行すると簡単なテストが実行されます. http://ideone.com/soulZG require した時にはテストは実行されません.

以下実装の解説というかなんというか読み込み専用モジュールの作り方

続きを読む

Lua で Python の if __name__ == '__main__':

Pythonなら単体テスト自動化もバッチリ

Python だと if __name__ == '__main__': でファイル単体で実行された時の動作を記述出来るらしい.いいな. モジュールのファイルを単体で実行した時に意味をもたせられるのは単純に面白い気がする.

Lua でも出来るよ!

続きを読む

Lua に C関数を公開する時

Programming in Lua 曰く,

Enum を受け取るような関数を定義する時は文字列で受け取ったほうが良い

というような事が書いてあって,実際標準Luaライブラリにも luaL_checkoption というまさにうってつけの関数が用意されてる

……んだけど,その許可するものの数が膨大だとこれでは(Programming in Lua内にあるコードでも)文字列から線形探索になるからちょっと気になるんじゃないかなーと.

続きを読む

まだまとまってないけどコルーチンが使える言語でアクション作る時に使えるかもしれないメモ

前提

簡単なアクションゲームプログラミングをしてるとして, キャラクタークラスが毎フレーム呼ばれる Update() メソッドを持っており, Updateメソッド内で座標移動とかをする.

他キャラクターとの当たり判定を IsHitOtherCharacter() で取得できる

続きを読む

C++ポケットリファレンスの執筆に参加しました。

C++ ポケットリファレンス(Amazon)

http://gihyo.jp/book/2013/978-4-7741-5715-3

本日が発売日の、C++ポケットリファレンスに共著として参加しました。 2013/05/18 12:33 現在、AmazonのC++カテゴリで1位、プログラミングカテゴリで10位になっています。

初めての執筆経験となりました。大変でしたが、色々と貴重な経験となりました。 執筆プロジェクトの体制については、同じく著者である晶さんのブログ記事が詳しいです。

本書は、日本では初のC++11対応書籍です。 中身は、逆引きリファレンスで主にライブラリの解説が中心となります。

C++11では言語仕様、標準ライブラリともに大幅に追加されました。 なるべく広く深く扱うため、528ページというボリュームになりましたが、 それほど重くなく、電車内でパラパラと読むのにも適していると思います。

あ、電子書籍版も出ています。 よろしくお願いします。