@peccul is peccu

(love peccu '(emacs lisp cat outdoor bicycle mac linux coffee))

ES6で動的に親クラスを指定する

引数に応じて親クラスを切り替えたいことがあって調べて、Dynamic super classes (extends) in ES6 – MikeDoesWeb が出てきたので試した。

おそらく私はmix-inみたいなことをしたかったのだと思う。

サンプルコードとそれのテスト(使い方の例になると思う)はGitHubに置いた。

github.com

解決法の解説/概要

クラスを直接定義するのではなく、関数スコープ内で定義することで解決していた。

実際に私がやりたかったのはNode.jsで動くならfsを使うクラスを継承して、ブラウザで動くならBrowserFSを使うクラスを継承したかった。 外からみると同じAPIにしたかったので、環境か引数によって必要なバックエンドのクラスを切り替えてテストしたかった。

以下GitHubに置いた解決策の抜粋。

// fsを使うクラス
export class FS {
  constructor(config){
  }
}

// BrowserFSを使うクラス
export class BrowserFS {
  constructor(config){
  }
}

// fallbackクラス
export class DefaultClass {
  constructor(config){
  }
};

// 外からはこの擬似クラス(実態は関数)を使う
const Dynamic = function(config = {}){
  if(!new.target){
    throw "Uncaught TypeError: Class constructor Dynamic cannot be invoked without 'new'";
  }
  // Dynamicというクラスを引数に応じて定義する

  if(config.backend === 'fs'){
    // FSを継承するパターン
    class Dynamic extends FS {
      constructor(config){
      }
    };
    return new Dynamic(config);
  }

  if(config.backend === 'browserfs'){
    // BrowserFSを継承するパターン
    class Dynamic extends BrowserFS {
      constructor(config){
      }
    };
    return new Dynamic(config);
  }
  // fallback
  return new DefaultClass(config);
};
export default Dynamic;

es6-dynamic-class-extends/dynamic.js at master · peccu/es6-dynamic-class-extends · GitHub

使用法はテストコードでイメージできるかと。 (Jest利用、同じく抜粋)

Dynamicはクラスではなく関数なので、instanceof Dynamic はfalseとなる。

import {default as Dynamic, FS, BrowserFS, DefaultClass} from './dynamic';

describe('Dynamically switching parent class', () => {
  test('non specified class', () => {
    let target = new Dynamic();
    expect(target).toBeInstanceOf(DefaultClass);
  });
  test('extends FS', () => {
    let target = new Dynamic({backend: 'fs'});
    expect(target).toBeInstanceOf(FS);
  });
  test('extends BrowserFS', () => {
    let target = new Dynamic({backend: 'browserfs'});
    expect(target).toBeInstanceOf(BrowserFS);
  });
});

es6-dynamic-class-extends/dynamic.test.js at master · peccu/es6-dynamic-class-extends · GitHub

c.f.

github.com

environment

  • .babelrc
{
  "presets": ["@babel/preset-env"],
  "plugins": [
    [
      "@babel/plugin-transform-runtime",
      {
        "regenerator": true
      }
    ]
  ]
}
  • package.json
...
  "scripts": {
    "test": "jest"
  },
  "devDependencies": {
    "@babel/core": "^7.2.2",
    "@babel/plugin-transform-runtime": "^7.2.0",
    "@babel/preset-env": "^7.2.3",
    "@babel/runtime": "^7.2.0",
    "babel-core": "^7.0.0-bridge.0",
    "babel-jest": "^23.6.0",
    "jest": "^23.6.0"
  },
...

git remoteにssh接続するときに秘密鍵を指定する

ssh接続するコマンドを環境変数に指定すればよい。

GIT_SSH_COMMAND="ssh -i /path/to/id_rsa-for-remote -F /dev/null" git ...

... の部分は clone なり push origin branch なりgitサブコマンドを指定する。

flatmap-streamの話の整理

この記事を読んだメモ

qiita.com

対処としてはflatmap-streamに依存しているパッケージはそれを消すか更新しましょう。ということらしい。

以下のコマンドで利用しているか確認できるとのこと。

npm ls flatmap-stream
Read more

見ているページをTwitterにつぶやくブックマークレット

macSafariのバージョンが12?になってShareメニューから呟けなくなったのが不便。 ブックマークレットにした。

↓これをブックバークバーにドラッグしていただければ。

Tweet

Read more