Java演習用のテキスト画面シミュレータ

子供にJavaを教える必要が出てきたのですが、課題の作り方が難しいです。

標準入出力を使って数学の問題を解くような課題は、ロジックを組み立てる訓練になりません。
一方で、ウインドウプログラミングやWebプログラミングは、理解すべき事が多すぎて手始めには向きません。
理想としては、8bit時代のパソコンのBASICのような、テキスト画面を使ったインタラクティブなプログラミングだと考えています。

Javaはターミナルの制御が貧弱なので、カーソルの位置を設定したり、ノンブロッキングでキーボードの入力を拾うような事ができません。
Jansiのようなライブラリもあるのですが、実行時にネイティブライブラリが必要な上、eclipseのコンソール出力では動作を確認できないので、初心者に厳しいです。
そこで、swingを使ってテキスト画面のシミュレータを実装してみました。

JavaConsoleSimulator

80文字×25行のテキスト画面に対して、

  • 文字の表示
  • カーソル位置の変更
  • 画面の消去
  • 指定したキーの押下状態の取得

が可能です。

最初は45度にしかボールが飛ばないブロック崩しあたりから始めて、最終的にはテトリス辺りを実装できるように教えたいと思います。

カテゴリー:開発 タグ:

CocoaSQLMapperについて発表してきました

2013年1月26日 1件のコメント

Cocoa勉強会で、CocoaSQLMapperについて発表してきました。

「NSDecimalNumberをサポートしないの?」という話と、「外部結合でツリー状の親子オブジェクトを取得したいよね」という突っ込みがありまして、とりあえず前者はなんとかしようと思います。
後者は、上手いインターフェースを思いつかないです。

カテゴリー:開発 タグ: , ,

Time Machine用にProLiant MicroServerを導入

家族で共用のTime Machineを使ったバックアップ先に、QNAPのTurboNAS 410というNASを使っています。
これは非常に使い勝手の良い製品なのですが、ARMをCPUに使ったソフトウェアRAIDなので、I/O性能があまり高くありません。
Time Machineで使用する場合バックアップ時は問題ありませんが、過去のファイルをブラウズする操作が実用にならない程遅いです。
RAID5でなければ実用的な性能が出るのかもしれませんが、目的に沿わないので試していません。

そこでx86を使った高速な製品を物色していて、ReadyNAS Ultra4TurboNAS 469Lあたりを考えていたのですが、良いお値段なのでなかなか踏ん切りがつきませんでした。
そんな折に、HPのProLiant MicroServerが2万円以下という事を知り、FreeNASあたりを使えば手間も商用のNASと大差無いと判断して導入してみました。

性能は十分です

期待通りの性能が出ました。
Time Machineでの過去のファイルのブラウズも軽快で、十分必要なファイルを探しまわれます。

大変五月蝿いです

静音サーバという事になっていますが、NASとは比較になりません。
電源FANとケースFANが分離しており、双方ともに音量があります。
低負荷時にCPUのクロックを下げたり、HDDをスピンダウンしたりさせてみましたがも焼け石に水です。
静粛を求めるのであれば、大人しくNASを買うべきです。

楽ではありません

FreeNASはNASと言うよりも、商用LinuxディストリビューションのGUI設定ツールのような物です。
UNIXのユーザ管理や、Samba、Netatlkの知識が必要です。

僕はNASのユーザ管理やファイル共有設定には、次のような物が求められると考えています。

  • 複数のユーザを作成して共有領域を読み書きした時に、パーミッションに起因する問題が起きない
  • WindowsとMacのクライアントが混在する時に、文字化けが起きたり管理ファイルが見えたりしない

QNAPなどは上記を実現する為に、UNIXやSambaやNetatalkを上手に隠蔽して独自の設定をユーザに見せています。
結局、Linuxで自宅サーバを構築していた頃と大差無い手間が必要でした。

細かい話をすると、WebDAVのサポートが無いのでiOSなどからのアクセスが辛いです。

ファイル共有でユーザが相互に読み書きするコツ

複数ユーザで共有領域を利用する場合、ユーザ作成時にプライマリグループを「staff」あたりにしておくと楽です。
新規ファイルにグループ書き込みパーミッションさえ付けば、ユーザ間の読み書きが問題になる事が無いので。

CIFSの共有に設定については、「高度な設定」の「補助パラメータ」にアクセスを許すユーザを列記する必要があります。

valid users = "ユーザ1,ユーザ2"
write list = "ユーザ1,ユーザ2"

特にパーミッションは心配無いです。

AFPの共有設定については、「許可リスト」と「読み込み/書き込み可能アクセス」にアクセスを許すユーザを列記する必要があります。
またパーミッションは、「Default file permission」と「Default directory permission」のGropのWriteにチェックを入れる必要があります。

Macから接続する時にCIFSを使うとロクでも無いパーミッションが設定されるので、避ける事をお勧めします。

カテゴリー:サーバ, ハードウェア

Objective-C++で型推論が使える件について

Xcode 4.3のclang 3.1で、下記のコードがコンパイルできて正常に動作する事を確認しました。
Objective-C++なので、ファイル名はmain.mmです。

#import <Foundation/Foundation.h>

@interface Foo : NSObject

@end

@implementation Foo

- (void)dealloc
{
    NSLog(@"dealloc");
}

@end

int main(int argc, const char * argv[])
{
    @autoreleasepool {
        auto foo = [[Foo alloc] init];
        NSLog([foo className]);
    }
    return 0;
}

標準出力を見る限り、ARCもきっちり動いているご様子です。

2012-03-03 02:16:12.972 Test2[28693:403] Foo
2012-03-03 02:16:12.974 Test2[28693:403] dealloc

C++11の新機能を精査すれば、Objective-Cに美味しい機能がまだあるかもしれません。

カテゴリー:開発 タグ:

CocoaSQLMapperでレコードの数を数える

英語圏のエンジニアからメールで、「CocoaSQLMapperを使って”select count(*) from foo”はどーするんだよ?」と質問があり、サンプルを更新した後にその三倍の時間を使って英文の返事を書きました_| ̄|○

さてSQLの集約関数ですが、下記のようなコードを書きます。

@interface Count : NSObject
@property (nonatomic) int value;
@end

NSError *error = nil;
Count *count = [database selectObjectBySQL:@"SELECT COUNT(*) AS value FROM Person" parameter:parameter resultClass:[Count class] error:&error];
if (count) {
    NSLog(@"%i", count.value);
}

ポイントはSQLの「AS句」ですが、それ以前に整数型の値を一個受け取る為に新しいクラス定義を行っているあたりが、大変残念な気持ちを誘っています。
CocoaSQLMapperは本業でも用いていて、この残念感には以前から気がついていたのですが、忙しくて放置プレイになっていました。

今の所、二つのプランがあります。

  • 整数、文字列、日付を一つ受け取る為のクラスを、予めライブラリに含める。
  • 結果セットの列が一つの場合に、resultClassにNSNumberなどの指定を許す。

どうした物でしょうね。
http://github.com/marvelph/CocoaSQLMapper

カテゴリー:開発 タグ: , ,

C言語のswitch文でcaseラベル単位にブロックを導入する時の奇麗なインデント

現代的なC言語のスタイルでは、変数のスコープは最小化するべきだと考えています。
所がこの方針でコーディングを行うと、switch文のインデントが残念な見栄えになる事が多いのではないかと思います。

長い間下記の様に書いていましたが、インデントが深過ぎると感じていました。しかも、自動インデントで奇麗に整形できないようです(少なくてもXcode4では)。

switch (i) {
    case 0:
        {
            ~
        }
        break;
    case 1:
        {
            ~
        }
        break;
}

最近、次のような書き方を思いつきました。これはインデントも浅く、自動インデントも問題ありません。

switch (i) {
    case 0: {
        ~
        break;
    }
    case 1: {
        ~
        break;
    }
}

break文をブロックの中に入れる所がポイントです。

カテゴリー:開発 タグ:

「CocoaSQLMapper」でNSNumberをサポートしました

パラメータ及びリザルトにおいて、整数・浮動小数・論理値のNULLを表現したい場合に、NSNumberを使う事ができるようになりました。
http://github.com/marvelph/CocoaSQLMapper

リザルトにおいてビット幅を仮定する事はできないので、NSNumberの内部表現はBOOLとintはlong long intになり、floatはdoubleになります。
しかし使用時には、boolValueやintValue、あるいはfloatValueを呼び出した時点で適切に変換されます。

カテゴリー:開発 タグ: , ,