カテゴリ: 未分類 - ページ 9

LGPL3.0がすごい

ライセンスについて色々と調べていたところLGPL3.0がとんでもなくすごいライセンスだということに気づきました。LGPL3.0がいかにすごいかを紹介したかったのでちょっと記事を書きます。あと、ここに書いてることはすべて鵜呑みにしないでください、あくまで参考程度にとどめておくようにお願いします。

GPL

オープンソースライセンスとして有名なのは、「GPL」ではありますが、GPLGPLとして配布されているソフトウェアもしくはライブラリを使用した場合はそのすべてのソフトウェアやライブラリをGPLとして公開してね、という超強力なコピーレフトを備えている恐ろしいライセンス。

オープンソースと聞くと、この超強力なコピーレフトが嫌な人も多いと思う。自分もそうで、このGPLのせいでオープンソースのことをちょっと食わず嫌いしていた時期もありました。

GPL汚染

ソフトウェアをオープンソースとしてGPLを使用するのは別にいいとは思うのですが、それがライブラリだとすると話が変わってきます。ライブラリ、つまり、モジュールです。ソフトウェアにそのライブラリを組み込んで機能の一つ、いわゆる一部分としてだけ使いたいのに、GPLだとソフトウェアすべてのソースコードを開示しなくてはならないという、オープンソース界隈ではない人にとっては嫌な存在になるわけで。

LGPL

そこで、そのGPL汚染を解決するために LGPLっていうのができた。これだとライブラリとして使用する分には、ソースコードを公開しなくてもいいよ。ただ著作権表示とか免責事項だけは明記してねっていうのがLGPLで、これを使えばソフトウェア全体としてソースコードを開示する義務を追わなくてすむので、オープンソース界隈ではない人にとっては大喜びのライセンスだったりします。

あと、LGPLとして配布されていたソースコードを改変して使用したいという場合はその改変した部分のソースコードだけを開示すればOK。ソフトウェア全体のコードを開示しなくてもいい。

しかしこれにもちょっとした問題があって、論争がまた起きてる。

  • LGPLで配布されているものは、DLLとかSO形式のものでダイナミックリンクしないとだめだ
  • アプリケーションの内部に組み込んだら違反だ!ソフトウェア全体のコード開示しろ!
  • いや、同じファイルにまとめたとしても、ちゃんと別々になってるし、そもそもソースコード改変してないしソフトウェア全体とは別物だし開示しなくてもいいだろ

などなど・・・。いろんな考え方があります。

そこでLGPL3.0

GNU 劣等一般公衆利用許諾書 (GNU Lesser General Public License)
http://sourceforge.jp/magazine/07/09/05/017211

このページがGoogle検索にひっからなかったのでちょっと探すのに苦労したのですが、sourceforgeオープンソースプロジェクトを作成する場合は、このライセンスが選べるようになっていたりします。

このライセンスに書いてあることを一部抜粋すると、

5. 結合されたライブラリ

あなたは、『ライブラリ』を基にした作品であるライブラリ機能を、『アプリ ケーション』ではなく、かつ本許諾書で保護されていない他のライブラリ機能 と一緒に、単一のライブラリ内で並置し、そのような結合されたライブラリを あなたが選んだ条項に従って伝達することができる。ただしその場合、以下の 両方を行わなければならない。

  1. 結合されたライブラリに、他のいかなるライブラリ機能とも結合されて おらず、本許諾書の条項に従って伝達される、元のままの『ライブラリ』を基 にした作品のコピーを添付する。
  2. その一部が『ライブラリ』を元にした作品である結合されたライブラリ に、対応する結合されていない形式の同じ作品がどこで見つかるかを説明した 目立つ告知を載せる。

これを自分の解釈なりに言い表してみると(間違ってるかも)

あなたがLGPL3.0のライブラリを使用したソフトウェアで、そのライブラリを動的リンクによって外部ファイルとして扱うのではなく、異なるライブラリと一緒にまとめて一つのファイルにし利用する場合は以下のルールに従わなければならない

  1. 一つのファイルとしてまとめられたファイルに含まれるLGPL3.0のライブラリを、異なるライブラリと完全に分離された状態で、元のままのライブラリの形(改変しない)として本来のインターフェースによって使用すること
  2. 一つのファイルとしてまとめられたファイルの中に含まれるLGPL3.0のライブラリのまとめらてない状態のライブラリがどこにあるかを示したURLまたはファイル名の説明書きを行うこと

となった。つまりこれって、前者の問題を解決してることになるんじゃないだろうか。うまく読み進められてないけど、とにかくLGPL3.0はすごいと思った。

idとclassを使用しないjQueryコーディング

idとclass

通常HTMLとJavascriptの関係といえば、予めHTML要素としてidまたはclass属性を指定しておき、その属性に対してjavascript側からidやclassを指定して要素を特定しますが、jQueryを使うことによってidやclassを一切かかなくてもjavascriptで操作することが可能になるみたいです。

jQueryで要素を作成

よくある方法として、

<span class="synIdentifier">var</span> hoge = $(<span class="synStatement">document</span>.body).append(<span class="synConstant">'<div>test</div>'</span>);
Code language: JavaScript (javascript)

のようにして要素を追加をするやり方がありますが、これだとhogeには要素の追加先であるdocument.bodyの要素が参照されます。

しかしこれだと追加した要素を操作することができないためidかclass属性を使用するか $(“document.body:last”)というスマートじゃない方法を使用するしかないです。

これを解決するには、こうします。

<span class="synIdentifier">var</span> hoge = $(<span class="synConstant">'<div>test</div>'</span>);
$(<span class="synStatement">document</span>.body).append(hoge);
Code language: JavaScript (javascript)

やってることは上と一緒ですが、このやり方だとhogeにはjavascriptによって操作したい要素がそのまま参照されるので、このhogeを自由に書き換えることができます。しかも、javascriptで準備してから、appendで画面に表示ということができるので、準備時間があり、ローディング時において画面が瞬間的に点滅したり表示が崩れている様子を隠すこともできます。

jQueryプラグイン作成テンプレートがものすごく便利

jQueryプラグイン

有名どころで[coliss.com/:title=コリス]とかあるけども、jQueryプラグインを紹介しているブロガーの方が最近すごく増えてきているとおもいます。いろんなプラグインがあるんだなぁと見て回っていたりしていたのですが、ふと、functionなんかで関数定義せずに全部jQueryプラグインにしてしまったほうが早いんじゃ・・と気づきjQueryプラグインを効率よく作る方法はないかと探したらありました。

jQuery Boilerplate

jQuery Boilerplate
http://jqueryboilerplate.com/

このテンプレートはMITライセンスで配布されているもので、MITなので著作権表示さえすれば自己責任で自由に使えるというものです。なので再頒布も可能です。

というわけでjQuery Boilerplateにコメントを割り振ったものをここに載せちゃいます。

  • ライセンス MIT License
;(<span class="synIdentifier">function</span> ($, <span class="synStatement">window</span>, <span class="synStatement">undefined</span>) <span class="synIdentifier">{</span>
    <span class="synComment">//プラグインネームの定義</span>
    <span class="synIdentifier">var</span> pluginName = <span class="synConstant">'defaultPluginName'</span>,

        <span class="synComment">//ドキュメント</span>
        <span class="synStatement">document</span> = <span class="synStatement">window</span>.<span class="synStatement">document</span>,

        <span class="synComment">//デフォルト値</span>
        defaults = <span class="synIdentifier">{</span>
            propertyName: <span class="synConstant">"value"</span>
        <span class="synIdentifier">}</span>;
    <span class="synComment">//プラグインの初期化</span>
    <span class="synIdentifier">function</span> Plugin(element, options) <span class="synIdentifier">{</span>

        <span class="synComment">//要素</span>
        <span class="synIdentifier">this</span>.element = element;

        <span class="synComment">//オプション</span>
        <span class="synIdentifier">this</span>.options = $.extend(<span class="synIdentifier">{}</span>, defaults, options);

        <span class="synComment">//デフォルト値設定</span>
        <span class="synIdentifier">this</span>._defaults = defaults;

        <span class="synComment">//プラグインネーム設定</span>
        <span class="synIdentifier">this</span>._name = pluginName;

        <span class="synComment">//初期化</span>
        <span class="synIdentifier">this</span>.init();
    <span class="synIdentifier">}</span>
    Plugin.prototype.init = <span class="synIdentifier">function</span> () <span class="synIdentifier">{</span>
        <span class="synComment">//プラグインの初期化</span>
        console.log(<span class="synConstant">"プラグインの初期化を行っています"</span>, <span class="synIdentifier">this</span>.element, <span class="synIdentifier">this</span>.options);
    <span class="synIdentifier">}</span>;
    $.fn<span class="synIdentifier">[</span>pluginName<span class="synIdentifier">]</span> = <span class="synIdentifier">function</span> (options) <span class="synIdentifier">{</span>
        <span class="synStatement">return</span> <span class="synIdentifier">this</span>.each(<span class="synIdentifier">function</span> () <span class="synIdentifier">{</span>

            <span class="synComment">//初期化</span>
            <span class="synStatement">if</span> (!$.data(<span class="synIdentifier">this</span>, <span class="synConstant">'plugin_'</span> + pluginName)) <span class="synIdentifier">{</span>
                console.log(<span class="synConstant">"初めてプラグインが実行されたのでプラグインの初期化を行います"</span>);
                $.data(<span class="synIdentifier">this</span>, <span class="synConstant">'plugin_'</span> + pluginName, <span class="synStatement">new</span> Plugin(<span class="synIdentifier">this</span>, options));
            <span class="synIdentifier">}</span>

            <span class="synComment">//実装</span>
            console.log(<span class="synConstant">"実装部分をここに書きます"</span>, <span class="synIdentifier">this</span>, options);
        <span class="synIdentifier">}</span>);
    <span class="synIdentifier">}</span>;
<span class="synIdentifier">}</span>(<a class="keyword" href="http://d.hatena.ne.jp/keyword/jQuery">jQuery</a>, <span class="synStatement">window</span>));
$(<span class="synStatement">document</span>.body).defaultPluginName(<span class="synIdentifier">{</span>
    propertyName: <span class="synConstant">'a custom value'</span>
<span class="synIdentifier">}</span>);
Code language: JavaScript (javascript)

初期化関数

このプラグインが使用されたHTML要素が初めての使用だった場合必ず初期化関数が呼び出されます。同じ要素に対して二回目の実行を行なっても「プラグインの初期化を行っています」と書かれている場所は呼ばれません。

「実装部分をここに書きます」と書いてあるところは毎回呼ばれるので、初期化関数には要素のスタイルを適用したりして、毎回実行されるところにはデータの更新などの記述をすると便利になると思います。