Updates from mitsuwo RSS Toggle Comment Threads | キーボードショートカット

  • mitsuwo 8:11 pm on April 19, 2010 パーマリンク | 返信  

    Slab Allocator Again 

    ここで書いた Slab Allocator を、同期処理に
    前回書いたMSynchを使うようにしてリリースしました。

    一応、WIN32 と POSIX で動くようにしたのですが、
    gcc でのコンパイルに手間取り、segmentation fault と格闘、
    やっとリリースにこぎつけました。

    MSlab

    名前も nslab から mslab にバージョンアップ。
    まともに使えそうな同期処理が手に入ったので、
    今までやりたかったことがどんどん進みそうな予感。

     
  • mitsuwo 1:17 pm on April 7, 2010 パーマリンク | 返信  

    RWロックを書いてみた 

    以前に書いた Slab Allocation もそうなんですが、
    いろんなライブラリを書いてると、スレッドセーフにしたくなります。

    critical section とか mutex とか
    最近のOSは便利な制御を提供してくれてるのですが、
    ロックの時間をなるべく減らそうと思うと
    やはりReaders-Writersロックがほしくなります。

    ここ最近 boost::shared_mutex に目を付けて使ってたのですが、
    テストしてみるとなんかうまく動かない時があるので悩んでました。

    で、色々探してたらこんな本に出会いました。
    "The Little Book of Semaphores Second Edition"

    本といっても、ネット上にPDFで置いてあるものなので無料です。
    最初は例題の名前が「散髪屋問題」とか「寿司バー問題」で面白そうだったので
    興味本位で読み始めたのですが、読んでみると今まで悩んでいたことが
    次々に解決していきました。僕にとってはもうバイブル級です。
    これまでに読んだプログラミング関係の本のなかでも
    5本の指に入るといっても過言ではない。

    本の著者 Allen B. Downey氏に感謝しつつ、Readers-Writersロックを含む、
    同期プログラミング・ライブラリを作ってみました。

    MSynch

    下記を再利用可能なライブラリとして提供してます。

    ・ポータブルなセマフォ・クラス(win32/pthread)
    ・2フェーズバリア
    ・生産者-消費者モデル
    ・有限バッファ版 生産者-消費者モデル
    ・Reader優先版 Readers-Writersモデル
    ・Writer優先版 Readers-Writersモデル
    ・飢餓状態(stavation)回避版 Readers-Writersモデル

    今後、Slab Allocation もこのライブラリを使って
    同期制御するように書き換えてリリースする予定。

    ちなみに、あとでわかったのですが、boost::shared_mutex には
    127個以上のスレッドが排他ロックを待つ状態になると異常な状態になり
    例外も投げないというバグがあるそうです。
    https://svn.boost.org/trac/boost/ticket/2293

    127個のスレッドというのは実環境ではあまり考えなくてよい
    ような制約かも知れないのですが、使う方は気をつけてたほうがいいですよ。

     
  • mitsuwo 8:54 pm on February 15, 2010 パーマリンク | 返信  

    Win32 で簡易暗号化 

    今流行りの twitter のクライアントが作りたい。

    ユーザーのIDとパスワードをどこに置くか?
    OAuthていうのを使うといいらしいけど、なんかややこしそうだし
    セキュリティホールがあるってのも気になります。

    やっぱレジストリに置こうかな。
    ってことで、とりあえず可逆暗号書いてみました。

    いろいろ調べたけど、結構簡単に使えそうなAPIがあったので
    助かりました。

    Windowsが関数の中で LocalAlloc する変数があるので忘れずに
    LocalFree。恐ろしや。

    #pragma comment(lib, "crypt32.lib")

    #include <cstddef>
    #include <string>
    #include <windows.h>
    #include <Wincrypt.h>

    bool encrypt(const std::string& key, const std::string& plain, void* crypt, size_t* crypt_len )
    {
        DATA_BLOB key_bolb;
        key_bolb.pbData = (BYTE*)key.c_str();
        key_bolb.cbData = key.length()+1;

        DATA_BLOB plain_bolb;
        plain_bolb.pbData = (BYTE*)plain.c_str();
        plain_bolb.cbData = plain.length()+1;

        DATA_BLOB crypt_bolb; // must LocalFree

        BOOL result
         = CryptProtectData(
            &plain_bolb,
            L"",
            &key_bolb,
            NULL,
            NULL,
            0,
            &crypt_bolb);

        if(result)
        {
            *crypt_len = (size_t)crypt_bolb.cbData;
            if(crypt != NULL )
                ::memcpy(crypt, crypt_bolb.pbData, *crypt_len);
        }
        LocalFree( crypt_bolb.pbData );

        if(result)
            return true;
        else
            return false;
    }

    bool decrypt(const std::string& key, const void* crypt, const size_t crypt_len, std::string& plain )
    {
        DATA_BLOB key_bolb;
        key_bolb.pbData = (BYTE*)key.c_str();
        key_bolb.cbData = key.length()+1;

        DATA_BLOB crypt_bolb;
        crypt_bolb.pbData = reinterpret_cast<BYTE*>(const_cast<void*>(crypt));
        crypt_bolb.cbData = crypt_len;

        DATA_BLOB plain_bolb; // must LocalFree
        LPWSTR* desc = NULL;  // must LocalFree

        BOOL result
        = CryptUnprotectData(
            &crypt_bolb,
            desc,
            &key_bolb,
            NULL,
            NULL,
            0,
            &plain_bolb);

        if(result)
        {
            plain = (char*)plain_bolb.pbData;
        }
        LocalFree( plain_bolb.pbData );
        LocalFree( desc );

        if(result)
            return true;
        else
            return false;
    }

    使い方。

    void main()
    {
        std::string plain = "あいうえおかきくけこさしすせそ";
        std::string key   = "1234"; //鍵。暗号化と復号で同じものを使う

        size_t out_len; //まずは暗号化後の長さを得る
        if(::encrypt(key, plain, NULL, &out_len))
            std::cout << "encrypt len ok" << std::endl;
        else
            std::cout << "encrypt len ng" << std::endl;

        char* out = new char[out_len]; //暗号化
        if(::encrypt(key, plain, out, &out_len))
            std::cout << "encrypt ok" << std::endl;
        else
            std::cout << "encrypt ng" << std::endl;

        //outに暗号化後のデータが入ってるので、どっかに保存したりする
        memdumpc(out, out_len);

        std::string check; //復号
        if(::decrypt(key, out, out_len, check))
            std::cout << "decrypt ok" << std::endl;
        else
            std::cout << "decrypt ng" << std::endl;

        delete [] out;

        std::cout << check << std::endl;

        return;

    }

     
  • mitsuwo 3:59 pm on February 13, 2010 パーマリンク | 返信  

    C++ で Slab Allocation 

    C++でメモリダンプでやりたいといってた slab allocation。

    書いたどー。
    http://na-s.jp/download.ashx?dl=/nslab_pp/nslab_pp_016.zip

    一般に、malloc や free を繰り返していると、ヒープで管理される
    メモリブロックの単位が次第に小さくなっていき、断片化してきます。
    とくに、確保される領域の大きさがバラバラだったり、
    確保から解放までの時間がバラバラだったりすると、
    断片化が顕著になるといわれています。

    ある程度断片化したヒープからは、空き領域があっても
    まとまった領域を確保することができなくなってしまうので、
    プロセスの再起動が必要になってしまいます。

    slab allocation は上記のような問題に対する解決策です。

    プロセス起動時にまとめて malloc した巨大な領域(slab)を、
    あらかじめ決めておいた単位に分けて貸し出し、返却された
    領域を再利用していくというもの。

    ここに詳しい説明があります。
    http://gihyo.jp/dev/feature/01/memcached/0002

    【使い方】

    malloc と free を置き換える場合。

    #include <iostream>
    #include "nslab_pp/slab_manager.hpp"

    using namespace nslab_pp;

    size_t SLAB_UNITS[] = {4, 8, 100, 200 }; //貸し出し単位
    const size_t SLAB_SIZE = 100 * 1024 * 1024; //mallocサイズ

    int main()
    {
        ::sconf(
          SLAB_SIZE, SLAB_UNITS, sizeof(SLAB_UNITS)/sizeof(size_t) );

        char* cptr = (char*)::salloc(100); //動的メモリ確保

        // 何かする。

        ::sfree(cptr)

        return 0;
    }

    オブジェクトとして使いたい場合。

    #include <iostream>
    #include "nslab_pp/slab_manager.hpp"

    using namespace nslab_pp;

    size_t SLAB_UNITS[] = {4, 8, 100, 200 }; //貸し出し単位
    const size_t SLAB_SIZE = 100 * 1024 * 1024; //mallocサイズ

    slab_manager g_slab_man(
      SLAB_SIZE, SLAB_UNITS, sizeof(SLAB_UNITS)/sizeof(size_t) );

    int main()
    {
        char* cptr = (char*)g_slab_man.allocate(100); //動的メモリ確保

        // 何かする。

        g_slab_man.release(cptr)

        return 0;
    }

    【コンパイル方法】

    ■A. Windowsの場合

    0. Windows SDK と boost(thread関係) をインストール・構築しておく

    1. src\Makefile.win の先頭2行を自分の環境に合わせる

    2. Visual Studio Command Prompt を起動

    3. src に cd

    4. 自分の環境に適したコマンドを発行

    >nmake -f Makefile.win BUILD=release ARCH=x86
    >nmake -f Makefile.win BUILD=release ARCH=x64

    dist に .lib ファイルなどが生成されます。

    ■B. Linuxの場合

    0. g++ と boost(thread関係) をインストール・構築しておく

    >sudo yum install gcc-c++
    >sudo apt-get install g++

    1. src に cd

    2. make コマンドを発行

    >make BUILD=release

    dist に .a ファイルなどが生成されます。

     
  • mitsuwo 2:03 pm on January 20, 2010 パーマリンク | 返信  

    C++でメモリダンプ 

    memcached の slab allocation みたいなことがやりたいです。
    で、new とか malloc をいじってたら、
    いい感じのダンプ関数が出来たので公開。

    ふつうは、C/C++初心者のとき先輩に作らされたりするみたい
    だけど、実際にやってみると結構むずかしいもんですね。

    Cのprintfとか使わずにC++の標準関数だけで攻めてるとこが拘り。

    #include <iostream>
    #include <iomanip>

    // int version
    void memdumpi(void* vptr, size_t len)
    {
        std::cout << ">>>> memdump(int) ---------------------------" << std::endl;

        unsigned int* cptr = reinterpret_cast<unsigned int*>( vptr );
        for (size_t i=0; i<(len/sizeof(int)); ++i )
        {
            if ( i%4 == 0 )
            {
                if ( i != 0 ) std::cout << std::endl;
                std::cout << std::hex << std::setw(8) << std::setfill('0');
                std::cout << reinterpret_cast<int>(&cptr[i]) << ": ";
            }
            std::cout << std::hex << std::setw(8) << std::setfill('0');
            std::cout << static_cast<int>(cptr[i]) << " " ;

        }
        std::cout << std::endl;

        std::cout << "--------------------------- memdump(int) <<<<" << std::endl;
    }

    // char version
    void memdumpc(void* vptr, size_t len)
    {
        std::cout << ">>>> memdump(char) --------------" << std::endl;

        unsigned char* cptr = reinterpret_cast<unsigned char*>( vptr );
        for (size_t i=0; i<len; ++i )
        {
            if ( i%8 == 0 )
            {
                if ( i != 0 ) std::cout << std::endl;
                std::cout << std::hex << std::setw(8) << std::setfill('0');
                std::cout << reinterpret_cast<int>(&cptr[i]) << ": ";
            }
            std::cout << std::hex << std::setw(2) << std::setfill('0');
            std::cout << static_cast<int>(cptr[i]) << " " ;

        }
        std::cout << std::endl;

        std::cout << "-------------- memdump(char) <<<<" << std::endl;
    }

    こんな風に使う。

    struct struct1
    {
        std::string name;
        int id;
    };

    int main()
    {

        int* ptr1 = reinterpret_cast<int*>( malloc( sizeof(int)*10 ) );
        memdumpc( ptr1, sizeof(int)*10 );

        memset( ptr1, 0, sizeof(int)*10 );
        memdumpc( ptr1, sizeof(int)*10 );

        for( size_t i=0; i<10; ++i )
        {
            if( i < 5 )
                ptr1[i] = 1010101;
            else
                ptr1[i] = 2020202;
        }
        memdumpc( ptr1, sizeof(int)*10 );

        free(ptr1);

        char* ptr2 = reinterpret_cast<char*>( malloc( sizeof(char)*10 ) );
        memdumpc( ptr2, sizeof(char)*10 );

        memset( ptr2, 0, sizeof(char)*10 );
        memdumpc( ptr2, sizeof(char)*10 );

        for( size_t i=0; i<10; ++i )
        {
            if ( i < 5 )
                ptr2[i] = 'Y';
            else
                ptr2[i] = 'X';
        }
        memdumpc( ptr2, sizeof(char)*10 );

        free(ptr2);

        struct1* ptr3 = reinterpret_cast<struct1*>( malloc( sizeof(struct1)*3 ) );
        memdumpi( ptr3, sizeof(struct1)*3 );

        memset( ptr3, 0, sizeof(struct1)*3 );
        memdumpi( ptr3, sizeof(struct1)*3 );

        struct1* ptr3_1 = new(&ptr3[0]) struct1;
        struct1* ptr3_2 = new(&ptr3[1]) struct1;
        struct1* ptr3_3 = new(&ptr3[2]) struct1;
        memdumpi( ptr3, sizeof(struct1)*3 );

        ptr3_1->id = 10;
        ptr3_1->name = "あいうえお";
        ptr3_2->id = 200;
        ptr3_2->name = "かきくけこ";
        ptr3_3->id = 3000;
        ptr3_3->name = "さしすせそ";
        memdumpi( ptr3, sizeof(struct1)*3 );

        ptr3_1->~struct1();
        ptr3_2->~struct1();
        ptr3_3->~struct1();
        free(ptr3);

        return 0;
    }

    こんな風に表示される。

    >>>> memdump(char) --------------
    003849c8: cd cd cd cd cd cd cd cd
    003849d0: cd cd cd cd cd cd cd cd
    003849d8: cd cd cd cd cd cd cd cd
    003849e0: cd cd cd cd cd cd cd cd
    003849e8: cd cd cd cd cd cd cd cd
    -------------- memdump(char) <<<<
    >>>> memdump(char) --------------
    003849c8: 00 00 00 00 00 00 00 00
    003849d0: 00 00 00 00 00 00 00 00
    003849d8: 00 00 00 00 00 00 00 00
    003849e0: 00 00 00 00 00 00 00 00
    003849e8: 00 00 00 00 00 00 00 00
    -------------- memdump(char) <<<<
    >>>> memdump(char) --------------
    003849c8: b5 69 0f 00 b5 69 0f 00
    003849d0: b5 69 0f 00 b5 69 0f 00
    003849d8: b5 69 0f 00 6a d3 1e 00
    003849e0: 6a d3 1e 00 6a d3 1e 00
    003849e8: 6a d3 1e 00 6a d3 1e 00
    -------------- memdump(char) <<<<
    >>>> memdump(char) --------------
    003849c8: cd cd cd cd cd cd cd cd
    003849d0: cd cd
    -------------- memdump(char) <<<<
    >>>> memdump(char) --------------
    003849c8: 00 00 00 00 00 00 00 00
    003849d0: 00 00
    -------------- memdump(char) <<<<
    >>>> memdump(char) --------------
    003849c8: 59 59 59 59 59 58 58 58
    003849d0: 58 58
    -------------- memdump(char) <<<<
    >>>> memdump(int) ---------------------------
    00384d38: cdcdcdcd cdcdcdcd cdcdcdcd cdcdcdcd
    00384d48: cdcdcdcd cdcdcdcd cdcdcdcd cdcdcdcd
    00384d58: cdcdcdcd cdcdcdcd cdcdcdcd cdcdcdcd
    00384d68: cdcdcdcd cdcdcdcd cdcdcdcd cdcdcdcd
    00384d78: cdcdcdcd cdcdcdcd cdcdcdcd cdcdcdcd
    00384d88: cdcdcdcd cdcdcdcd cdcdcdcd cdcdcdcd
    00384d98: cdcdcdcd cdcdcdcd cdcdcdcd
    --------------------------- memdump(int) <<<<
    >>>> memdump(int) ---------------------------
    00384d38: 00000000 00000000 00000000 00000000
    00384d48: 00000000 00000000 00000000 00000000
    00384d58: 00000000 00000000 00000000 00000000
    00384d68: 00000000 00000000 00000000 00000000
    00384d78: 00000000 00000000 00000000 00000000
    00384d88: 00000000 00000000 00000000 00000000
    00384d98: 00000000 00000000 00000000
    --------------------------- memdump(int) <<<<
    >>>> memdump(int) ---------------------------
    00384d38: 00000000 00000000 00000000 00000000
    00384d48: 00000000 00000000 00000000 0000000f
    00384d58: 00000000 00000000 00000000 00000000
    00384d68: 00000000 00000000 00000000 00000000
    00384d78: 0000000f 00000000 00000000 00000000
    00384d88: 00000000 00000000 00000000 00000000
    00384d98: 00000000 0000000f 00000000
    --------------------------- memdump(int) <<<<
    >>>> memdump(int) ---------------------------
    00384d38: 00000000 00000000 a282a082 a682a482
    00384d48: 0000a882 00000000 0000000a 0000000f
    00384d58: 0000000a 00000000 00000000 ab82a982
    00384d68: af82ad82 0000b182 00000000 0000000a
    00384d78: 0000000f 000000c8 00000000 00000000
    00384d88: b582b382 b982b782 0000bb82 00000000
    00384d98: 0000000a 0000000f 00000bb8
    --------------------------- memdump(int) <<<<

     
  • mitsuwo 9:35 pm on September 21, 2009 パーマリンク | 返信  

    FreeBSDのパッケージ管理には pkg_add より ports が吉? 

    NSでは YRM による NmagemanA の正式リリース準備が進んでいるようです。
    http://na-s.jp/NmagemanA/

    NmagemanA は これまでIISでのみ利用可能だった 画像自動変換モジュール
    Nmageman の Apache版 であり、対応環境が一気に拡大する画期的な製品。

    社内では、VirtualBox や Parallels に Linux や BSD をインストールし、
    Apacheの環境を構築して NmagemanA をテストする作業が行われてるみたいです。

    直接の担当ではないものの、Windowsラブ かつ Linuxもラブ な僕としては
    いろいろ気になるところ。特にあまり使ったことがない FreeBSD は気になるなー。

    Linuxのラブなところは、洗練されたパッケージ管理システムです。
    yum や apt-get を使うと必要なときに必要なパッケージ(ソフト)を
    コマンド一発でインストールしてくれる。パッケージはネットワーク経由で
    自動的にダウンロードされるので、インストールCD(DVD)に戻る必要もない。

    昔はいちいち CDをマウントして .rpm や .deb を手作業でインストールしてた。
    依存するパッケージが多いパッケージなんか入れるときはうんざりしたけど、
    今は依存パッケージも勝手にダウンロードしてくれる。超便利。

    で、FreeBSDはどうなのかというと、大きく2通りのやり方があるみたい。

    1つめは pkg_add を使う方法。これは Linux における yum や apt-get
    と同じようなもので、

    pkg_add -r [パッケージ名]

    のようなコマンドを発行すると、コンパイル済のバイナリをネットワーク経由で
    ダウンロードしてきてインストールしてくれる。
    もちろん依存関係も解決してくれる。

    2つめが FreeBSDの独特な方法で、ports という仕組み。CDからのインストール時に
    /usr/ports に全パッケージの Makefile がコピーされる。必要なときに
    このMakefileを使って make を実行すると、パッケージのソースのダウンロード、
    設定(configure)、コンパイル、インストールが自動的に行われる。
    依存パッケージもコンパイル等、同様に処理してくれる。

    依存パッケージも含めると、パッケージによってはコンパイルにとても時間が
    かかるので、当然 ports よりも pkg_add がよいと思って使ってた。

    ところが、pkg_add を使って入れた apache のパッケージに不具合があり、
    インストールに成功して、デーモンは起動して、tcp接続のacceptまではいくのに、
    ブラウザにまったくレスポンスが返ってこない現象が発生した。

    ports を使ってインストールしたらこの問題は発生しなかった。

    いろんなサイトで FreeBSD の環境構築について調べてみると pkg_add より
    ports のほうが圧倒的に使われているようである。
    やはりFreeBSDでは ports を使うのが一般的ということなのだろうか。

    で、下記のような事情があるのではないかと考えてみた。

    Linux の場合は、OSのコアなモジュールである kernel を開発しているところと、
    実際にインストールして使える形(ディストリ)にして提供しているところが
    組織として独立している。しかも各ディストリが互いに競争してより使いやすい
    ものを目指して開発しているため、バイナリパッケージの品質が比較的高い。

    一方で、FreeBSDの場合は、kernelの開発もパッケージの管理も同じ団体が
    行っている。Linux的にいうとFreeBSDの唯一のディストリはFreeBSDだけである。
    その結果、コンパイル済のバイナリの品質管理などはどうしても後回しに
    なってしまうこと、またユーザー側もportsでの管理に満足しているため
    そちらに開発資源が割かれない。ということがあるのではないか。

    このように考えて、納得した次第です。これからは ports を使います!

    Windows & Linux ラブな僕ですが、FreeBSD も ハッカー的な
    においがぷんぷんして とても かっこいいと思います。

     
  • mitsuwo 10:32 am on September 9, 2008 パーマリンク | 返信  

    Google Chrome で Jumpman を使うには 

    こんにちは、mitsuwo です。

    先日ついに Google が Webブラウザ を公開しましたね。
    Google Chromeけっこう軽快に動作するので気に入ってます。

    さて、今日はこのGoogle Chromeでデフォルトの検索エンジンを
    JumpmanにするTips を紹介します。

    • Google Chrome を起動して、ウインドウ右上のスパナのアイコンをクリック
    • 「オプション」を選択すると「Google Chrome オプション」が開きます。
    • 三段目の「既定の検索エンジン:」の「管理」ボタンをクリック、「検索エンジン」が開きます。
    • 右上の「追加」ボタンをクリック。「検索エンジンの追加」が開きます。
    • 名前
      Jumpman
      キーワード
      shizentai.jp
      URL

      http://shizentai.jp/Jumpman/Jumpman.aspx?Word=%s

      のように入力して、「OK」ボタンをクリック

    • あとは、既定の検索エンジンで「Jumpman」を選択しておくだけです。

    以上で Google Chrome の Jumpman化 完了です。
    以後、アドレスバーにURL以外を入れるとJumpman を経由して検索されるようになります。

     
  • mitsuwo 4:31 pm on September 5, 2008 パーマリンク | 返信  

    Framebox 1.0.0.0 リリース!!! 

    Framebox という Javascript をリリースしました。
    http://na-s.jp/Framebox/

    画像の表示に広く使われている Lightbox のiframe版のようなものです。
    Lightbox ではリンク先の画像がダイアログ表示されますが、Framebox はリンク先のページを表示します。

    Lightboxを使ってみて、ページが表示できると面白いのではないかと考え、
    既存のものを探したのですが、有料のものしか見つからなかったので作ってみました。

    Lightbox2のソースを元に作成したので、使い方やインターフェースもほぼ同じです。

    この場を借りて、Lightbox 作者の Lokesh Dhakar 氏にお礼申し上げます。
    Thank you Mr.Lokesh Dhakar for your underlying works.

     
  • mitsuwo 12:08 pm on September 2, 2008 パーマリンク | 返信  

    Nasp Idioms 開発記 (02) 

    皆さん こんにちは。Mitsuwo です。

    約半年ぶりとなってしまいましたが、
    Naspのサンプル・アプリケーション “Nasp Idioms” を更新しました。
    http://na-s.jp/nasp/



    このサンプルは、Naspが対応している各種開発言語を用い、
    Webアプリケーションを開発する際に必ず登場するコーディング
    パターンを網羅的に実装していこうというものです。

    当初は、言語とパターンの掛け算でどんどんリリースしていく予定
    だったのですが、今回は新機能の追加はありません。



    新機能の代わりに、下記を行いました。

    ・Guideman http://na-s.jp/guideman/ の導入
    ・プログラムの設計をよりNasp的な、ライトウエイトなものに軌道修正

    また、前回は各開発言語一括でのダウンロードになっていましたが、
    今回から開発言語ごとにダウンロードファイルを分けました。
    現状、VBScript(ASP) と JScript(ASP) が利用できます。



    Guideman は Apacheの世界での mod_rewrite と同等の働きを IISの世界で
    実現する ISAPIフィルタツールです。

    Naspで開発する際は導入必須と言ってよいものなのですが、これまで
    具体的なサンプルを提供できていなかったため、
    この機会に提供することにしました。

    Guideman を導入することで、Nasp による Front Controller型実装を
    行いつつ、ユーザーには自然なURLを見せることが可能になります。



    プログラムの設計に関しては、今まで公開されていたサンプルを
    見ていただいていた方には、「ごめんなさい」と言いたいと思います。

    前回のサンプル作成は入社直後に行ったため、私自身Nasp以前のスタイル
    の影響がかなり残っており、自分でも気づかないうちに、Nasp的でない
    コードを書いてしまっていました。

    この半年間、いくつかのNaspプロジェクトに参加して経験を積むことで、
    Nasp的に「いけてる」コードがかなり書けるようになりました。

    新しいサンプルでは、Naspプロジェクトでは不要な中間ロジックの
    分離を行っていないため、コード量が半減しており、サンプルとしても
    より見やすくなっていると思います。



    次はいつになるか分かりませんが、開発言語・コーディングパターン
    ともに増やしていく予定なので、気長に待っていて下さい!

     
  • mitsuwo 3:47 pm on July 7, 2008 パーマリンク | 返信  

    Jumpman リニューアル! (AJAXなど) 

    お待たせしました。 Jumpman リニューアルです。
    http://shizentai.jp/Jumpman/

    下記の変更を行いました。
    ・ユーザーインターフェースのAJAX化
    ・検索エンジンが選択可能に
    (Google, Yahoo, MSN, Wikipedia, goo, Excite, 百度)
    ・お友達(キーワードシェア)機能

    AJAX的な動作確認ずみブラウザは以下です。
    Vistaとか、IE7とかあまり見てないので、不具合があれば
    情報お待ちしています。

    【Windows XP SP2】
    ・IE 6.0.2900
    ・Firefox 3.0
    ・Opera 9.26
    ・Safari 3.1.1

    【Mac OS X 10.5.3】
    ・Firefox 2.0.0.12
    ・Safari 3.1.1
    ・Opera 9.73

    【CentOS 5】
    ・Firefox 1.5.0.12
    ・Opera 9.27

     
    • yrm 11:10 am on 7月 8, 2008 パーマリンク

      お!
      リリースされてるね。

      自分のワードリスト画面からクリックでURLへジャンプすることがあったので、
      その機能がまたほしいな~。

      あとは今後の発展に大期待です。
      まずはよくジャンプするワードがトップ画面にリスト表示されるといいな~。

    • mitsuwo 4:06 pm on 7月 8, 2008 パーマリンク

      とりあえず、ワードリスト画面内のジャンプリンクは対応しました。

      あと、特にIE6で入力ダイアログ用のAJAXテンプレートが
      一瞬表示されてしまう問題があったので対応しました。

    • mitsuwo 9:25 am on 7月 11, 2008 パーマリンク

      ログインの有効期限が1日になっていたので90日に延長しました

c
新規投稿作成
j
次の投稿 / 次のコメント
k
前の投稿 / 前のコメント
r
返信
e
編集
o
コメントを表示する / 隠す
t
トップへ移動
l
go to login
h
show/hide help
esc
キャンセル