ラベル CodeSnippets の投稿を表示しています。 すべての投稿を表示
ラベル CodeSnippets の投稿を表示しています。 すべての投稿を表示

2011/04/17

JavaScript の Private メンバ

■問題
JavaScriptの文法上、直接オブジェクトのprivateメンバを指定することはできません。とはいえ、Douglas Crockford氏が「Private Members in JavaScript」で書かれている通り、JavaScriptで privateメンバが実現できないわけではありません。明示的に書けるようにされた方もいます。
しかし上記の方法ではオブジェクトの生成に「new」を使用しています。JavaScriptの「new」はちょっと厄介な仕組みになっていますので、出来れば使いたくありません。

■解案
同じく Douglas Crockford氏の著書「JavaScript: The Good Parts ―「良いパーツ」によるベストプラクティス」では、「new」を使用しない仕組みも紹介されています。個人的にちょっと理解し難かったので、その方法を纏めてみました。

    var function createMyObject(inInitArg){
        // 1. Create private members
        var privateVariable = inInitArg;
        var privateFunction = function(){
                    :
                    :
        };

        // 2. Create a new empty object.
        var that = {};  

        // 3. Add propery to the new objet as its public members.
        that.publicVariable = 0;
        that.publicFunction = function(inFuncArg){
                    :
                    :
            // Use Private Members
            privateVariable = inFuncArg * 2;
            var ret = privateFunction();
                    :
                    :
        };
    
        // 4. Return the obuject as MyObject
        return that;
    };

■若干の解説
createMyObject()内の処理は以下の通り。
  1. privateメンバとなる変数/関数を定義する
  2. まっさらのオブジェクト「that」を作成する
  3. 「that」にプロパティを追加してMyObjectのインスタンスにする
  4. 完成した「that」 を返却する
クロージャを利用して、createMyObject()関数内のコードからは、private メンバにアクセスできるようになっています。privateメンバの呼び出し時に、「this.」がないのがポイントです。
これで、「new」を排除することができました。(^o^)

■継承
別のオブジェクト(クラスではない!)を継承したいときは、「var that = {};」 の部分を
var that = createMyParentObject();
としてあげれば良いです。

■欠点
JavaScriptの「prototype」機能を活用出来ていません。
複数のMyObjetインスタンスを作成した場合、共通で使えるはずのpublicFunction()関数オブジェクトのインスタンスもその数分、作成されてしまいます。大量にオブジェクトを生成する場合は注意が必要です。

2011/03/05

Link-style HTML button

CSSでボタンをリンク風に見せるコードスニペット。

  button.linkstyle{
    text-decoration: underline;
    border: none;
    color: blue;
    background-color: transparent;
  }
  button.linkstyle:hover{
    cursor: pointer;
    color : red;
  }
  <button class="linkstyle">リンクスタイルのボタン</button>

マウスポインタをのせたときは、判りやすくポインタの形とリンクの色を変える。
簡単にこのブログにスタイルシートを埋め込む方法が分からなかったので
見た目のサンプルはありません。m(__)m

2010/12/31

ChromeExtensionsのpopupで選択中のタブを取得する方法

ポップアップタイプの Chrome Extensions で選択中のタブを取得する方法のメモです。
結論としては、以下のようになります。

chrome.windows.getCurrent(function(currentWindow){
    chrome.tabs.getSelected(currentWindow.id, function(selectedTab){
            :
            :
    })
});

chrome.tabs モジュールにはもっとシンプルな getCurrent() 関数があります。
しかし、ドキュメントに
May be undefined if called from a non-tab context (for example: a background page or popup view).
との記載がある通り、ポップアップタイプのChrome Extensionsで使用しても現在のタブが取得できません。そこで
  1. chrome.windows.getCurrent() 関数で選択されているWindowのIDを取得する
  2. WindowのIDを指定してchrome.tabs.getSelected() 関数で選択中のタブを取得する
という段取りになります。
JavaScript初心者に分かり難いのは、getCurrent()/getSelected() 関数がともに、WindowやTabを受け取るコールバック関数を引数にとるという点です。たとえば、getSelected() であれば以下のような形です。
    chrome.tabs.getSelected(integer windowId, function callback)
    callback --->  function(Tab tab) {...};
そのコールバック関数を無名関数でカスケードさせたのがこの記事の最初のスニペットです。

ところでドキュメントを読めば、chrome.tabs.getSelected()の第一引数WindowIDはOptionalでDefaultはCurrentWindowとなっています。そのため以下のように、第一引数にnullを指定することで、コールバック関数のカスケードを回避するが可能です。

chrome.tabs.getSelected(null, function(selectedTab){
            :
            :
});
とはいえ、JavaSccriptで省略可能な引数を引数リストの末尾に持ってこないのは、ちょっとマナー違反です。明示的にnullを渡さないといけないのですが、これではもう省略可能ではありません。また後でコードを読んだ時に、null が何を表すかわからなくなりそうです。

DjangoTemplateとAjax

Django Template は、サーバー側(GAE)でHTMLを生成する仕組みです。その対比でいくとAjaxは、クライアント側(ブラウザ)でHTMLを生成/変更/削除する仕組みと言えます。ではDjango Templateを使ってAjaxを実現するにはどうしたら良いのか、ちょっと悩んでしまいました...

で、結論としては、Django Templateで部分HTMLを作成してAjaxでHTMLを差し替える、というのが解の1つかと思いました。

つまり以下のようなHTMLを用意しておいて、
<html>
    <head>
            :
            :
    </head>
    <body>
            :
            :
        <div id="TargetForAjax"></div>
            :
            :
    </body>
</html>
getElementById("TargetForAjax").innerHTML = (Templateで作成したHTML)
としてやれば良いわけです。

prototype.jsを使用するのであれば、クライアント側のJavaScriptは以下のような感じです。
new Ajax.Request(
    URL,
    {
        method: "get",
        parameters: {arg: myArgument},
        onSuccess: function(transport){
            Element.update($("TargetForAjax"), transport.responseText);
        },
        onFailure: function(){alert("Something went wrong...") }
    }
);

Ajaxというと受信するデータはついつい、XML/JavaScript/JSONなどを想定してしまいますが、部分HTMLでも良いわけですね。

2010/12/30

DjangoTemplateでGAEデータストアのIDを使用する

2ヶ月ぶりのブログ更新です。遊んでいたわけではなく、GAEとChrome Extensionsで遊んでいた(^_^;)からです。ということで、Code Snippets いきます。

GAEのデータストア内のレコードには、アプリケーション全体で一意となる数値IDが自動でふられます。しかしGAEのドキュメントには、そのIDをDjango Templateで使用する方法が書かれていませんでしたので、メモを残しておきます。

Python側
例えば以下のように、MyModelのレコードを10件取得するとします。
template_values = {
  "items" : MyModel.all().fetch(10)
}

Template側
「key.id」でアクセス可能です。
{% for item in items %}
    {{ item.key.id }}</br>
{% endfor %}

たったこれだけですが、意外に悩んでしまいました。

2010/04/08

バイト配列 から長さを指定してstringを切り出す

バイト配列 から長さを指定してstringを切り出す

    std::string str;
    char* byteData = new char[MAX_SIZE];
         :
    (バッファにデータを追加)
         :
    int bufSize = getDataSize(); // 切り出す文字列の長さを取得する
    str.assign(byteData, bufSize);



バイト配列など'\0'で終端しないデータを
長さを指定してstd::string に 切り出す場合など。

set の要素を、vector の末尾に追加する

set の要素を、vector の末尾に追加するSnipet

    std::set inList;
    std::vector outVector;
         :
    (それぞれに要素を追加)
         :
    std::copy(
     inList.begin(),
     inList.end(),
     std::back_inserter(outVector)); 


コンテナの変換、
複数のsetを1つのvectorに纏めたい場合(?)など。

2010/02/12

ExcelVBAでWebアクセス

' WEBからHTTP Get でデータを取得する
 Private Function getDataFromWeb(inUrl As String) As String
    ' データ取得
    Dim httpObj
    Set httpObj = CreateObject("Microsoft.XMLHTTP")
    httpObj.Open "GET", inUrl, False
    httpObj.send

    ' データ取得結果を確認する
    If (httpObj.Status >= 200 And httpObj.Status < 300) Then
        getDataFromWeb = httpObj.ResponseText
    End If

    ' 後始末
    Set httpObj = Nothing
End Function