2017年4月20日木曜日

開発環境

メタプログラミングRuby 第2版(Paolo Perrotta (著)、角 征典 (翻訳)、オライリージャパン)の1部(メタプログラミング Ruby)、3章(火曜日: メソッド)、3.1(重複問題)、3.2.3(メソッドを動的に定義する)、3.2.4(Computer クラスのリファクタリング)を JavaScript で取り組んでみる。

HTML5

<pre id="output0"></pre>
<button id="run0">run</button>
<button id="clear0">clear</button>

<script src="sample1.js"></script>

JavaScript

let btn0 = document.querySelector('#run0'),
    btn1 = document.querySelector('#clear0'),
    pre0 = document.querySelector('#output0'),
    p = (x) => pre0.textContent += x + '\n';

let Computer = (computerId, dataSouce) => {
    let that = {},
        id = computerId,
        mouse = () => component('Mouse'),
        cpu = () => component('Cpu'),
        keyboard = () => component('Keyboard'),
        component = (name) => {
            let info = dataSouce[`get${name}Info`](id),
                price = dataSouce[`get${name}Price`](id),
                result = `${name}: ${info} ($${price})`;
            
            return price >= 100 ? `* ${result}` : result;
        };

    that.cpu = cpu;
    
    return that;
};

let Computer1 = (computerId, dataSouce) => {
    let that = {},
        id = computerId,
        defineComponent = (name) => {
            that[name.toLowerCase()] = () => {
                let info = dataSouce[`get${name}Info`](id),
                    price = dataSouce[`get${name}Price`](id),
                    result = `${name}: ${info} ($${price})`;
                
                return price >= 100 ? `* ${result}` : result;
            };
        };

    defineComponent('Mouse');
    defineComponent('Cpu');
    defineComponent('Keyboard');
    
    return that;
};

let Computer2 = (computerId, dataSouce) => {
    let that = {},
        id = computerId,
        defineComponent = (name) => {
            that[name.toLowerCase()] = () => {
                let info = dataSouce[`get${name}Info`](id),
                    price = dataSouce[`get${name}Price`](id),
                    result = `${name}: ${info} ($${price})`;
                
                return price >= 100 ? `* ${result}` : result;
            };
        };

    Object.keys(dataSouce)
        .map((k) => {
            let t = k.match(/^get(.*)Info$/);
            return t ? t[1] : null;
        })
        .filter((name) => name !== null)
        .map((name) => defineComponent(name));

    return that;
};

let output = () => {
    let ds = {
        getCpuInfo: (id) => {
            if (id === 42) {
                return '2.16 Ghz'
            }
        },
        getCpuPrice: (id) => {
            if (id === 42) {
                return 220;
            }
        },
    };

    p('手順1: 動的ディスパッチを追加する');
    let myComputer = Computer(42, ds);
    p(myComputer.cpu());

    p('手順2: メソッドを動的に生成する');
    let myComputer1 = Computer1(42, ds);
    p(myComputer1.cpu());

    p('手順3: コードにイントロスペクションをふりかける');
    let myComputer2 = Computer2(42, ds);
    p(myComputer2.cpu());
};

btn0.onclick = output;
btn1.onclick = () => pre0.textContent = '';

output();




  









						

0 コメント:

コメントを投稿