getUserMedia でバックカメラを要求する
THE INCAL を読んだ
読んだ。
DUNE で出会ったアレハンドロ・ホドロフスキーとメビウスが再びタッグを組んで作ったフレンチSFコミック。
街の一角のありふれた場面からビッグバンのように爆発して、宇宙を覆い尽くさんばかりに物語が膨らんでいく。読んでいて圧倒される作品。
両性具有の話が小道具として出てくるのだけど、その表現がダ・ヴィンチ・コードと繋がるものがあって興味深かった。
- 作者: アレハンドロ・ホドロフスキー,メビウス
- 出版社/メーカー: パイインターナショナル
- 発売日: 2015/12/18
- メディア: 単行本
- この商品を含むブログ (2件) を見る
Ethereum トークン (ERC20 Token Standard) の残高を取得する
8月頃にプレセールで買ったとあるトークンが最近発行されて、Etherscan や My Ether Wallet でトークンが発行されたことを確認したのだけど、自分用の Wallet App を作ってみたくなったので、プログラムからトークンの残高を取得する方法を調べてみた。
web3 という Ethereum JavaScript API の module を使う。version は 1.0.0-beta.23。
const Web3 = require('web3'); const web3 = new Web3(); const WALLET_ADDRESS = 'XXX'; const CONTRACT_ADDRESS = 'XXX'; web3.setProvider(new web3.providers.HttpProvider('https://api.myetherapi.com/eth')); web3.eth.call({ data: `0x70a08231000000000000000000000000${WALLET_ADDRESS}`, to: CONTRACT_ADDRESS }, "pending").then((res) => { console.log(parseInt(res, 16)); })
data の部分は、コントラクトのメソッドを SHA3 256 でエンコードした値(web3.utils.sha3('balanceOf(address)').substring(0,10)
)とトークンを保管しているアドレスを合わせて、全体が 32 byte になるように結合したもの。
参考
vue-router で初期表示後に、どのルートで解決されたか知りたい
初期ナビゲーションが終わった後のルーターオブジェクトにアクセスすればよい。onReady
と currentRoute
のコンボでいける。
router.onReady(() => { router.currentRoute; });
vue-router ひと通りドキュメントに目を通していたつもりだったのですが、ひさしぶりにみたら router オブジェクトのメソッドが色々増えていたり、学びがあった。
Webpack を使っていてファイルの相対パスを書くのがつらくなったとき
小ネタ。
Webpack(というよりモジュールバンドラ) を使っていて、ディレクトリの階層が深くなってくると import や require でロードするファイルのパスを ../../../../foo.js
のように ../
の数を正確に指定するゲームになってくる。
以下のように書くことで src ディレクトリをルートにしてパスを指定することができるようになるのだけど
resolve: { modules: [ path.resolve(__dirname, 'src'), "node_modules" ], },
同僚氏に npm でいれたパッケージか、src にあるファイルか分からないから、src ディレクトリの alias を定義したらどうか、と勧められた。
resolve: { alias: { '@': resolve(__dirname, 'src'), }, },
これで、どの階層にあるかに関係なく、import store from "@/store"
とか import router from "@/router"
とか書ける。Vue の Progressive Web App template や Nuxt.js でも同様のことをやっている。最悪、記号の単純な置換か、簡単なスクリプトを書けば済むので、筋は悪くないと思う。
Vue で配列を使った算出プロパティの値が変わらないとき
1回ハマったら体が覚えて、次回から気を付けるようになるのだけど、記事にしておく。
例えば、以下のように配列をスタックとして使い、トップを算出プロパティで定義したとき。1秒後にトップの id が 100 になると思いきやそうはならない。Vue は push, pop, splice といった操作のメソッドをラップして、配列の変更を検知しているので、配列の要素へ代入しても配列の変更とはみなされない。
new Vue({ data: { items: [] }, mounted() { this.items.push({id: 1}); this.items.push({id: 2}); this.items.push({id: 3}); setTimeout(() => { this.items[this.items.length - 1] = {id: 100}; }, 1000); }, computed: { top() { if (this.items.length === 0) { return null; } return this.items[this.items.length - 1]; } } });
これを意図通りに動かすには setTimeout のコールバックの処理を次のように splice メソッドを使って変更するように書き換える。
this.items.splice(this.items.length - 1, 1, {id: 100});
vue-router でパスにマッチしたコンポーネントの Vue インスタンスにアクセスする
タイトルが長い。
お仕事で vue-router 絡みのプラグインを書いていてアクセスしたくなった。
VueRouter のインスタンスが router として、以下のようにプロパティを参照することでできる。
router.currentRoute.matched[0].instances['default']
あくまで内部がこうなっているというだけの話で、API として正式に提供されているものではないので注意。
matched が配列になっているのは、ネストしたルートを定義することができるから。
例えば、以下のような定義の場合、/user/3/profile
のようなパスでアクセスしたら、/users/3
で1回、/users/3/profile
でもう1回マッチすることになる。
{ path: '/users/:id', component: User, children: [ { path: 'profile', component: UserProfile }, ], }
instances がオブジェクトになっているのは名前付きビューがあるため。以下のようなルーティング定義をした場合、instances オブジェクトの default, a, b それぞれのプロパティでコンポーネントの Vue インスタンスにアクセスできる。名前付きビューを使っていない場合は default プロパティを参照すれば良いです。
[ { path: '/', components: { default: Foo, a: Bar, b: Baz }, }, ]
(keepalive コンポーネントを使うと話が変わりそうですが)インスタンスの参照はいつ変更される分からないので、参照を変数に入れて、使いまわすとかはしないほうがよさそう。