はぐれギークLv.1 このページをアンテナに追加 RSSフィード

2011-04-17

CentOS5.5にMadwifiインストール。

なんか超久しぶりのエントリー

自宅のLAN環境がイマイチ過ぎて泣けてきたのでLinuxBoxでルーターを作ることにした。

pppoeとdhcpはまぁすんなりと。

有線環境が整ったところで無線も・・・と思ったら未知領域過ぎてこけまくる。

NICBuffaloのWLI-UC-GNを買ってきて、クライアントモードはなんとか完了したものの、未だAPにするための途上。


ここまで最大のずっこけポイントのMadwifiをとりあえず越えたので備忘録

ath/if_athvar.cの118行目。

//#define ATH_GET_NETDEV_DEV(ndev)      ((ndev)->dev.parent)
#define ATH_GET_NETDEV_DEV(ndev)        ((ndev)->class_dev.dev)

これだけ。

これでmakeが通った。


あとは完成したらまとめを書こう・・・

2011-01-20

言われなきゃ気付かない$.extendの引数。

$.extendも$.fn.extendも同じなんだけど、このメソッドには引数が3種類ある。

まずはメジャー系2種。

$.extend({ foo: 'bar' }); // jQuery.foo = 'bar';

var o = $.extend({ foo: 'bar' }, { fizz: 'buzz' }); // merge but shallow

jQuery自体を拡張する1引数extendと、引数マージする複引数extend

この辺はplugin作ったりなんだりで良く見かける。


わざわざ「but shallow」とか書いた時点でオチが読めるとは思うけど、

第3のコール方法は、deep mergeのためのもの。

var o = $.extend(true, { foo: 'bar' }, { fizz: 'buzz' });

第1引数をboolean値にすると、deep mergeの有無を指定するフラグとして扱われる。


デフォルトがshallow mergeなだけに何かしらdeep mergeする手段はあると思ったけど、こういうことだったらしい。

2011-01-13

superが呼べる継承メソッド。

javascript継承といえば、

var Parent = function() {};
var Child = function() {};
Child.prototype = new Parent();

という感じで「prototype継承」を使うのが普通(だと思う)。


ただ、この手法で困るときがある。

オーバーライドした子クラスメソッド中で親クラスの同名メソッドを呼びたいとき

Child.prototype.method = function() {
  Parent.prototype.method.apply(this);
};

一応上記の方法で子クラスインスタンスコンテキストで呼ぶことはできる。

ただ、記法が冗長になってしまうのと、

クラス名をハードコーディングするか、プロパティ等に保持していないといけない。


というわけで以下のように使える継承メソッド作ってみた

var Parent = function() {};
Parent.prototype = {
  name:   'Parent',
  method: function() {
    alert(this.name);
  }
};

var Child = (function() {}).inherit(Parent);
Child.proto({
  name:   'Child',
  method: function() {
    this.super().method();
  }
});

var p = new Parent();
var c = new Child();

p.method(); // Parent
c.method(); // Child

Functionオブジェクトからinherit()を呼ぶと、引数で与えたFunctionオブジェクト継承する。

また、proto()メソッド既存prototypeに要素を追加できる。

クラスメソッドからsuper()を呼ぶと、

自分自身のコンテキストで親クラスメソッドを呼べるオブジェクトが返る。

なお、何も継承していないクラスオブジェクトから呼ばれた場合は、Objectを親クラスの代わりに使用する。



(´・ω・`)しかし世の中に既にあったりしないんだろうか


id:amachangさんにレビューしてもらえたらなぁ・・・という願望。


コードの中身は以下。

/**
 * inherit.js - utility for class inheritation
 */

(function() {
    Object.prototype.proto = function(proto) {
        for (key in proto) {
            this.prototype[key] = proto[key];
        }

        return this;
    };

    Object.prototype.inherit = function(s) {
        if (typeof(s) != 'function') throw new Error('cannot inherit from non-function variable');

        var f = function() {};
        f.prototype = new s();

        var p = this.prototype;

        this.prototype = new f();
        this.proto(p);
        
        this.prototype.__super_proto__ = s.prototype;
        
        return this;
    };
    
    Object.prototype.super = function() {
        if (typeof(this.__super_proto__) != 'object') this.__super_proto__ = Object.prototype;
        
        if (typeof(this.__super__) != 'object') {
            var s = {};
            var p = this.__super_proto__;
            
            for (key in p) {
                if (typeof(p[key]) != 'function') {
                    s[key] = p[key];
                    continue;
                }

                s[key] = (function(origin, target, method) {
                    return function() {
                        var args = Array.prototype.slice.call(arguments);

                        return (this === origin) ? method.apply(target, args) : new method(args);
                    };
                })(s, this, p[key]);
            }

            this.__super__ = s;
        }

        return this.__super__;
    };
})();

2011-01-11

Functionにまつわる変態的検証。

JavaScript不思議言語構造、Function。

どうなるか気になる挙動があったので確認してみた。

Functionをnewするときとcallするときでthisってどうなるの?

まずFunctionが何かっていうと、

var f = function() {};

のようにして作られる「関数オブジェクト」のこと。

Perl無名関数のように、そのままcallすることができる。

f();

JavaScript独特の挙動として、このFunctionオブジェクトクラスのようにも振る舞う

var o = new f();

とすると、oには「fというクラスインスタンス」とも言えるオブジェクトが入る。

その他prototypeが云々というのもあるが、今回の件とは関係ないので割愛。


そして本題へ

今回の主旨は、「関数としてもコンストラクタとしても呼べるFunctionを両方の呼び方したらthisの値はどうなるのか」を検証すること。

まずは以下のコード

var f = function() {
  alert((this === window));
};

f();     // true
new f(); // false

windowのコンテキストで単に呼ぶとthisがwindowになる。

これは普通の挙動として知ってはいた。

本命は以下。

var f = function() {
  alert((this === window));
};

var Foo = new function() {};
Foo.prototype.normal = function() { f(); };
Foo.prototype.create = function() { new f(); };

var foo = new Foo();

foo.normal(); // true
foo.create(); // false

クラスインスタンスコンテキストで呼んでみたらwindowじゃなくてインスタンスがthisになるんじゃないかと思ったけど、

そうでもないらしい。

どこから呼ぼうとapplyなどでコンテキストを明示しない限りwindowをthisとして実行されるようだ。


つまり、if (this === window)でコンストラクタとして呼ばれたかどうかが分かるわけで・・・フフフ

2010-12-29

Catalyst/PSGIに入門。

遅まきながら、perlの必修項目としてCatalystPSGIに入門することにした。


まずはcpanで以下をインストール

Plack
DBIx::Class
Template
Catalyst
Catalyst::Devel
Catalyst::Engine::PSGI

したらworkspaceで

$ catalyst.pl MyApp

これで原型ができる。

次にplackupするために

$ cd MyApp/
$ ./script/myapp_create.pl PSGI

すると"script/myapp.psgi"が生成される。

このままplackupしたいところだけど、

Can't Locate MyApp.pm

と怒られてしまうので、psgiファイルにちょっと手を入れる。

冒頭の

use MyApp;

より前に

use File::Basename;
use lib sprintf("%s/../lib", dirname(__FILE__));

を追加する。

これでCatalystファイルレイアウトに合った形になるので、

$ plackup script/myapp.psgi

で起動可能。


今日はこれだけ!