Hatena::ブログ(Diary)

雑草の音

2018-09-30

JavaScriptオブジェクト指向は、逆の順番で学んだほうが理解しやすいと思うので… 02:48

<title>JavaScriptオブジェクト指向は、逆の順番で学んだほうが理解しやすいと思うので…</title>

JavaScriptオブジェクト指向は、逆の順番で学んだほうが理解しやすいと思うので…

※この投稿は 2011/03/10 に こちら に投稿した記事の転載です。

これを書いた経緯

 事の発端というか、きっかけは、id:perlcodesampleさんとid:gfxさんの下のポストを見て、

 new とか prototype を使うのが推奨されてないとか、直接代入するほうが楽とかじゃなくて、挙動が違うんだよなぁ、と思ったこと。

 挙動が違うんだから、もちろん使いどころも違うんですよね。

 でも実際、JavaScriptオブジェクト指向は混乱しやすいと思います。

 自分もご多分にもれず、さんざん混乱させられたクチですしね。

 わかってしまえば、どってことなくて、とってもシンプルなんですけどね。

 せっかくなので、今だからこそ言える、自分だったらこうやって教えて欲しかったなぁ、っていう説明をしてみようかと思います。

 題して、JavaScriptオブジェクト指向は、逆から入門しろ!

逆からってどこから? → Object.createから

 思うに、JavaScriptオブジェクト指向は、new から入るよりも、Object.create から入ったほうが理解しやすいと思うんですよね。

 Object.create っていうのは、新しいJavaScriptの仕様(ECMAScript 5th Edition)で標準に取り入れられたメソッドで、引数で指定したオブジェクトプロトタイプとする新しいオブジェクトを作ることができます。

 こんなふうにです:

var mam = {
  given_name : "サザエ",
  family_name: "フグタ",
  who_am_i   : function(){ alert(this.family_name + this.given_name);  }
};

var kid = Object.create(mam);
kid.given_name = "タラオ";

mam.who_am_i();  // フグタサザエ
kid.who_am_i();  // フグタタラ
 kidmamメソッド継承していることがわかりますね。

 そもそもJavaScriptオブジェクト指向ってプロトタイプベースの継承なわけで、new とかコンストラクタっていうのはなくてもいいんです。

 この Object.create メソッドからはじめて、従来からある newコンストラクタ、それからprototype プロパティの挙動をみていこうと思います。

 つまり、歴史的に逆順というわけです。

 ちなみに、この Object.create メソッドは、モダンブラウザなら既に実装されているので、実際に実行して試すことができます。(今回自分は、Chrome 9.0で動作確認をしました。)

そもそもプロトタイプってなんなん?

 上のコードを見て、「Object.create の中では新しいオブジェクトを生成して mamプロパティをコピってるんだな、こんなふうに↓」

Object.create = function ( o ) {
    var p = {};
    for ( var i in o ) {
        p[i] = o[i];
    }
    return p;
};

 と思ったアナタ!イイ線いってます!

 でも、事はそれほど単純ではありません。次のコードを続けて実行してみましょう:

mam.call = function(){ alert("カツオ!"); };

mam.call();  // カツオ
kid.call();  // カツオ

 callmam にしか追加していないのに、kid のほうでも使えるようになってしまいましたよ。

 実は mamkid は同じオブジェクトを指している?いやいや、上ので who_am_i を呼んだ時には、ちゃんと別々になってましたよね。

 種明かしをすると、kid は自身にセットされた given_name プロパティ以外はなんにも持っていない、ほとんど空っぽのオブジェクトです。

 ただし、自分が持っていないプロパティについては mam に問い合わせて、mam のものを自分のものとして使おうとするようになっています。

 実は kid はユーザの気づかないところで mam への参照を隠し持っていて、自分が知らないことはmam のマネをするわけなんですね。

 このような特別な関係があるとき、mamkidプロトタイプだと言います。

 また、kidmam に問い合わせたプロパティmam も持っていなかったとしましょう。

 すると mam は、やはり自分が持っている隠し参照を使って、自分自身のプロトタイプへと問い合わせを伝搬させます。

 このようにプロパティの探索をたどっていくリンクの連なりを、プロトタイプチェインと呼んだりします。

 最終的に、この鎖の終端は通常は Object.prototype になっており、終端にたどりついてもまだ該当するプロパティが見つからなかった場合に、プロパティが未定義ということになります。

 Object.create は、オブジェクト間でこのような特別な関係を築いてくれるわけですね。

オーバーライドは子供で値を設定するだけ

 ところで、上の call メソッドでは、kidmam のマネをしてカツオを呼び捨てにしてしまっていました。

 ここはひとつ、もう少し子供らしく呼ぶようにしつけをしてあげましょう:

kid.call = function(){ alert("カツオおにいちゃん"); };
kid.call();  // カツオおにいちゃん

 プロパティ探索の挙動がわかってしまえば、挙動を変えたい場合は単に値を代入してしまえば良いことがわかりますね。

 もちろん、この段階でも mamcall の値は元のままです。



 逆に、kid 独自の挙動を元に戻したいと思ったら、プロパティを削除してやればOKです:

delete kid.call;
kid.call();  // カツオ

 kid からプロパティを消しても、mam からも消えるわけではないので、ふたたびマネをするようになるわけですね。

継承Mixi-in

 ただ同じ振る舞いをさせたいだけであれば、単純に片方のオブジェクトからもう片方のオブジェクトへとすべてのプロパティをコピーしてしまえば良い話です。

 このように既存の実装コードを、まったく関係のないオブジェクト間で再利用するというのは、継承ではなくMix-in(Rubyのincludeとか)の考え方です。

 利用ケースによっては、Mix-inと継承はまったく同じような結果をもたらします。

 しかしプロトタイプ継承を使うと、親への機能拡張メソッドの追加)が、すぐさま子供からも使えるようになるという点が大きな違いです。

 実行時に、プロトタイプチェインに連なっているすべてのオブジェクトについて、一度の変更で機能を追加・変更できます。

 また、どれだけたくさんの子オブジェクトが作られていても、たとえ子オブジェクトにアクセスすることができなかったとしても、変更の影響を及ぼすことができます。

 Mixi-inとは違って、親子オブジェクト間で特別な絆ができている継承でなくては、こう柔軟にはいきませんよね。

 しかし、継承がかさんでプロトタイプチェインがあまりに長くなってしまうと、ずっと親の代で定義されているプロパティを探索するのに多くの時間がかかってしまうことにもなります。(このあたりは処理系最適化にも大きく依存しますが)

 だからといって、なんでもかんでもそれぞれのオブジェクトが自分で持っていては、メモリ効率も悪くなるでしょうし、継承を使った柔軟な挙動変更もできなくなってしまいます。

 結局、継承Mixi-inは適材適所。

 その場で相応しいほうを使い分けることができてこそ、真のJavaScripterというものですよね!

プロトタイプ関係を作れるのはnewだけ(だった)

 ここからは、上で使った Object.create の機能を、従来のJavaScriptだけで実装してみましょう。

 いきなりコードで書くと、こういうことになります:

Object.create = function ( o ) {
    function dummy(){}
    dummy.prototype = o;
    return new dummy();
}

(※実際の Object.create は、変更不可能なプロパティを定義できたりと、3rd Editionの範囲では決して実現できなかった機能も含む高機能なものです!ここではあくまで、プロトタイプ継承関係の構築のみに焦点を当てています。)

 空の関数である dummynew して返す前に、dummyprototype プロパティプロトタイプとなるオブジェクトを設定しているのがミソです。

 JavaScriptでは、 new F(ARGS) という式は、次のように処理されます:

  1. 新しい空のオブジェクトを作る
  2. 新しいオブジェクトプロトタイプとして F.prototype を設定する
  3. F(ARGS) を呼び出す。この時、呼び出され側の this の値として新しく作ったオブジェクトを使う
  4. 3の結果がオブジェクトだったら、これを結果として返す。
  5. そうでなければ、1で作ったオブジェクトを返す  擬似コード的に書くと、こんなかんじ:

function new ( F, ARGS ) {
    var o = {};
    o.__proto__ = F.prototype;
    var r = F.apply(o, ARGS);
    return r != null && r instanceof Object ? r : o;
}

 あれ、ここで使ってる __proto__ って、どこかで見たことありませんか?

 そうです。継承するコードでたまに出てくるやつですね。FirefoxとかChromeとか、特定の処理系だけで使えます。

 実はこれが、上で言っていた「ユーザが気づかないところで持っている隠し参照」のことです。

 処理系によっては、これがユーザから直接触れるようになっているということですね。

 直接いじれちゃえば、もっと細かい制御もやり放題なので、これは便利!なのですが、もちろん、ブラウザ間の互換性が損なわれるので、あまりオススメはしません。

 非標準なAPIは、ちゃんと使える場所と使いどころとをわきまえて使いましょうね。JavaScripterとの約束だよ!

newいらない子(ェ

 上で new を実装するために __proto__ プロパティを使いましたが、 Object.create を標準で手に入れた我々は今や、__proto__ に頼らずともオブジェクトの親子関係を作れる力を手にしたのでした。

 つまり、new に相当する機能をJavaScript標準の機能だけで実装することができるようになったのです!

 こんなふうに:

function New ( F, ARGS ) {
    var o = Object.create(F.prototype);
    var r = F.apply(o, ARGS);
    return r != null && r instanceof Object ? r : o;
}

function Cat ( name ) {
    this.name = name;
}
Cat.prototype.caterwaul = function(){
    alert(this.name + "「ニャーニャー」");
};

var cat = New(Cat, ["タマ"]);
cat.caterwaul();  // タマ「ニャーニャー」

 上では new を使って Object.create を実装する例を示しましたが、今回はその逆です。

 つまり、Object.create が最初からあれば、new っていらなかったってことですね(>_<)

蛇足: なんでわざわざ関数プロパティを経由するようになってるの?

 なんででしょうね?

 ここからは勝手に推測してみますが、たぶん、関数だけでなんとかしてJavaコンストラクタの見た目をマネしたかったんじゃないでしょうか?

 普通は、一連の機能をもったオブジェクトをただひとつ一点物で作る(シングルトンパターンみたいな)ケースよりも、同じ機能をもったオブジェクトをたくさん量産するケースのほうが多いと思います。

 すると当然、オブジェクト初期化を行う処理をサブルーチン化しておいて、その中でオブジェクトを生成して返すことを考えますよね。

 こんなふうに:

function bear ( name ) {
    var k = Object.create(mam);
    k.name = name;
    return k;
}

var kid = bear("タラオ");

 つまるところこれって、コンストラクタですよね?

 また一方で、JavaScriptはその出自から、Javaに見た目を似せなければならないという宿命を持って生まれてきました。(このあたりは、id:badatmathさんのプレゼン資料 がとってもわかりやすいです)

 で、Javaってコンストラクタを呼び出すときには new をつけますよね?

 そこで、new をつけて関数を呼び出したときに特別な処理を持たせ、関数コンストラクタとクラスの2つの役割を押し付けてしまおうと考えたのではないかと思います。

 そうなると、Javaコンストラクタっぽく見せるためには、関数new をつけて呼び出されたときには、新しいオブジェクトが適切に(プロトタイプから継承されて)作られ、this にバインドされていなければなりません。

 そこで、そのコンストラクタ関数)がオブジェクトを生成する際に暗黙的に使うプロトタイプを、コンストラクタ自身に持たせておこう。でも、どの関数コンストラクタとして呼び出されるかはわからないから、すべての関数プロパティで持たせておこう。

 っていうことになったんじゃないかと。

 えっ、JavaScriptは最初からプロトタイプベースのオブジェクト指向を採用するつもりだったのかって?

 それはわかりません。Sun Microsystemsプロトタイプベースの始祖であるSelfの研究者を抱えていたってこと以外、私は知りません。

 開発者のEich氏は、最初からSchemeのような関数型言語を作るつもりだったようですけどね。

書いたあとに一言

 うん!

 長々と書いたわりには、全然わかりやすくなってない気がするね(´・ω・`)

Google Fontsが日本語WEBフォントを正式サポート – Dream Seed 00:03

<title>Google Fontsが日本語WEBフォントを正式サポート – Dream Seed</title>

Google Fontsが日本語WEBフォントを正式サポート

ユーザーの端末にインストールされていないフォントを表示できるWEBフォント。便利な反面、日本語など文字数が多いフォントではファイルサイズが大きくなり、通信量が増えてしまうのが難点です。

しかし、そんな日本語フォントGoogleのWEBフォントサービスGoogle Fontsがサポートしました。といっても、以前から早期アクセスとして提供はされていましたが、正式版になったということのようです。

利用可能なのはゴシック6種 + 明朝2種の8書体。早期アクセスで提供されているものとは書体が異なります。

  • Noto Sans JP
  • Noto Serif JP
  • Sawarabi Mincho
  • Sawarabi Gothic
  • M PLUS 1p
  • M PLUS Rounded 1c
  • Kosugi
  • Kosugi Maru

懸念のファイルサイズについては、フォントスライシングシステムの最適化で対応したとのこと。これは、フォントファイルをまとめてダウンロードするのではなく、幾つかのファイルに分け(スライス)、必要に応じてダウンロードするようにするもの。

日本語の場合、頻出する3000文字を20のスライスに分割するのが最も効果的だったとか。これにより、クライアントフォント全体を送信した場合よりも80%少ないバイト数の転送で済むようになり、結果として日本語フォントの正式対応が可能になったとのことです。

そんな難しい話は置いておいて、日本語フォント実用的なレベルでWEBフォントが利用可能になったと思っておけば良さそうです。

ちなみにこのサイトでも少し前からKosugi Maruを利用しています。

(source Google Developers Blog)

2018-09-29

Pythonで学ぶ『ブロックチェーンプログラミング入門』が良すぎた話 - 🎃toricago🎃 15:08

<title>Pythonで学ぶ『ブロックチェーンプログラミング入門』が良すぎた話 - 🎃toricago🎃</title>

Pythonで学ぶ『ブロックチェーンプログラミング入門』が良すぎた話

ブロックチェーンの社会実装の勢いが止まらない。テック市場に特化したイギリスの調査会社Juniper Researchが、今年の夏に発行した調査レポートの結果によると、

大企業=1万人以上)

とのことだ。

え!導入比率、意外に高くない?国内でも例えば、つい昨日は日本経済新聞の朝刊LINEがトークンエコノミー構想の詳細を明らかにしたことが話題になったりして、たまに見かけるけど、まさかここまで来ていたとは驚きだ。ここまで来てしまうと、そろそろ私のような一介のサラリーマンであっても、ブロックチェーンを理解しておかないといけない雰囲気が漂ってきたと言わざるを得ない。

だが、それが結構難しい。一筋縄ではいかない。ブロックチェーンビジネス書を何冊か読んでみても、わかったようなわからないような「とりあえずブロックチェーンに乗せればなんかスゴイ」というレベルから脱出できない。落ち込む。

そんなことを考えていたら、Codecademyという、オンラインでプログラミングを無料で勉強できるサイトから、メールが届いた。以前、ここのサイトで色々と勉強したことがあったので、メールアドレスがSubscribeされていたのだろう。メールを開いてみたら、『ブロックチェーンプログラミング入門』というコースがオープンしたというお知らせだった。

Want to be able to talk intelligently about Blockchain and apply the fundamentals to your work? After this course you’ll be able to do that and more, including build a blockchain library in Python and create your own blocks through interactive simulations.

ナイスタイミング!!早速だが試してみた。すると結構良かった。無料で、時間はそんなに取られないし、実装の雰囲気もわかるし、ブロックチェーンの理解も深まるし、Pythonでできるので新たな言語を覚えなくても良い!ということでブログでも紹介したいなぁと思った次第である。2018年9月から開始されたばかりの最新オンライン講座、皆さんもいかがでしょう?

どういう内容か?

前半、後半の2部構成となっている。前半はレクチャー形式でコーディングは一切出てこない。ブロックチェーンの仕組みの最低限を学ぶという形で、ビジュアルが充実していてわかりやすいし、20分ぐらいでサクッと終わる。

ただ、事前知識がなければ「わかったようなわからないような…」という状態に陥ってしまうのではなかろうか。実は数週間前に私はちょうど『徹底理解ブロックチェーン』を読み終わったところだったので、復習にもなってよかった。ちなみに、この本はすごいお勧めで、レビューはこちら:

とはいえ、このオンラインコースの前半はおまけのようなもので、むしろ価値があるのは後半だ。後半では、PythonでBlockchainを実装していくという内容で、以下のような流れ。

  • Representing Transactions
  • Creating Blocks
  • Hashing and SHA-256
  • Generating BLock Hashes
  • Creating the Blockchain Class
  • Adding Blocks to the Blockchain
  • Checking for a Broken Chain
  • Hacking the Chain
  • Nonce and Proof-of-Work
  • Implementing Proof-of-Work
  • Adding Blocks to the Chain Securely
  • Blockchain Summary

実際にやってみると、2時間〜3時間(要領の良い人なら2時間以内)で終わるボリューム感である。最低限のブロックチェーンを実装して、Proof-of-Workをしたり、新たなブロックを追加したり、そういうのを一通り体験できる流れになっていて素晴らしい。「こんなに簡単なんだ〜!」と思うところが多かった。例えば、ハッシュ関数を使うためには、この一行だけ。

from hashlib import sha256

それで、何らかのデータをハッシュ値に変換したければ、

text = 'このブロックチェーンコースは楽しいなぁ!'
hash_result = sha256(text.encode())

で終わり!こんな感じで話がポンポン進んでいくので楽しい。(もちろん本格的にやっていくならもっともっと大変なんだろうけど。)

これらをすべて、ウェブブラウザ上で行うことが出来るので、時間のかかるPython環境構築も必要ないし、なんならスマホタブレットでも学習を進められてしまう。使ったことないけど専用アプリもある。ブロックチェーンといえばGPUを思い浮かべる人もいるかもしれないが、最低限を実装するだけなので、そういう機材ももちろん必要ない。しかも数時間で終わるお気軽コース。ウェブに繋がれば誰でもできる。昼食の休み時間を何回か投入するだけで最後まで通せる。

あと、昔のCodecademyは答えを見るという機能がなかったので、わからないときは半日を潰してバグを見つけたりする必要があってストレスが溜まることがあった。でも今回のコースでは何回か誤ると、"See the solution"という項目が表示されるようになっていて、どうしてもわからない場合は答えを見れるという安心感が加わったのもなお良い。非エンジニアにも優しい。

必要なのは多少の英語力とPython力だけ

英語のサイトであるので、多少の英語力は求められる。と言っても、Python用語とBlockchain用語がわかっていれば、問題なく進められる程度だと思う。例えば、

Call the datetime module's .now() method to print out the current date and time.

と言った文章が読めて、やるべきことがわかればOKだ。Pythonのレベル感としては、「クラス」が読めるし自分でも書けるというレベル。入門書を1〜2冊読んだことのある人であれば問題ないはずだ。Pythonの勉強から始めたい人であれば、CodecademyのPythonコースもお勧めである。

(が、PythonならCodecademyじゃなくても、日本語でも良いオンラインコースが多いかもしれない。)

最後に、今回のブロックチェーンプログラミングのコースのリンクを載せて、今回の記事は締めくくるとしよう。気になる人はぜひ試してみては?

2018-09-28

CSS Gridが適しているレイアウト、Flexboxが適してるレイアウトを詳しく解説 | コリス 21:10

<title>CSS Gridが適しているレイアウト、Flexboxが適してるレイアウトを詳しく解説 | コリス</title>

CSS Gridが適しているレイアウト、Flexboxが適してるレイアウトを詳しく解説

UX道場 -UXデザインの基礎知識からUI/Webデザインに役立つ情報、Adobe XDの最新情報まで

CSS GridとFlexboxは、CSSで現在主流となるレイアウトテクノロジーです。

CSS GridとFlexboxは表面的には似ているように感じるかもしれません。しかし、実際には異なるタスクに使用され、それぞれ異なるレイアウトの問題を解決します。

Flexboxが適してる場合、CSS Gridが適している場合、また両方を使用する場合、さまざまなレイアウトの問題を正しく解決する方法を紹介します。

サイトのキャプチャ

Grid vs. Flexbox: Which should you choose?

下記は各ポイントを意訳したものです。

※当ブログでの翻訳記事は、元サイト様にライセンスを得て翻訳しています。

ページ全体のレイアウト

CSS Gridはコンテナベースで、Flexboxはコンテンツベースです。Flexboxのレイアウトではセル(Flexアイテム)のサイズはFlexアイテム自身で定義され、CSS Gridではセル(Gridアイテム)のサイズはGridコンテナで定義されます。

実際のコードを見ながら、詳しく説明します。

水平方向にdiv要素を配置するためのHTMLを用意しました。


1

2

3

4

5

6

<div class="row">

<div>1</div>

<div>2</div>

<div>3</div>

<div>4</div>

</div>


Flexboxを使用して、スタイルしてみます。


1

2

3

4

5

6

7

8

9

10

11

.row {

    margin: 20px auto;

    max-width: 300px;

    display: flex;

}

.row > div {

    border: 1px dashed gray;

    flex: 1 1 auto; /* Size of items defined inside items */

    text-align: center;

    padding: 12px;

}


flex: 1 1 auto;」で、Flexアイテム内のセルのサイズが定義されています。flexプロパティでは順にflex-grow、flex-shrink、flex-basisプロパティを設定することを省略しており、デフォルト値は「0 1 auto」です。

.rowのdiv要素はFlexコンテナで、そこでアイテムのサイズを定義していないことに注目してください。Flexアイテムでサイズを定義しています。

参考: CSS Flexbox の各プロパティの使い方を詳しく解説

上記のコードは、下記のように表示されます。

ブラウザで表示

ブラウザで表示

今度は、CSS Gridでスタイルしてみます。


1

2

3

4

5

6

7

8

9

10

11

.row {

    margin: 20px auto;

    max-width: 300px;

    display: grid;

    grid-template-columns: 1fr 1fr 1fr 1fr; /* Size of items defined inside container */

}

.row div {

    border: 1px dashed gray;

    text-align: center;

    padding: 12px;

}


このスタイルシートはFlexboxで実装したのと全く同じ見た目になります。

ここで注目すべきは、セルのサイズを定義しているのは.rowのdiv要素、つまりGridアイテムではなく、Gridコンテナであることです。

これは非常に重要な違いです。

Flexboxのレイアウトではコンテンツがロードされた後に計算されるのに対して、Gridのレイアウトではコンテンツに関係なく計算されることを示しています。

つまり、Flexboxでページ全体のレイアウトを構築することは表示が遅くなるため、避けた方がよいということです。

隙間が必要なレイアウト

CSS GridとFlexboxの大きな違いは、CSS Gridにはgrid-column-gapを使用してGridアイテムに隙間を作ることができることです。Flexboxには隙間のためのプロパティはありません。

隙間を使ったレイアウト

隙間を使ったレイアウト

Flexboxで同様の結果を得るには、paddingとネストされたコンテナを使用するか、Flexコンテナの幅を広げてjustify-contentを使用する必要があります。

いずれは、CSS Box Alignment Module 3に用意されているマルチカラムのcolumn-gapプロパティを利用できるようになるかもしれません。

1次元と2次元のレイアウト

1次元とは一方向(横行か縦列のいずれか)に配置することで、2次元とは二方向(横行と縦列)に配置することです。これはtableレイアウトの時代からあるコンセプトで、CSS GridもFlexboxもこのコンセプトに基づいています。

1次元に要素を配置するのはFlexboxが適しています。そして2次元に要素を配置するのはCSS Gridが適しています。

Flexboxは1次元、CSS Gridは2次元、と覚えておいてもよいでしょう。よく使用される1次元のレイアウトを見てましょう。

1次元のレイアウト

1次元のレイアウト

HTMLはリスト要素を使用しました。


1

2

3

4

5

6

7

8

<ul class="social-icons">

  <li><a href="#"><i class="fab fa-facebook-f"></i></a></li>

  <li><a href="#"><i class="fab fa-twitter"></i></a></li>

  <li><a href="#"><i class="fab fa-instagram"></i></a></li>

  <li><a href="#"><i class="fab fa-github"></i></a></li>

  <li><a href="#"><i class="fas fa-envelope"></i></a></li>

  <li><a href="#"><i class="fas fa-rss"></i></a></li>

</ul>


Flexboxでリストの各アイテムを1次元(横行)に配置します。


1

2

3

4

5

.social-icons {

  display: flex;

  list-style: none;

  justify-content: space-around;

}


justify-contentプロパティは、Flexコンテナの余分なスペースがFlexアイテムにどのように分配されるかを決定します。space-aroundはFlexアイテムが均等に配置されるようにスペースを分配します。

参考: CSS Flexbox の各プロパティの使い方を詳しく解説

続いて、よく使用される2次元のレイアウトを見てましょう。

2次元のレイアウト

2次元のレイアウト

このレイアウトは、単一の行または単一の列で実装することはできません。複数の行と列が必要です。2次元のレイアウトなので、CSS Gridで実装します。


1

2

3

4

5

6

<div class="container">

  <header>Header</header>

  <main>Main</main>

  <aside>Aside</aside>

  <footer>Footer</footer>

</div>


CSSは下記のようになります。


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

.container {

  max-width: 800px;

  margin: 2em auto;

  display: grid;

  grid-template-columns: 3fr 1fr;

  grid-template-rows: repeat(3,auto);

  grid-gap: 1rem;

}

.container header {

  grid-area: 1/1/2/3;

}

.container main {

  grid-area: 2/1/3/2;

}

.container aside {

  grid-area: 2/2/3/3;

}

.container footer {

  grid-area: 3/1/4/3;

}

.container > * {

  background-color: #ddd;

  padding: 1rem;

}


grid-template-columnsプロパティで2つの列を作成し、grid-template-rowsプロパティで3つの行を作成しています。repeat()関数で、3つの行の高さを作成します。

Gridアイテム(header, main, aside, footer)の内部では、grid-areaプロパティを使用してそれぞれのGridアイテムがカバーする領域の大きさを定義します。

参考: CSS Gridの実装で必要な基礎知識、主要なプロパティと用語をくわしく解説

ラッパー

コンテナ内のアイテムの幅の合計がコンテナの幅より大きい場合、どちらのレイアウトモデルにもアイテムを新しい行に押し出すオプションがあります。しかし、その方法はそれぞれ異なります。

サンプルのレイアウトでその違いを見てましょう。

FlexboxとCSS Gridでそれぞれ6つのdiv要素を配置します。


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

<h2>Flexbox</h2>

<div class="row-flex">

    <div>1 2 3  4 5 6 7 8 9 0</div>

    <div>2</div>

    <div>3</div>

    <div>4</div>

    <div>5</div>

    <div>6</div>

</div>

<h2>Grid</h2>

<div class="row-grid">

    <div>1 2 3  4 5 6 7 8 9 0</div>

    <div>2</div>

    <div>3</div>

    <div>4</div>

    <div>5</div>

    <div>6</div>

</div>


FlexboxとCSS Gridのコードは、下記のようになります。


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

/* Flexbox row styles */

.row-flex {

  margin: 40px auto;

  max-width: 600px;

  display: flex;

  flex-wrap: wrap;

2018-09-26

Node.jsでのイベントループの仕組みとタイマーについて - 技術探し 18:55

<title>Node.jsでのイベントループの仕組みとタイマーについて - 技術探し</title>

Node.jsでのイベントループの仕組みとタイマーについて - 技術探し

  • イベントループ
    • イベントループとは?
    • libuv
    • タスク
    • イベントループの仕組み
      • フェーズ
        • イベントキュー
      • nextTickQueue / microTaskQueue
        • nextTickQueue
        • microTaskQueue
      • Timers Phase
      • Pending Callbacks Phase
      • Idle, Prepare Phase
      • Poll Phase
      • Check Phase
      • Close Callbacks Phase
      • 第一ラウンド
      • 第二ラウンド
      • 第三ラウンド
    • まとめ
  • Timer
    • setTimeout(() => {}, 0)
    • 順番を操作する
  • まとめ
  • リファレンス

イベントループ

f:id:about_hiroppy:20180925085430g:plain

イベントループとは?

イベントループとは、JavaScriptシングルスレッドなのにもかかわらず、効率よくノンブロッキングI/Oを実行できるようにする仕組みです。

イベントループはメインスレッドで実行されます。

ブラウザのイベントループとは異なるので注意が必要です。

Node.jsのイベントループはlibuvに基づきます。

ブラウザのイベントループはhtml5に基づきます。

libuv

Node.jsの非同期はカーネルと会話するためにlibuvを使います。

もともと、Node.jsのために作られたものですが、今は様々なところで使われています。

libuvとは、非同期I/Oに強く、クロスプラットフォーム対応の抽象化ライブラリです。

基本的には、イベントループと非同期処理を行います。

f:id:about_hiroppy:20180926003353p:plain

libuvは、Node.jsにイベントループ機能全体を提供しています。

デフォルトでは、デフォルトサイズが4のスレッドプールを作ります。

Design overview — libuv documentation

イベントループのコードは以下を参照してください。

github.com

タスク

タスクは、同期タスクと非同期タスクの2種類存在します。

setTimeout*1;setImmediate*2;process.nextTick*3;Promise.resolve().then*4;*5();



同期タスクは常に非同期タスクよりも早く実行されます。

また、EventEmitter で発生するイベントはタスクとは呼びません。

このコードの出力は以下の通りになります。

5
3
4
1
2


なぜこのような順番で出力されるかは、次のイベントループの説明でわかるはずです。

イベントループの仕組み

Node.jsが起動すると以下のイベントループが初期化されます。

f:id:about_hiroppy:20180925232715p:plain

http://voidcanvas.com/nodejs-event-loop

https://nodejs.org/en/docs/guides/event-loop-timers-and-nexttick/#event-loop-explained

初期化はされますが、開始前に行われることがあります。

  • タイマーのスケジュール設定
  • process.nextTick等の実行
  • 同期タスクの実行
  • 非同期APIの呼び出し


上記が終わり次第、イベントループが開始されます。

注意点として、イベントループは複数のtaskを同時に処理することはできないため、キューに入れられ順次処理をされるようになっています。

つまり、一つのタスクが完了する時間が長いと健全ではない(イベントループに遅延が出る)ということになります。

また、Node.jsではタスクキューの処理にOSカーネルが依存しているため、タスクを受け取った瞬間を判断することは不可能で、準備ができている場合のみを知っています。

フェーズ

イベントループには6つのフェーズが存在します。

  • timers
  • pending callbacks
  • idle, prepare
  • poll
  • check
  • close callbacks


JavaScriptの実行は、idle, prepare を除くどこかのフェーズで実行されます。

それぞれフェーズには、実行するコールバックのFIFOジョブキューを持ちます。

そのフェーズに入るとそのフェーズの処理が実行され、キューが処理されます。

そして、キューがemptyになるかコールバックの上限に達したらイベントループは次のフェーズへ遷移します。

libuvとの関係図です。

f:id:about_hiroppy:20180925214205j:plain

Handling IO — NodeJS Event Loop Part 4 – The JS Blog

libuvは、各フェーズ毎にフェーズの結果をNodeに伝達する必要があります。

このときにnextTickQueueとmicroTaskQueueに入れられたイベントのキューをチェックします。

もし、キューが空ではない場合は空になるまでキューの処理を行い、メインのイベントループのフェーズへ移行します。

つまり、各フェーズ後(フェーズが移行する前)にnextTickQueueとmicroTaskQueueが実行されるということです。

フローは以下の図のような感じになります。

f:id:about_hiroppy:20180925083813p:plain

What you should know to really understand the Node.js Event Loop




イベントキュー

libuvから提供されるキューとNodeが提供するキューの6種類があります。

  • libuv
    • Expired timers / intervals queue 
    • IO Events Queue 
    • Immediates Queue 
    • Close Handlers Queue
  • Node
    • nextTick Queue
    • microTask Queue


nextTickQueue / microTaskQueue

code: ib/internal/bootstrap/node.js#L77-L78

code: lib/internal/process/next_tick.js

先にnextTickQueueとmicroTaskQueueの説明をしたいと思います。

この2つはlibuvによる提供ではなく、Nodeにより実装されています。

先程の説明の通り、イベントループの各フェーズの後にnextTickQueueとmicroTaskQueueに入れられたイベントのキューをチェックし、空になるまで実行します。

また、この2つはイベントループのフェーズの一部ではないことに注意してください。

nextTickQueue

process.nextTickを使用して登録されたコールバックを保持します。

すべての非同期タスクの中で最速となります。

nextTickは再帰的に呼び出すとNodeをブロックする可能性があるため注意です。

microTaskQueue

Promisesオブジェクトのコールバックはここに所属します。

microTaskQueueに入っているPromiseはV8によって提供されるネイティブのみが適用対象とされます。

イベントループと同様にnextTickQueueが空になり次第、実行となります。

process.nextTick*11;Promise.resolve().then*12;process.nextTick*13;Promise.resolve().then*14;process.nextTick*15;




1
3
5
2
4


先にnextTickQueueが消費されているのがわかります。


ここまでの説明で、以下がなぜこの順番になるのか半分ぐらいわかるかと思います。

setTimeout*16;setImmediate*17;process.nextTick*18; // 2Promise.resolve().then*19;  // 3*20(); // 1


次からは各フェーズの説明を行っていきます。

Timers Phase

code: src/timer.c#L147-L164

イベントループの開始フェーズです。

このフェーズでは、setTimeoutsetInterval のタイマーのコールバックを実行します。

タイマーを最小ヒープに保持し、Nodeは有効期限が切れたタイマーを確認し、コールバックを呼びます。

複数の有効期限が切れたタイマーが存在する場合、登録した順番に実行されます。(FIFO)

OSスケジューリングや他のコールバックの実行により遅延が発生する可能性があり、Node.jsではコールバックの実行する正確なタイミングや順序付けは保証されません。

指定された時間のできるだけ近い時間で呼び出されます。

https://nodejs.org/api/timers.html#timers_settimeout_callback_delay_args

const start = process.hrtime();

setTimeout(() => {
  const end = process.hrtime(start);

  console.log(`timeout callback executed after ${end[0]}s and ${end[1]/Math.pow(10,9)}ms`);
}, 1000);




# output
timeout callback executed after 1s and 0.0070209ms
timeout callback executed after 1s and 0.004651383ms
timeout callback executed after 1s and 0.001348922ms


毎回異なる結果となり、0ms となることはありません。

Pending Callbacks Phase

code: src/unix/core.c#L765-L784

イベントループのpending_queueに存在するコールバックを実行するフェーズです。

完了、エラーのI/O操作のコールバックが実行されます。

pollフェーズの最後のラウンドで実行されるコールバックは実行できず、このラウンドのpending callbacksフェーズまで延期となります。

Idle, Prepare Phase

code: src/unix/loop-watcher.c#L48-L60

libuvによって内部的に呼び出されるフェーズです。

次のフェーズであるPoll Phaseが開始されるたびにPrepareも実行されます。

Poll Phase

code: src/unix/posix-poll.c#L134

このフェーズは、サーバの応答、まだ返されていないI/Oイベントを待機するために使用されるポーリング時間です。

新しいソケットコネクトやファイルの読み込みなどの新しいI/Oイベントを取得し、実行します。

このフェーズでは、以下の2つのことを行います。

  • I / Oをブロックしてポーリングする時間を計算する
  • キュー内のイベントを処理する


ポーリングする時間を計算します。(これは様々な状態によって結果が変わります)

I/Oの処理をシステムコールの epoll のキューに全て登録します。

epoll_waitシステムコールを呼び、ポーリングを行います。

完了したら、コールバックを呼びます。

キューになにか存在する場合、キューがemptyになるかシステム依存の限度に達するまで順次同期実行を行います。

キューが空の場合、以下の2つのうち1つが実行されます。

  • スケジューリングされている場合、イベントループはこのフェーズを終了し、次のcheckフェーズへ進みスケジュールされたスクリプトを実行する
  • スケジュールされていない場合、イベントループはコールバックがキューへ追加されるのを待ち実行する


Check Phase

setImmediateのコールバック専用フェーズです。

setImmediateで登録されたすべてのコールバックを実行します。

timerフェーズのものとは異なり、専用のフェーズがあるため、必ず実行が保証されます。

つまり、pollフェーズで実行されていたコールバック内にsetImmediateが存在すれば、setTimeoutよりも先に呼ばれることが保証されます。

Close Callbacks Phase

code: src/unix/core.c#L293-L305

すべての close イベントのコールバックが処理されます。(e.g. readable.on('close', () => {}))

もし、キューに処理するものがなければ、ループが終了となります。

存在すれば、timerフェーズへ遷移します。

const { readFile } = require('fs');

const timeoutScheduled = Date.now();

setTimeout(() => {
  console.log(`delay: ${Date.now() - timeoutScheduled}ms`);
}, 100);

readFile(__filename, () => {
  const startCallback = Date.now();

  while (Date.now() - startCallback < 500) {}
});




# output
delay: 502ms


このコードをぱっと見た時に、100ms後にdelay: 100msと出力されるだろうと思うかもしれません。

このコードのフローを説明します。

第一ラウンド

スクリプトが最初のイベントループに入ったときには、まだ有効期限が切れたタイマーが存在しておらず、実行可能なI/Oコールバックも存在しません。

つまり、この第一ラウンドはポーリングフェーズに入り、カーネルからのファイル読み込み結果を待ちます。

このときは、ファイルの読み込みが軽量であり、タイマーよりも早く結果を取得します。

例えば、setTimeoutに時間を100ではなく0や1にしていた場合、ファイルの結果よりも先にタイマーの有効期限が切れるため、次のループで結果が変わります。

第二ラウンド

今回は、100msでやっていて、ファイルの読み込みのほうが速く、まだtimerの有効期限が切れてません。

もし、0や1であれば、delayが出力されていたでしょう。

すでに、ファイルは取得できているため、pending callbacksフェーズに入ります。

このコールバック内では、500msの同期処理を実行させています。

そして、このコールバックはジョブキューに入っており、次のフェーズへ移行するには、キューを空にする必要があります。

なので、ここで500msの遅延(500msを停止させた)が発生したということになります。

無事、500msの実行が終わったらキューが空になるため、次のイベントループへ移行します。

第三ラウンド

すでに第二ラウンドの遅延により、タイマーの有効期限が切れるため、setTimeoutはタイマーフェーズ中に実行され、delayを出力し終了します。

The Node.js Event Loop, Timers, and process.nextTick() | Node.js

まとめ

setTimeout*21;setImmediate*22;process.nextTick*23;Promise.resolve().then*24;*25();




5
3
4
1
2


なぜこの順番の出力になるかは上記のイベントループの流れでわかるかと思います。

1. 同期タスク: *26();2. 非同期タスク::nextTickQueue : process.nextTick*27;3. 非同期タスク::microTaskQueue: Promise.resolve().then*28;4. 非同期タスク::timers phase: setTimeout*29;5. 非同期タスク::check phase: setImmediate*30;



  • イベントループはメインスレッドで実行される
  • イベントループは複数のタスクを実行できず、キューに入れられたのを順次処理する
  • イベントループには6つのフェーズが存在する
  • フェーズが遷移する前にnextTickQueueとmicroTaskQueueが実行される


Timer

Node.jsで使えるタイマーは以下の4つとなります。

setImmediateprocess.nextTickNode.js固有でありブラウザにはないことに注意してください。

setTimeout
setInterval
setImmediate
process.nextTick


setTimeout(() => {}, 0)

setTimeout*31;setImmediate*32;process.nextTick*33;


上記の出力は以下のようになります。

nextTick
setTimeout
setImmediate


nextTickが一番最初に来るのは最初に説明したとおりです。

そして、timersフェーズが来て、checkフェーズなのでこのような出力となります。

しかし、この出力は保証された出力ではありません。

timerフェーズに入ったときに有効期限が切れたかわからないためです。

さて、setTimeout0の時の遅延はどれぐらいなのでしょうか?

第二引数の範囲は、1msから2147483647msと決められており、範囲外の指定をしたときには、1msとなるように規定されています。

つまり 0のときは1msより大きい値となります。

Timers | Node.js v10.11.0 Documentation

ちなみに、setTimeout4msに指定したら自分のPCではsetImmediateが先に出力されるようになりました。

setImmediate は、pollフェーズ後に保証された実行ができるため、使う場面によっては、有用な使い方が可能となります。

順番を操作する

const { readFile } = require('fs');

readFile(__filename, () => {  setTimeout*34;  setImmediate*35;
});




setImmediate
setTimeout


上の例だと必ず setImmediate が先に出力されるようになります。

それは、最初にpending callbacksフェーズに入り、その次がcheckフェーズだからです。

timersフェーズは過ぎてしまっており、次のループなため出力が遅れるのです。

まとめ

ブラウザとは違う部分がありますが、macroTasksやmicroTasksの考えなどは同じ部分があります。

ちなみにブラウザはこの記事がわかりやすいです。

jakearchibald.com

動画はこちら

Philip Roberts: What the heck is the event loop anyway? | JSConf EU - YouTube

イベントループは理解するまで難しいコンセントではありますが、一度理解すればコードの理解が深まったり、最適化できたりします。

(よく言われる「わからないでnextTickを使うのは危険」っていう話とか)

なにかあれば、Twitterまでどうぞ!

リファレンス


次にソフトウェアエンジニア採用した際に教材にしたい本(基礎教養部分) - terurouメモ 13:15

<title>次にソフトウェアエンジニア採用した際に教材にしたい本(基礎教養部分) - terurouメモ</title>

次にソフトウェアエンジニア採用した際に教材にしたい本(基礎教養部分)

受託の仕事がひと段落したので、現実逃避がてら内容が古い・良くない社内図書の整理を行っていた。整理しながら「そういえば基礎教養部分の社員教育カリキュラムがまったく準備できてないなぁ」と思い、社内図書をベースに教育用に課す本を考えてみた。

以前から「日本語作文能力が足りない〜」と言ってきていたのだが、それに対しての現時点の暫定解がこれかなぁと思っている。

世界一やさしい課題解決の授業


とりあえず最初に読む本。ごく当たり前の話がサクっと書いてあるが、意識がないと全く身についてない話でもある。

読むだけなら数時間(読むのが早い人であれば、30分もあれば読める)、演習もやるなら1日〜1.5日程度。

デキる大人の文章力教室(暫定、省略可)

デキる大人の文章力教室
小林 洋介
日本文芸社
売り上げランキング: 118,760


類書は多いので、別にこれでなくてもよい。軽く数時間〜半日読んで、手元に置いて必要時に読み返せれば十分。

新卒採用の初っ端によく見る「学生っぽい幼稚な文章表現」を矯正する(認知させる)ために使う。切り口は違うのだが、後述の「数学文章作法」と被る内容も多いので、教育時間がなかったり、2年ぐらいの業務経験がある人なら省略してもいいかもしれない。

数学文章作法 基礎編・推敲編

数学文章作法 基礎編 (ちくま学芸文庫)
結城 浩
筑摩書房
売り上げランキング: 25,822




数学文章作法 推敲編 (ちくま学芸文庫)
結城 浩
筑摩書房
売り上げランキング: 28,004


THE 基礎教養。仕事で日本語文章を書く全ての人間は読むべき。

ページ数が少ない本ではあるが、1日〜2日程度かけてじっくり読んだ方がいい。時間的に早く読み終わってしまった場合は、休憩を挟んで読み直しさせるのもいいぐらい。

類書に有名な「理科系の作文技術」があるが、今なら「数学文章作法」だけで十分だと思う。「理科系の作文技術」は名著であることは間違いないのだが、エピソードトークみたいなものが若干多いせいで内容が分かりづらくなっている面もあり、「数学文章作法」の登場によって役目は果たしたのかなと思う。

「聞く技術」が人を動かす(暫定、省略可)


端的には「相手を怒らせない」「相手のモチベーションを下げない」受け答えの仕方が書かれた本。教育側が「他人との会話することが得意ではないな」と感じた場合は読ませた方がよい。話すのが得意なタイプであれば省略しても構わない。

数時間〜半日程度で読んだら、手元に置いておいて何度も見返すタイプの本。ただ、この本は若干読みづらいなとは思っているので、もっと良い類書が見つかれば差し替えると思う。

メール文章力の基本 大切だけど、だれも教えてくれない77のルール(暫定、省略可)


類書は多いので、これも別にこの本でなくても構わない。これも数時間〜半日程度読んで、手元に置いて必要時に読み直すタイプの本。

新卒採用の場合は必読として、中途採用でもメール文章を書くのが苦手な人(もしくはあまり書いてきてない人)は割と見かけるので、念のため読んでもらった方がいい。仕事で出すメールなんてほとんどのケースが定型なのだけど、定型文をちゃんと学習できてないことで、メールの往復回数が無駄に多くなって時間を無駄にしたり、「お前それ喧嘩売ってるよね」みたいな文章を平気で出してしまってトラブルになったりを未然に防ぐことができる。

顧客折衝をガンガンやってきましたみたいな人の場合は、当然読まなくてよい。

考える技術・書く技術


ロジカルシンキング・ロジカルライティングの名著。前述までの本とは違って、一気に難易度が上がるのだが、世の中のロジカルシンキング・ロジカルライティング本は大体これの派生みたいな感じがあるので、最初からこれを読んだ方がよい。

できれば1週間ぐらいかけて、要約しながら読むという感じで進めたい。

プログラムは技術だけでは動かない ~プログラミングで食べていくために知っておくべきこと(省略可)


これは厳密には基礎教養というよりかは、おっさんが話す「やらかさないようにこうした方がええで」とか「業界で食ってくならこういう立ち振る舞いをしたほうがええで」的な経験則に沿った内容を体系立てて1冊にまとめた本というべきか。受託開発ありきな内容に若干偏っているところ

*1:) => console.log(1

*2:) => console.log(2

*3:) => console.log(3

*4:) => console.log(4

*5:) => console.log(5

*6:) => console.log(5

*7:) => console.log(1

*8:) => console.log(2

*9:) => console.log(3

*10:) => console.log(4

*11:) => console.log(1

*12:) => console.log(2

*13:) => console.log(3

*14:) => console.log(4

*15:) => console.log(5

*16:) => console.log(1

*17:) => console.log(2

*18:) => console.log(3

*19:) => console.log(4

*20:) => console.log(5

*21:) => console.log(1

*22:) => console.log(2

*23:) => console.log(3

*24:) => console.log(4

*25:) => console.log(5

*26:) => console.log(5

*27:) => console.log(3

*28:) => console.log(4

*29:) => console.log(1

*30:) => console.log(2

*31:) => console.log('setTimeout'

*32:) => console.log('setImmediate'

*33:) => console.log('nextTick'

*34:) => console.log('setTimeout'

*35:) => console.log('setImmediate'

2018-09-25

これを読んで稼げない人はやめた方が良いと思う!アフィリエイト初心者向け良記事まとめ | アフィリエイトボンバー 07:37

<title>これを読んで稼げない人はやめた方が良いと思う!アフィリエイト初心者向け良記事まとめ | アフィリエイトボンバー</title>

これを読んで稼げない人はやめた方が良いと思う!アフィリエイト初心者向け良記事まとめ

いつもお世話になっております。

umiです。エルモと呼ばれることが多いです。

アフィリエイターブロガー界隈では有料noteが話題ですね。

アフィリエイトブログで稼ぐノウハウを有料コンテンツとしてnoteというプラットフォームで販売して儲けよう、という話です。

これに関して私は販売する側、儲ける側は好きにすれば良いんじゃないかと思います。

情弱から搾取している」

という意見も多々見られますが、お小遣い稼ぎたいと思っている若者に数千円のnoteを売っている人よりも、定年退職した人達に数千万単位で詐欺まがいの投資信託とか売ってる金融会社の人たちの方が半人道的な商売をしているかなと私は感じます。

それよりも問題は買う側のリテラシーの低さかなと思います。

正直私はブログアフィリエイトで月数万〜数十万稼ぐためのノウハウはネットで無料で読める情報で十分達成出来ると思います。後はやる気の問題かと。

月数百万以上になってくると、対象者の数が少ないので「無料の情報⇛一部の人から収益を得る」という広告ビジネスが非常に難しいため、無料での情報がほとんどありません。

そういった人(月数百万以上稼いでいる人)は信頼出来るところであれば有料でも情報を買いたいと思ってしまうもんです。※求めている人は結構多いと思います

ただ、まだあんまり収益を上げられていない初心者はネット上にたくさんいるため、「無料の情報⇛一部の人から収益を得る」という広告ビジネスで十分収益を得ることが出来ます。そのため現在ネット上にはそういった情報がたくさんあります。

しかしたくさんありすぎてどれが正しいかわからない。

という問題がありますね。だからnoteを買うんだと思います。

有料だから信頼出来る情報だと思って。

残念ながらそれは幻想です。

僕は有料noteをほとんど買ったことがないのでわかりませんが、少なくともネット上に転がっている無料の情報より有料の情報が優れているということは絶対ないと言い切れます。

なぜなら無料で読める情報にも中にはこれ以上ないくらい有力な情報があるからです。

というわけで本ページでは私がとても参考になったネットで無料で読めるまさに「有料級」のウェブページをまとめて紹介します。サイトではなくページで紹介します。サイトだとそこから良いページ探す力がないとダメだからね。

0から1向けの人に教えたい優良ウェブページ

まだ全然稼げてない、取り組んではいるけど何が正解か全然わからず雲を掴むような思いで取り組んでいる人は以下の3ページ+1を読みましょう。

ブログアフィリエイトはてなブログなど無料ブログで簡単に始めることが出来ますが、正直迷ったらWordPressで開設した方が良いです。

というのも無料ブログは運営者側に睨まれるとブログの運営ができなくなってしまう恐れがあるからです。

例えばブログアフィリエイトで人気のあるはてなブログは、アフィリエイト広告そのものを禁止しているわけではありませんが、ある程度厳しいガイドラインがあります。

はてなブログのガイドライン

WordPressで運営すれば広告の貼り方でブログ運営ができなくなるなんてことはないので、WordPressで始めた方が良いと考えます。

サーバに関しては別にどこでも良いですが、安くて早くて人気のあるエックスサーバで良いと思います。細かく調べる暇があったらさっさとこれで始めましょう。

ASPの登録に迷っている暇があったらこのページを参考に登録しましょう。全部しなくても問題ありません。むしろ登録するASPは出来る限り絞った方が良いと思います。

最初はとりあえず「a8net」「バリューコマース」「アクセストレード」「アフィリエイトB」辺りを登録しておくことをおすすめします。

サイトの作り方に関してはこの記事を読んでおけばだいたいわかると思います。

実際に運営しているサイトも紹介されているのでとても参考になりますよ。

わからない用語などがあれば自分で調べて理解しましょう。それが出来ない人はアフィリエイトで稼ぐことが絶対無理なので別の道を考えましょう。

基本的な記事の構成(見出しとか記事の雰囲気みたいなやつ)や装飾(文字の色や大きさ)はこの2つの記事を真似すれば良いですよ。

ライティングに関する記事です。ライティングに関してはこの記事に書いてあることを取り入れればだいたい外さないと思います。

いきなりすべてを取り入れることは出来ないと思うので、少しずつ取り入れて行きましょう。

このブログの記事です。意外と誰も教えてくれないことを書いたつもりです。これから始める人は右も左もわからないと思うので一応いれておきました。

1〜10以上を目指す人のための優良ページ

少しずつ、なんとなくわかってきて、初報酬とか入ってくるくらいになった以上の人向け。

いわゆるコンテンツSEOの答えのような記事。まあ見ての通り実践するのが大変です。

しかし競合性の高いキーワードで上位表示するには少なくともこれくらいの熱量が必要です。

少なくともこれくらいやらないとガッツリ稼ぐことは出来ません。

コンバージョンに関する数少ない優良記事。アフィリエイトのやり方がわからない時にとても参考になりました。書いてあることの意味がわからないという人はまだそのレベルまで達していないのかも。

このブログの記事。キーワード選びについて結構詳しくまとめました。初心者にはちょっとわかりにくいところが多めかもしれません。

サーチコンソールの使い方、改善方法をわかりやすくまとめた記事。サーチコンソールはもはや必須ツールですが、ある程度のアクセス数が必要です。というわけである程度報酬がある人向けかな。

外注戦略に関する良記事。

正直これが実践出来るアフィリエイターはすでに月100万以上は軽く稼いでいるのではないでしょうか。

というくらいやはり実践が難しく、熱量が必要です。

ただアフィリエイトで稼ぐというのはこういったベテランの組織アフィリエイターと同じ土俵(検索)で戦うことになるということだけは知っておきましょう笑

まとめ

今回、最近はあまりシェアされることのないやや古めの記事(失礼?)を中心に紹介しました。

公開日が2年以上前のものも多いですが、どれも未だに廃れることなく実践すれば稼ぐことが出来る再現性のあるものばかりだと思っています。

ただ、再現性のあるノウハウというのは真似されやすく、真似されない優良な再現性のあるノウハウというのは中々実践が出来ないものとなっています。

※逆に言えば誰でも出来る再現性のあるノウハウはすぐに真似されて使い物にならなくなってしまいます

上記はいずれも実践するハードルがやや高いですが、故に廃れにくい手法であると考えます。

  • 実践する
  • 継続する
  • とにかく記事を書く

が最初は重要ですね。

また、これ以外にもまだまだ無料で読める良い記事はたくさんあると思います。

「これは入れとけよ!」

っていうのがあれば教えてください。

加えてもし上述した記事よりも圧倒的に素晴らしい有料noteがあったら教えてください。

SSHなるものをよくわからずに使っている人のための手引書 07:29

<title>SSHなるものをよくわからずに使っている人のための手引書</title>

SSHなるものをよくわからずに使っている人のための手引書


SSHとは

SSHとは、セキュアな通信を行うためのプロトコルです。

たとえば、HTTPHTTPを通してブラウザからWebサイトにアクセスし、

コンテンツを閲覧したりWebアプリを利用したりします。

この「HTTP」というのもプロトコル一種です。

HTTPSSHOSI参照モデルと呼ばれる層の最上位、アプリケーションレイヤーに位置しています。

なお、よく聞く「OpenSSH」とは、このSSHプロトコルを実現するための

有名なソフトウェアプログラム)のひとつです。

FTPプロトコルで言うFileZillaとか、そういったイメージです。

このSSHを使うと、リモートサーバに安全にログインできたり、

ファイルをセキュアに送受信することができたりします。

SSHは「Secure Shell」の訳で、リモートシェルに特化しています。

公開鍵認証という仕組みを用いて、セキュアな通信を実現しています。

同じ公開鍵認証を用いる仕組みに、「SSL」というものがあります。

SSLを聞いたことがなくても、「HTTPS」を聞いたことがある人は多いですよね。

HTTPS」は、「HTTP over SSL/TLS」と呼ばれ、SSLという仕組みを用いて

HTTP通信を行う、というものです。

さて、SSHの説明に戻ります。

最近で言うと、AWSの人気やGithubのユーザ数増加などによって、

あまりセキュリティそもそもUnix系のコマンドに詳しくない方でも

チュートリアルにしたがって「ssh-keygen」なるコマンドをターミナルにおそるおそる

入力してみたり、なんかわけわからない文字列をコピーしてGithubの設定画面に

コピーしてみたり。。。でもこれ本当に安全なのか、間違って大事なもの(秘密鍵)を

公開してしまってないかとか。。。

そんな背景もあって、SSHがよくわからない人のために、

SSH通信の設定を通して、なるべくわかるように説明してみます。

間違っている箇所や説明が足りない箇所があればぜひ教えて下さい。

SSHログイン認証には、以下の方法があります。

1. パスワード認証

ユーザ名とパスワードが分かれば誰にでもログインされるので、

SSHの設定ファイルを変更して無効にするのが標準です。

2. 公開鍵認証による接続

事前にローカル側で作成した公開鍵を、ログイン先のサーバに登録することで、

登録された公開鍵に対応した秘密鍵を持っているクライアントのみが接続できます。

パスワード認証」と比べ事前の準備が必要となりますが、より安全な認証です。

詳細な手順については、後述します。

SSHことはじめ

状態確認:

# sshdSSHデーモン)が動いていることを確認(CentOSなど)
$ lsof -i:22
$ lsof | grep sshd

# もしくはssh-agent(Macなど)
$ lsof | grep ssh-agend

~/.ssh/known_hosts

一度接続したことのあるサーバSSHサーバ証明書は、

クライアント側のホームディレクトリの中、~/.ssh/known_hostsに格納されます。

# known_hostsファイルの内容を表示
$ cat ~/.ssh/known_hosts

公開鍵認証について

  1. クライアント側)公開鍵と秘密鍵を生成
  2. クライアント側→サーバ側)公開鍵をコピー・サーバ側に設置

1. (クライアント側)公開鍵と秘密鍵を生成

# 公開鍵と秘密鍵を生成
$ ssh-keygen

...

上記コマンドを実行すると、~/.sshディレクトリがまず作成され、

その中に公開鍵(id_rsa.pub)と秘密鍵(id_rsa)が作成されます。

この秘密鍵は誰にも渡さない・公開しないようにしてください

公開鍵の方は、サーバに登録します。テキストファイルなので

中身を確認してみましょう。

$ cat ~/.ssh/id_rsa.pub

なお、ssh-keygenコマンドを実行する際に、暗号のタイプを指定することができます。

暗号の種類には、「rsa1」「rsa」「dsa」から選択できます。

Q. 「rsa1」「rsa」「dsa」。。。なにが違うの?

Type Merit Demerit
RSA1 SSH1で使える SSH1には脆弱性がある
DSA SSH2で使える 鍵長が1024bitと短め
RSA 鍵長が最長4096bitと長め 特に無し

SSH1をサポートする必要がある場合などがあれば、RSA1などが検討候補と入ってくると思いますが、

大抵の場合はRSAで事足りると思いますし、この選択肢の中では一般利用であればRSAが最善策だとだと思われます。

(もちろん加味すべき要因は多々あるかと思いますが。。。)

http://security.stackexchange.com/questions/23383/ssh-key-type-rsa-dsa-ecdsa-are-there-easy-answers-for-which-to-choose-when

Q. 「パスフレーズ」を求められるのはなぜ?

パスフレーズは、秘密鍵を使う際に必要なパスワードです。

万が一秘密鍵が盗まれてしまったり漏洩してしまったりしたとしても、

その秘密鍵を使うためにはパスフレーズが必要なので、

なりすましを防ぐことができます。

念には念を入れる、ということですね。

なお、パスフレーズはのちのち変更することができます。

変更したい場合は、ssh-keygen -pを実行してください。

man ssh-keygenコマンドを実行しマニュアルを開くと、

推奨されるパスフレーズについて、以下の様な記述がされています。

A passphrase is similar to a password, except it

can be a phrase with a series of words, punctuation, numbers, whitespace, or any string of characters you want. Good passphrases are

10-30 characters long, are not simple sentences or otherwise easily guessable (English prose has only 1-2 bits of entropy per character,

and provides very bad passphrases), and contain a mix of upper and lowercase letters, numbers, and non-alphanumeric characters.

  • 10~30文字程度
  • 推測しやすい文章を避ける
  • 大文字小文字、数字、記号を混ぜる

Q. 「randomart」ってなに?

ssh-keygenコマンドを実行して、画面の指示にしたがってパスフレーズを入力すると、

下記のような謎の記号絵図がいきなり出現します。この記号絵図はなんのためにあるのでしょう?

The key's randomart image is:

			
      • [ RSA 2048]----+
| o=. | | o o++E | | + . Ooo. | | + O B.. | | = *S. | | o | | | | | | | +-----------------+

たとえば、ある日ローカルホスト上の鍵が勝手に変更されていたとしましょう。

しかし、cat ~/.ssh/id_rsaコマンドを実行したところで、

以前と変更されていたかどうか、判断できるでしょうか?

鍵のテキストファイルは、記号だらけでほとんどの人間にとっては

一目見ただけでは変更されたかどうかが判断できません。

そこで導入されたのが、この「randomart」という仕組みです。

鍵を「人間がみやすいように記号絵図にする」ことによって、

ある日突然鍵の中身が書き換えられたとしても判別しやすくする」

ことを目的としています。

なお、このrandomartをログイン時に毎回表示させるためには、設定変更が必要です。

コマンドラインsshを実行するたびに-o VisualHostKey=yesオプションを付与するか、

~/.ssh/configファイルにVisualHostKey=yesという行を追加してください。

なお、~/.ssh/configファイルは作成されていない場合があります。

その場合は適宜新しく作成してください。作成して保存すると設定は自動で反映されます。

そうすると、毎回sshログインするたびにrandomartが表示されるようになります。

2. (クライアント側→サーバ側)公開鍵をコピー・サーバ側に設置

次に、クライアント側で生成された公開鍵をサーバ側に設置する必要があります。

この手順の流れの定石は、以下のとおりです。

  1. scpコマンドを使いセキュアにファイルをコピー
  2. ~/.ssh/authorized_keysファイルにコピーした公開鍵の内容を追加
  3. ログイン

1. scpコマンドを使いセキュアにファイルをコピー

まず、「クライアント側からサーバ側に公開鍵をコピー」する必要がありますが、

どのようにコピーすればいいでしょうか?メールを送るわけにも行きませんし、

コピーペーストでできるわけでもありません。

ここでは、scpコマンドという、SSHプロトコルを用いたファイルコピーのための

コマンドを使います。

# クライアント側で
# remote-user-name@server-address:~ とは、
# 「remote-user-nameというユーザー名でserver-addressサーバログインし、
# ホームディレクトリ(~)に該当ファイルをコピーする」という意味です。
$ scp ~/.ssh/id_rsa.pub remote-user-name@server-address:~

2. ~/.ssh/authorized_keysファイルにコピーした公開鍵の内容を追加

コピーできたら、次はサーバ側での作業です。

まずはSSHコマンドでログインし、公開鍵を設置していきます。

# 2.1. SSHログイン
$ ssh remote-user-name@server-address

# (以下処理はサーバ側)
# 2.2. 公開鍵がコピーされていることを確認
$ cd ~ && cat id_rsa.pub

# 2.3. 「.sshディレクトリを作成・パーミッションを変更
$ mkdir ~/.ssh
$ chmod 700 .ssh

# 2.4. 「~/.ssh/authorized_keys」を作成・パーミッションを変更
$ touch ~/.ssh/authorized_keys
$ chmod 600 ~/.ssh/authorized_keys

# 2.5. 公開鍵を「~/.ssh/authorized_keys」に追加
# (">>"リダイレクトで、上書きではなくファイル内容を追加します)
$ cat ~/id_rsa.pub >> .ssh/authorized_keys

3. ログイン

最後に、公開鍵認証でログインできることを確認してみましょう。

まずは、サーバ側にログインしている場合は、ログアウトします。



次に、クライアント側からSSH認証でログインしてみます。

# パスワード認証ではなく公開鍵認証でログインできることを確認
$ ssh remote-user-name@server-address

以上がSSH認証のための準備です。

実は、ssh-copy-idという便利なコマンドを使うと、

サーバ側へのauthrorized_keysの作成やパーミッションの設定など

自動で行ってくれ、非常に便利です。

ですが、仕組みを知らない方は、ぜひ上の手順でひとつひとつ作業を確認しながら

SSH認証について理解を深めていきましょう。

おまけ:SSHコマンド関連逆引レシピ

# コマンドの一部を省略している場合があります
# また、SSH周りで作業するときに使えるコマンドも紹介しています

# IPアドレスを確認する
$ ifconfig

# 鍵ファイル(Identification)を指定してリモートログイン
$ ssh -i ~/.ssh/id_rsa.pub remote-user-name@XX.XX.XX.XX

# デバッグする(verboseモードでログを出力する)
$ ssh -v -i ...



2018-09-23

こびと株.comの運営メンバー - こびと株.com 14:59

<title>こびと株.comの運営メンバー - こびと株.com</title>

こびと株.comの運営メンバー

<header style="max-width: 100%;">

<figure style="max-width: 100%; font-size: 0.75em; line-height: 1.5em; font-family: -apple-system-font; color: rgba(0, 0, 0, 0.65098); margin: 1.4em 0px;">

</figure>

</header>

<section style="max-width: 100%;">

こびと株.comは、上場企業経理マンであるーウィードと、彼に巻き込まれた後輩たちによって運営されています。


シーウィード(管理人)

こびと株.comの設立者

一部上場企業の本社で10年間、経理/財務職に就いている会計の専門家

保有資格など

趣味

  • ゲーム
  • 国内・海外旅行(特に、電車旅)
  • ドライブ
  • 資格の勉強
  • 読書

価値観についてご紹介します。

?小さな成功をかき集めて、自分らしい暮らしを叶えたい

社長を目指すとか、億万長者の投資家を目指すとか、そういう計画はありません。4つの財布をバランスよく育てたいと思っています。

?サラリーマンで大成功→無理
?株式投資で大成功→無理
?不動産投資で大成功→無理
?サイト運営で大成功→無理

こういう自分の固定観念に抗えずにきてるんですが、それぞれの分野で目立たずこっそり少額ずつ稼いで、『かき集めてみたらなかなか悪くない』は可能な気がしています。

— こびと株.com (@kobito_kabu)








<time datetime="2017-07-16T13:34:58+0000" pubdate="" style="max-width: 100%;" title="投稿時刻: 2017年7月16日 13:34:58 (UTC)">22:34 - 2017年7月16日</time>

40歳でこの計画。年齢を重ねれば重ねるほど、各分野の金額は増えていきます。いいですね〜!

各分野での収入の育て方は次の記事をご参考に。

?3つの資本を育て続けて、小さな成長スパイラルのなかで暮らしたい

〇〇歳でリタイアしてのんびり暮らしたい!という願望はありません。人的資本を失うからです。持続可能な発展を求めています。荒波にもまれ続ける変化の激しい人生はちょっと遠慮しますw

3つの資本とは、

のことを言います。幸福になるには、この3つの資本をバランスよく育てる必要があります。

有名な作家、橘玲(あきら)氏の「幸福の資本論」を読むと、年収が高いのに幸せになれない、資産家なのに幸せになれない理由が良く分かります。

こびと株.comメンバーは、

  • 収入を分散し(4つの財布を作る)
  • 資本を分散し(3つの資本を育てる)

自分らしい楽しい生活を送りたいと考えています。

?配当金やサイト収入は、すべて生活を豊かにするために使う

株式投資のスタイルは、高配当株の長期ホールドです。株式投資を始めてから数年間、株式を一度も売ったことがありません。毎年毎年、配当金は増え続けています。

毎年5〜10万円ほど配当金が増えていきますから、50歳を過ぎたあたりで配当金だけで年額240万円のキャッシュフローになるでしょう、

2018年7月現在、このサイトは月間12万PV月額収入20万円程度になっています。最終的には、このサイト単体で、年間売上300万円を目指しています。月額25万円です。

これらはすべて趣味に充て、生活を豊かにするために使います。たくさんの楽しい経験をしながら、趣味仲間を増やしていきたいですね!

まとめ:4つの財布&3つの資本を育てながら、自分らしい生活を実現する

こういう価値観で活動しているということです。

収入を4つ分散し、会社だけに依存する典型的なサラリーマンのモデルから脱却します。

  1. 給与
  2. 配当
  3. 不動産
  4. 事業

同時に、3つの資本をバランスよく育てて、強固な人生基盤を築きます。

  1. 人的資本(自分の勤労を金銭に変える力)
  2. 金融資本(株式不動産
  3. 社会資本(家族、友人、同僚、趣味仲間との絆)

私にとって、このサイト(こびと株.com)の役割は、「サイト収入を得ること」と「志を同じくする人達との繋がりを得ること」です。

特に、若い人達との繋がりを作りたいと思っています。なぜなら、超少子高齢化・人口減の日本において、金融リテラシーを高めることはもはや必須だからです。先ほど紹介した橘氏も、このように言っています。

サラリーマン新卒からひとつの会社に定年まで勤めて、退職金年金で悠々自適で暮らすとか、妻が家事と子育てに専念して、夫の年金だけで老後を安心して暮らせるとか、そういう高度成長期ライフスタイルは完全に行き詰まりました。

— 橘 玲 (@ak_tch)








<time datetime="2017-12-29T09:29:41+0000" pubdate="" style="max-width: 100%;" title="投稿時刻: 2017年12月29日 9:29:41 (UTC)">18:29 - 2017年12月29日</time>

こびと株.comメンバーは、4人全員が「30歳で1,000万円の運用資産」を築くことに成功しています。大成功だと自慢できるほどのことではありません。

それでも私たちが持つノウハウは、多くの一般的なサラリーマンにとっては十分役に立つものでしょう。大学生や新卒第二新卒の方で、資産運用に興味のある方のサポートをしていけたら嬉しいなと思っています。

若い人たちの役に立つ情報を発信していけるよう、サイト運営を頑張っていきたいと思います。

どうぞ、こびと株.comをよろしくお願いします!

フルーツ(編集メンバー)

<figure class="auxiliary float left" style="width: 18%; max-width: 100%; display: block; clear: both; font-size: 0.75em; line-height: 1.4em; text-align: start; font-family: -apple-system-font; color: rgba(0, 0, 0, 0.65098); margin: 1.4em 0px; float: none;"><figcaption style="max-width: 100%; width: 100%; -webkit-margin-start: 0px; margin-top: 0.5em; margin-bottom: 0.5em; font-size: 0.75rem; color: rgba(0, 0, 0, 0.8);">フルーツ</figcaption></figure>

シーウィードの職場の後輩3名の総称。不運にも日商簿記1級と豊富な開示実務経験を有してしまったがために、「こびと株」の研究メンバーに加入させられた。

全員で情報・意見交換しながら、インカムゲイン拡大のための長期投資を実践中。3人とも「30歳で1,000万円」の運用資産を達成した堅実派。短期トレードではなく、堅実な家計管理・投資スタイルで資産を着実に増やしている。

なお、こびと株.comの記事を書いてるフルーツは一人(♀)だけ。シーさんの片腕として、女性ならではの視点を生かした記事を執筆しています。

<figure class="auxiliary float left" style="width: 18%; max-width: 100%; display: block; clear: both; font-size: 0.75em; line-height: 1.4em; text-align: start; font-family: -apple-system-font; color: rgba(0, 0, 0, 0.65098); margin: 1.4em 0px; float: none;"><figcaption style="max-width: 100%; width: 100%; -webkit-margin-start: 0px; margin-top: 0.5em; margin-bottom: 0.5em; font-size: 0.75rem; color: rgba(0, 0, 0, 0.8);">フルーツ</figcaption></figure>

</section>


不屈の精神で月20万円の副収入を育てると、月20万円の収入を失う話【つらい】 - こびと株.com 14:55

<title>不屈の精神で月20万円の副収入を育てると、月20万円の収入を失う話【つらい】 - こびと株.com</title>

不屈の精神で月20万円の副収入を育てると、月20万円の収入を失う話【つらい】

<header style="max-width: 100%;">




<figure style="max-width: 100%; font-size: 0.75em; line-height: 1.5em; font-family: -apple-system-font; color: rgba(0, 0, 0, 0.65098); margin: 1.4em 0px;">

</figure>

</header>




<section style="max-width: 100%;">


こんにちは、シーウィード@こびとが見える経理マンです。

40歳までに、給与以外に月20万円の収入を作る!というコンセプトのもと、日夜活動に励んでおります。

  • 配当金 月5万円(税引後)
  • 不動産 月5万円(税金、経費考慮後の手取り)
  • サイト 月10万円

年間で240万円になります。これにプラスして月10万分ぐらい働けば、家族2人なら十分に暮らせるでしょう。子供がいても、妻が月10万円稼げば全然OKです。夢の週2〜3労働だ!

最近では金融資本の蓄積=配当金の伸びが順調なので、40歳時点で月10万円ぐらいの配当に到達しそうな感じです。

サイト収入に関しては、現時点で月15〜20万円ぐらいの収益があるのでもうゴールしてますね。あとはこれをいかに長く安定させてキープするか。

このブログを開設した2016年10月時点と比較すると、2年でずいぶんと計画が進捗したように思います。いたって順調!何事もやってみるものですね。

ところが。

良いことがあれば、悪いこともあるのが世の常です。

順調に育つ副収入を横目に、妻ちゃんがこんなことを言い始めました。

妻「月20万円の副収入ができたら、私はもう働かなくて良くなるね♪」


ちょっと待っていただきたい。Youが働かなくなると、Meはフルタイムで働き続けなきゃいけない可能性があるんですが?

妻「私の月給は手取り20万円ぐらいだからー、月20万円の配当ブログ収益ができればプラマイゼロだよ!」



妻「早く副収入が20万円になるといいなー。ダラダラ過ごしたなー♪」

ダメだ話が通じない…

最近、純正のダメ上司が異動してきたらしく、労働意欲を著しく削がれているようです。

リタイアを夢見始めた妻。こうなると、現実の世界に連れ戻すのは並大抵の努力では不可能です。

あぁ、しっかりと議事録をとっておくべきだった…

  • なぜ私がこのような取り組み(4つの財布計画)を始めたか?
  • 私たちファミリーはどこからきて、どこへゆくのか?

自由へと向けた私の取り組みは、今や「妻を労働から解放するため」の崇高な戦いへと形を変えてしまったようです。

え、これさぁ。月20万円の副収入を育てる=妻の月給20万円がなくなるなら、僕の頑張り意味なくなくなくない?何もしないのが正解じゃないか!

これを「世帯年収保存の法則」と言います。

とりあえず、今晩、ケーキを買って帰って肩を揉みながらネゴシエーションをしようと思います。

負けないよ!

もしブログの更新が止まったら、つまりそういうことです。

それではまたっ!


</section>













2018-09-22

『お金のPDCA』を読んで、速攻で取り組んだことの詳細報告 - toricago 00:37

<title>『お金のPDCA』を読んで、速攻で取り組んだことの詳細報告 - toricago</title>

『お金のPDCA』を読んで、速攻で取り組んだことの詳細報告

『稼ぐ人が実践している お金のPDCA』を読んだ。この本、なんと著者があのハイパーベストセラー本『鬼速PDCA』の冨田和成さんである。『鬼速PDCA』についてはこのブログでも数々の体験記を投稿してきた。今でも『鬼速PDCA』の流儀に則り、毎日簡易な振り返りを行い、土曜日の早朝には1時間予定をブロックして、ディープな振り返りを行っている。発売直後から『鬼速PDCA』の内容を実践し、半年後、1年後の経過もブログで報告してきた。

さらには『鬼速PDCA』で紹介されていた「なるほどシート」をベースにした「なるほど共有会」を立ち上げ、当初のNaruhodo Sheets(Google sheets上)は後にNaruhodo Plus(Google Plus上)に進化を遂げ、さらに現在はNaruhodo Server(Discord Server上)へと形を変えレベルを上げている。Naruhodo Serverのメンバーたちはライフハック好きな方々ばかりで、メンバーから学ぶことが多い毎日を過ごしている。そして私自身も毎日「なるほど」と思うことを2年近く投稿し続けてきた。

ちなみに今までのブログ上での『鬼速PDCA』関連の記事はすべて次の記事にまとめた。

このように私は『鬼速PDCA』にはだいぶお世話になったので、その「お金版」とも言える『お金のPDCA』が出たと知り早速読んでみた。実は5月発売の本で、随分と前に読んでいたのだが、最近になってようやく取り組み始めることが出来た。数ヶ月間放置していたことになり、全然「鬼速」じゃなくて恥ずかしい笑。それは他のKGI/KPI/KDIを回していたということで大目に見てほしい…笑。

ということで、これからブログでも『お金のPDCA』について少しずつ体験記のようなものを投稿していきたいと思っている。まずはアマゾンの紹介文章を引用してみる。

PDCAで最大の課題――「お金」を動かす!

お金について急激に行動やマインドが変わってきています。

クラウドファンディング民泊カーシェアリングスキルシェアなど、お金を生み出す選択肢が広がったことで、お金のことを真剣に考え、行動したことによるリターンの可能性は段違いに大きくなりました。

人生100年時代の中、この変化の波に乗って一気に前進するのも、その波に押し流されてしまうのも、波に乗らずに傍観しているのも、「情報の非対称性」がますます広がる「お金のリテラシー」をどれだけ身につけているかによります。

本書は「そんな方法があるんだ」という発見と、「自分もやってみようかな」と思ってもらえるきっかけを提供するためにまとめたものです。

富裕層資産管理を知り、フィンテック企業のCEOの著者が教える新しいお金の教科書

仮想通貨、シェアエコノミー、評価経済フィンテック。お金をめぐる環境が大きく変わり始めました。経済の流れは、お金とともに、あなたの時間、仕事、人生にも大きな影響を及ぼします。この状況の中、節約・貯金といった従来のやり方だけでは対応できません。しかし、逆に新しい流れを捉えて仕事、時間、人生のプランを立てれば誰よりも早くチャンスがつかめます。理解だけでなく実行方法に焦点を当て、「お金の不安を打ち消し、理想の人生を送る」ための1冊。

内容はこんな感じ。そして今回の私の記事は書評というより、この本を読んでから私が速攻で実施したことの一覧を紹介していきたい。節約チックな話が多いが、これらはこの本の真髄というより準備に過ぎない。次回以降に、本題の個人バランスシート個人版プロフィットロス作りの話をしていきたい。

『お金のPDCA』を読んで、速攻で取り組んだことの一覧

ANAマイレージカード再設定

ANAマイレージカードのパスワードが不明になっていたので、再発行するためにコールセンターに電話をする。2週間もしないうちにパスワードとカードが自宅に届いて手続きを行った。過去半年前までの航空券などを取り出して、マイルを登録していく作業を行った。残念ながら、それよりも前のものは登録することができないので、泣く泣く諦める。もったいない!でも少なくとも半年分は登録できてホッとした。すでに結構マイレージが溜まった。

Amazon Classic Card登録

自分はAmazonで結構買い物をする上に、最近は『食事ハック』(著:勝間和代さん)も実践している関係でAmazon Freshを毎週のように頼んでいる。それによって結構な額をAmazonで利用しているので、Amazonクレジットカードについて調べてみた。私が観たときは、5000ポイントのキャンペーンを行っている「クラシックカード」にした。Amazon Heavy Userに対しては実質年会費はタダのようなものだし、プライム会員ならAmazonでのポイントが2%もつく。Amazonポイントはそのままポイントとして加算され、Amazonギフト券に変換するなどと言った面倒な作業が発生しないので、交換忘れが起きる心配もないので良い。

そのうち、ゴールドカードにグレードアップするのはアリ。後でまた検討したい。

bitFlyerの口座をアップデート

『お金のPDCA』の第5章(お金に働いてもらう稼ぎ力--金融資本)を読んで、資産運用も本格化させたい気持ちが湧いてきた。そこで、分散投資の一貫として、仮想通貨もちゃんと張っておきたいところ。

仮想通貨の代表的サービスbitFlyerの口座を再度稼働させるために、かなり久しぶりにログインしたら、すごい厳しくなっていてびっくり。本人確認書類の提出、色々と追加された同意書への同意、さらには自宅への書類送付による住所証明など、以前使っていたときには必要のなかったものが色々と義務化されていた。

それらの手続きを全部行い、再度利用できるようになった。自分がリスク資産に投入できる額をまずは決めて、さらにリスク資産の内訳として仮想通貨の割合を決めた。その分だけをbitFlyerの指定されていた口座に振り込んで、bitFlyerアプリ仮想通貨に切り替えた。

フィットネスジムを退会

もともと私は外で走っていたが、雨が降っていたら走れないということに嫌気が差し、どんな天候でも運動のスケジュールが狂わないフィットネスジムに切り替えた。フィットネスジムに特化したライフハックも数々開拓してきて、例えばこれらの記事でも紹介した。

もちろん、外で走るのも気持ちが良いので、外で走ったり、ジムで運動したりというハイブリッド型で運用していた時期が長かった。外で走るための記事もたくさん書いてきた。

しかし最近は、夏でも冬でも、晴れでも雨でも、外を走れるウェアや装備を整えることができた。なので、割合としてもジムが少なくなっていたところ。そろそろやめようか、どうしようか、と決断のエネルギーを絞れずにずっと後ろ倒ししていたときに『お金のPDCA』を読み、よし、やめよう、と思って辞めることが出来た。

ジムの月会費はバカにならないので、良い決断をした気分。実はジムで筋トレはしないし、水泳もしないし、サウナも入らない。ランニングマシーンしか利用していなかった自分としては、オーバースペックだった。もちろんジムを否定するつもりはなく、筋トレをする人にとってはジムの環境はマストだと思うし、人それぞれ状況は違うと思う。

ジムを辞めて思うのは、ジムまでの往復の時間、ジムに着いてから受付を済ませて、更衣室に移動し着替えて、フィットネスルームにまた移動したりと、タイムロスが思いのほか多い。一方ランニングの場合は、着替えて家を出たその一歩目からランニング出来るので素晴らしい。テンポが良い。会社から帰宅してパパッと数キロ走り、すぐシャワーを浴び、すぐ夕食をとり、すぐ前倒しシートを通し、『鬼速PDCA』用の簡易振り返りを行う。そのテンポの良さが気持ちよくなり最近はほぼ毎日走っている。ちなみに前倒しシートとは、こういうもの:

読書アプリKindle」読み上げ機能の徹底活用

ジムでは走りながら、もしくはペダルを漕ぎながら本を開いて勉強することが多かったが、外でランニングするときには『お金のPDCA』で紹介されていた神ハック「Kindleの読み上げ機能」を使いはじめている。

これはiPhoneの場合であれば、2本の指で画面の最上から下に向かって滑らせると、開いているページからKindleが本の内容を読み上げてくれるという最強ハックだ。しかもスピードは速めたり緩めたりできるので、私は聞き取れる最速のスピードに設定している。すると一冊の本が1時間ぐらいのランニングで聞き終わるようになるので、インプットできる量がどんどん増えるようになった。本に飽きたらPodcastを倍速で聞いたりしている。

耳がどんどん速い読み上げにも対応できるようになることに対して、興奮するものがある。このまま3倍ぐらいまで鍛えれば1時間の話が20分で聞き終わっちゃうからね。

ちなみに今は2.25倍ぐらいまでは聞き取れるようになっている。Kindleだと今の速度を知る機能がないが、YouTubeにいれているextensionで最大16倍まで早められるのだが、だいたい2.25が今の所限度。次の目標は3倍まで早めること。

この話は他にも書きたいことがあるので、また別の記事として書く予定。

マインドマップアプリ「MindNode」の徹底活用

『お金のPDCA』ではマインドマップツールの話も登場するが、iThoughtsとMindNodeが推奨されていた。私はこのうち、MindNodeのトライアル版を試してみたのだが、そのシンプルなUIや、PCのみならずタブレットスマホでも親指だけでどんどんマップを拡張していけることが気に入って、PC版、モバイル版両方の有料アプリを購入してしまった。今ではMindNodeをPC、タブレットスマホで同期させて、暇な時間に眺めてマインドマップに項目を付け足したりしている。合わせて数千円以上したと記憶しているが、買い切りなのでそれ以上はかからない。なかなかオススメだ。

最近気づいたのが、MindNodeで作ったマップをコピーして、ワードやエディターに貼り付けると、マインドマップのツリー構造を維持した形でコピペされるのだ。この機能には心底驚いたが、かなり便利。例えばブログ記事をセクション毎に枝分かれしていくメモをMindNodeで作成してから、それをエディターにコピーしたらセクション毎にまとまってコピペされるので編集しやすい。

セカンダリー市場「メルカリ」の徹底活用

いつか処分したいと思っていたものをすべてメルカリに出品した。例えば古いスニーカーとか、買い替えて残っていた電子レンジとか、数ヶ月に一回しか利用していないプリンターとか、サイズが合わなくなった5年〜10年前のビジネススーツ、通常なら捨てるしかないビジネス雑誌。「誰がどう考えても絶対に要らないもの」はもちろん捨てるけど、「誰がどう考えても要らないけど、もしかしたら欲しい人がいるかもしれないな」というレベルのものはすべて出品する。するとだいたい売れる。それがメルカリのすごいところ。基本的に「捨てる」という概念が私の中で消えつつある。

メルカリ活用の重要性は『お金のPDCA』でも強調されていて、お金に関する常識がすごい変化するきっかけを与えている現象だと思う。詳細は『お金のPDCA』をご覧頂きたい。もしくは私の以前のブログ記事もぜひ:

今では生活コストをどこまで下げられるか、というのをメルカリを通して実験している段階。質素な生活をするという意味ではなくて、ものを買っても自分に合わなければ定価から5%オフとかですぐに出品すればよいし、数年使い込んでも、ものによっては30%〜50%オフで売却できる。ものを買うときもまずはメルカリをチェックする癖が付いた。『お金のPDCA』にもランボルギーニロレックスの話が出ているし、むしろ生活が豊かになるんじゃないかな?と自分は思っている。

私は車や時計には関心が薄いが、ライフハッカーとして高価なガジェットを買うことが多い。それらの値段は積もれば馬鹿にならない。しかし自分に合わない場合も即売却できるので、ダメージを抑えることが出来るので良い。

そもそも、お金を心配して何かに挑戦できない状態を抜け出すためにこそ『お金のPDCA』を回しているわけだ。様々なキャリアパスが存在する中で、良い決断をしていく上で 、

  • 「給料が●●%下がっても何の問題もないね」
  • 「今の生活水準は確実に維持できるね」

と自分のBSやPLを見ながら言える環境を作り出せれば素敵だなぁと思うし、そのためにメルカリを使い込むのは悪くない。私はシェアリングエコノミーリユースに対する考え方がここ半年ぐらいで大きく変化したのは良かったなぁと思っている。(自分のBSやPLを作る話はこれから取り組むので、次回以降詳細を報告していく予定。)

公共料金をすべてクレジットカード払いに変更

電気、ガス、水道代をすべてクレジットカードでの支払いに変更して、コンビニに行って支払う手間を省いたと同時に、登録したクレジットカードのポイントが少しでも多く貯まるようにした。これも『お金のPDCA』で紹介されていた似たような話にインスパイアされている。

有料アプリの解除

TODOIST PREMIUMを解除した。自動更新だったので…。そのかわりTODOISTのフリープランでやっていくことにして、『鬼速PDCA』流のアイデアメモやアイスボックスとの連携などはTODOISTで引き続き行うことにした。日々のTODO的なものはWunderlistで管理するように変更した。ちなみに、TODOISTの使い方は『鬼速PDCA』にも少し出ているので詳しく知りたい人は参照されたい。

家計簿アプリ「マネーフォーワード」に情報集約

すべてのクレカ証券銀行口座などをマネーフォワードに登録した。すでにほとんど登録されていたが、抜けがないように気をつけた。ここにすべての情報を集約させて、今後は自分のバランスシートやプロフィットロスを作っていきたい。むしろ、自分のバランスシートやプロフィットロスを作ることで示唆を得るというのが『お金のPDCA』のメインメッセージの一つなので、これは次にやる予定。

クラウドコンピューティング利用契約を解約する

マネーフォワードの過去数ヶ月分の支払いを1件1件振り返っていった。すると、昔試したクラウドコンピューティング環境のアカウントがずっと稼働していた状態だったことに気づき、大変ショックを受けた。確認すると毎月1000円以上課金されていて、ショックだけどとんでもない額じゃなくてよかった。不幸中の幸い。気づいてよかった。

読書方法の再考

読書を紙の本にするのかKindleにするのかは非常に悩ましい。Kindleであれば『お金のPDCA』にも紹介されていた神ハック「音声読み上げ」を使うことが出来るし、効率的なインプットに役に立つ。ランニング中にも聞ける。しかしメルカリなどのセカンダリーマーケットで売却することが不可能である。紙にするとメルカリでも売却できるし、そもそも買うときにもメルカリで買うというオプションがある。リユース市場から調達しリユース市場に再度売却する。ベストセラーの本であれば定価の5%オフぐらいで売れるので、紙の本は魅力的になる。(ただし郵送料や手数料も取られるので、取り分はもう少し少ない。)

英語の本であれば迷わずKindle。なぜなら、メルカリなどでは英語の本を売る人も買う人もほとんどいないからだ。日本語の本の場合は毎回少し悩んだ上で決めている。

クレジットカードのポイントをギフト券に変換

クレカのポイントを全部調べて、すべてAmazonギフト券に変換して、Amazon口座に登録した。これは有効期限があるものなので、非常に面倒。将来的にはクレカ数をへらす必要があると感じた。普段使い用とAmazon用の2種類だけでいいんじゃないかな。色々なカードのポイントを定期的に交換したり、年会費などがかかっていないか確認したり、不正な購入がないかも目を光らせておくのは大変だ。2枚あれば片方が上限に達しても何とかなるし、海外出張や海外旅行も問題なさそうだ。

携帯料金プランの見直し

これはまだ出来ていないけど今後やりたいこと。携帯料金の見直しはやらなきゃと思いつつ全然できていない。結構な額を取られていて、ずっと頭の片隅にあるのでストレスを感じている。これも近いうちに実践してまた報告したいと思う。

シェアリングエコノミーの徹底的活用

これはまだ出来ていないけど今後やりたいこと。メルカリを使い込んで色々と価値観がアップデートされた気がするので、『お金のPDCA』に出てくる他のシェアリングサービスもガンガン使っていきたい。ちなみに本の中には41個の多分野にわたるシェアリングサービスが紹介される表があり、大変便利だ。この中から試していきたい。

個人BS/PLの作成

これはまだ出来ていないけど今後やりたいこと。そもそも個人BS/PLを作るための情報の整理、準備編が今回の記事だった。これからBS/PLづくりに取り組んでいくので、作成・分析が終われば、また記事で報告していきたい。

東京のIT企業7社でインターンシップをして感じたことをメタ的にまとめて見た。 - くうと徒然なるままに 00:05

<title>東京のIT企業7社でインターンシップをして感じたことをメタ的にまとめて見た。 - くうと徒然なるままに</title>

東京のIT企業7社でインターンシップをして感じたことをメタ的にまとめて見た。

今までの人生の中で7社ぐらいの会社にインターンシップしてました。(2017に1社2018に6社)

せっかくなので感じたことをまとめて見ました。なお、会社名は基本的に出さない方針です。

ほぼ全ての会社に当てはまってたもの

大学院卒の人がITエンジニアでは多い

肌感ですが、大学院卒の人が多いと感じました。

特に、若い人は結構な割合で大学院卒が多かったと思います。

また、インターンシップに参加してた人も半数〜過半数大学院生だった気がします。

(湯けむりハッカソンでは自分以外の人全員が大学院生だったし....

会社で泊まる人がほとんどいなかった

「なれるSE!」 を読んだことがあるので東京のIT企業ではあんな感じなのかなーとかずっと思ってました。

しかし、現実はかなりホワイトっぽさを感じました。

なれるSE は一度見とくと良いかも。




Excel仕様書はほとんどなかった

事業会社ばかり見てたので Japanese traditional company とは事情が違うとは思いますが、基本的にExcelを有効活用している会社はあまりなかったです。

それよりも、Slack や コンフル、kibela、zepplin などのツールを複数組み合わせて生産性を高めている会社が多かったです。

個人的にはコンフル好き(直球

PC は Mac or 高性能WIndows

イケイケな企業がよく使っているMac、もちろん新しめな高性能モデルでした。

Windows を使った場合でも、Intel Corei7 を搭載してるマシンだったりして快適な開発ができそうな雰囲気でした。

結婚してる人が多かった

IT エンジニアは結婚できないとかTwitterでよく言われてます。

けど、結婚してる人が意外に多かった!!

Git/Github が導入されてた。CI が導入されてた

Git/Github が導入されてるのはほとんどかなーとか思ってましたが、はてブの反応てきにそうではないらしいので一応、

また、Github と連携しCI が動いてるのがほとんどでした。

CI で lint も動いている会社がいるのが可愛かった(結果通知がSlack でかわいいキャラクターが教えてくれるので!

半数の会社に当てはまってたもの

ルフレックス

ルフレックスで生産性高めに働こうとしてる会社が多いと感じました。

現在はなってなくてもなんとか導入しようとチャレンジしてたり事業部ごとに導入してたりしなかったり。

リモートワーク

できる会社とできない会社が半数ぐらいでした。

個人的には、生産性が一番出る働き方をできればいいかなーとか思ってるので必須ではないと思ってます。

一部の会社に特有なもの

分離キーボードおじさん

布教されました。

結局慣れることはできず...

COMP おじさん

COMP グミをひたすら配ってるイケメンなおじさん

食事しなくても大丈夫になるので良いものですよ🌟

まとめ

自分の気持ちを整理するためにとりあえずまとめて見ました。

読者によりそれぞれ感想はあると思います。そんな人はこの記事を引用してその人なりの想いを書いて欲しいと思います✨

iPhoneからSSHコマンド実行・Webhook連携もできる公式アプリショートカット」を活用する - yuu26's memo 22:57

<title>iPhoneからSSHコマンド実行・Webhook連携もできる公式アプリショートカット」を活用する - yuu26's memo</title>

iPhoneからSSHコマンド実行・Webhook連携もできる公式アプリショートカット」を活用する

概要

iPhoneSSH コマンドを実行したり、Webhook 連携を組み立てることが可能となりました。Apple 公式アプリの「ショートカット」を使って実現できます。

ショートカットアプリの概要と、簡単な活用事例をまとめました。

iPhone から SSHcurl が実行できる

ショートカットアプリでは、多くのアクションが用意されています。その中には「SSH」や「URL 取得」などが含まれており、かなり遊べるアプリになりそうです。

URL 取得は GET に限らず POSTPUT も可能で、簡単なリクエストであれば iPhone からサクッと実行できます。簡易 curl のように使えます。

SSH では複数のコマンドを一度に実行できるほか、他アクションとの連携も可能です。

f:id:yuu2634:20180920222607p:plain

iOS 12 で Apple 公式アプリショートカット」を使用

これらの操作には、iOS 12 以降でサポートされている Apple 提供の無料アプリショートカット」を使用します。

ショートカットアプリで実行できるアクションは多数ありますが、特に面白そうなものをピックアップしてみました。

  • 指定した URL にリクエストを送信する(POST も可)
  • SSH 経由でコマンドを実行する
  • iPhoneデバイス状態を変更する


f:id:yuu2634:20180920215904p:plain

プログラミングのように、ユーザ入力を受け付けたり、変数操作やループ処理も実行できます。(小さい画面でポチポチ組むのは辛いかもですが)

f:id:yuu2634:20180920215906p:plain

これらを組み合わせることで、幅広いアクションが可能となります。

iPhone から SSH コマンドを実行する

App Store から「ショートカットアプリインストールしておきます。

アプリを起動後、ショートカットを作成 をタップ。

f:id:yuu2634:20180922110550p:plain

アクションの検索欄が出てくるので ssh を検索して選択

f:id:yuu2634:20180920224702j:plain

接続情報とコマンドを入力し、上部中央にある実行ボタンで開始。

f:id:yuu2634:20180920225219j:plain

結果が出力されました。アクションを後ろに繋げると、この文字列がパイプのように渡されていきます。

右上の変なボタンから、保存する際の名称やアイコンが設定可能です。










ホーム画面やウィジェットからワンタップ実行

作成した処理は、ホーム画面やウィジェットに追加できます。

アイコン色やロゴも自由に設定可能です。

f:id:yuu2634:20180920224157p:plain

特にウィジェットは便利で、アプリを立ち上げずにサクッと実行できます。家電操作系のコマンドと特に相性が良いでしょう。

iPhoneREST API を叩いて JSONパースする

せっかくなので、一つ例を作ってみました。

以下の URL にリクエストを投げ、スプラトゥーン2の現在のステージ情報を JSON で取得、JSONパースしてステージ情報だけを抜き出してみます。


今回の要件を実現するためには、5種類のコンポーネントを用います。


f:id:yuu2634:20180920221526p:plain

今回取得したいデータは、JSON 内の .result.maps[] となります。


f:id:yuu2634:20180920222123p:plain

テキストのみ抽出できました。取得結果が2件あるため、横フリックで確認できます。

仕上げとして、通知メッセージに出力します。


f:id:yuu2634:20180922010359p:plain

これで完成です。(作業中にステージが変わってしまいましたが)

ウィジェットから呼び出すと、ワンタップでステージ情報を確認できます。

f:id:yuu2634:20180922010751p:plain

なお、ここで使用した REST API の詳細については、イカの記事に書いてあります。

blog.yuu26.com

ちなみに User-Agent は以下の値でした。URLエンコードで「ショートカット」ですね。

%E3%82%B7%E3%83%A7%E3%83%BC%E3%83%88%E3%82%AB%E3%83%83%E3%83%88/700 CFNetwork/974.2.1 Darwin/18.0.0


ギャラリーで公開されているショートカットを使う

自分で作成するだけでなく、公開されているショートカットも利用できます。

「指定した URLiCloudダウンロード」というサンプルも。

f:id:yuu2634:20180922105544p:plain

作成したショートカットを共有する

ギャラリーへの投稿機能はありませんが、作成したショートカットは別のユーザに共有できます。ただのリンクなので SNS でシェアすることも容易です。

f:id:yuu2634:20180922110830j:plain

参考として、ナワバリバトルのリンクを張っておきます。

https://www.icloud.com/shortcuts/0e4cc2619d3740509faed8d0826a3a40

まとめ

iPhone で利用できる公式アプリショートカット」を紹介しました。

利用できるアクションが豊富なため、外部のシステムや API と連携させて遊べる面白いアプリです。

iOS 12 を利用している方は、ぜひお試しください。

blog.yuu26.com

2018-09-20

静的サイトを公開するならどこがいいの? #技術書典 - フロントエンドの地獄 13:00

<title>静的サイトを公開するならどこがいいの? #技術書典 - フロントエンドの地獄</title>

静的サイトを公開するならどこがいいの? #技術書

SPAなどの静的サイト(PHPRubyなどのサーバープログラムを走らせない環境でのWebサイト)のを公開するにあたって、運用・配信ホスティング)するならどこがいいかと聞かれたのですが、そのときの回答を技術書典の宣伝も兼ねてブログにしたためます。

今回は次の4つで比較しています。

  • GitHub Pages
  • Firebase Hosting
  • GitLab Pages
  • Netlify


上記4つはどれも独自ドメインの設定は無料で行うことが出来ます。

※比較的初心者に向けて書いている前提です。そのためAWS S3やレンタルサーバーアカウントがなければ設定も面倒ですし今回は除外しています。

少し機能について説明が必要な部分があるので、先に説明を書きます。

Rewrite設定について

SPAで静的サイトを公開する際にありがちなミスなのですが、URLを変更してサブディレクトに進んでからリロードすると404ページになってしまうというものです。

これは公開サイトでページの404のRewrite設定が出来ていない場合に起こってしまう事象です。

「ファイルの読み込み時に404だったら index.html を返す設定」をすることで、リロードしても継続してサイト閲覧することが可能になります。(その場合はJavaScriptで404ページかどうかを判定します。)

設定が出来ない環境でSPAのルーティングを利用する場合はハッシュルーターにする必要があります。

ビルド機能について

プロジェクトによってはWebpackなどを利用して、html,css,jsファイルをコンパイルトランスパイル)してから公開すると思います。

そのときにビルド機能がついている環境の場合は、「手元でビルドしたものをgitで管理したり、ビルドしてからdeployする」等の手間が省けます。

テストを書いていたらテストが通るかどうかなどもそこでチェックして、デプロイするかどうかを選択できたりもします。

各サービスの機能を紹介

GitHub Pages

  • とにかくタダで使えます!
  • 使えますが、下記の記事のような制限があります


GitHub Pagesでホストするサイトのアクセス上限は月10万リクエストが目安

  • 設定した特定のブランチが自動で公開されるので管理が楽。
  • ×: SPA用のRewrite設定不可
  • ×: ビルド機能無し


Firebase Hosting

  • △: たくさんアクセスがあるとデータ容量に応じて課金が必要になります


(無料枠で利用していて制限まで行ったら、通知が来るのみで勝手に課金されるようなことはありません。)

  • SPA用のRewrite設定可能
  • 特定のパスをFirebase Functionsに繋ぐことができる
  • ×: ビルド機能無し


GitLab Pages

  • とにかくタダで使える
  • SPA用のRewrite設定可能
  • 特定のブランチが自動公開できて管理が楽
  • ビルド機能アリ


Netlify

  • とにかくタダで使える
  • SPA用のRewrite設定可能
  • GitHubやGitLabと連携して、静的サイトを自動で公開可能
  • ビルド機能アリ
  • 特定のパスにAWS lambda(Netlify Functions)接続可能


まとめ

すでにGitHub、GitLabでソースを管理しているとして、ライブラリリファレンスなどのちょっとしたサイトならそれぞれのPages機能を使うと手軽です。

Firebaseを利用していて、FunctionsとパスをつなぎたいならFirebase Hostingを利用しましょう。しかしビルド機能がないので必要な場合はCircle CIなどと併用が必要です。

他、Firebase Functionsとつなぎたい場合を除いて便利な機能が揃っているNetlifyをおすすめしています。Netlifyには他にもたくさんの便利な機能が備わっています。

Netlifyの上記以外便利機能紹介

  • ブランチ毎に自動でサイトを公開できる(プルリクを確認するときなど便利)
  • Webhookでビルドしたり、ビルドしてデプロイしたらSlackに通知する(GitLabも可能)
  • ブランチごとのA/Bテスト用に出し分けができる
  • サーバーサイドレンダリングしないSPAだけど、コンテンツに応じてOGP画像などのmeta情報を出し分けられる(Prerendering機能)
  • 静的サイトであるあるな「フォームだけ設置したい」場合もNetlify Formが利用できる
  • ブログなどを作りたい場合にコンテンツを管理できるNetlify CMSもあります


他にもチーム開発で必要な機能や、BASIC認証の設定(有料)など様々な静的サイト公開に便利な機能が備わっています!

ということで宣伝

そんなNetlifyの様々な機能を1から10までほぼ全て実例を使って解説する本を今度の10月8日に開催される技術書典で販売しますので、いらっしゃる方はログインして下記のページをチェックしてぜひぜひ買いに来てください!!!

techbookfest.org

以上ですが、本買わなくともNetlifyはめっちゃ便利なので一度使ってみて下さい!

2018-09-19

React製のSPAのパフォーマンスチューニング実例 | リクルートテクノロジーズ メンバーズブログ 18:56

<title>React製のSPAのパフォーマンスチューニング実例 | リクルートテクノロジーズ メンバーズブログ</title>

React製のSPAのパフォーマンスチューニング実例

こんにちは.エンジニアリングマネージャーの五味です.

今回から 11 月末まで,18入社新人のうち9名によるブログリレーを開催します.

配属前研修 ) を終えた彼らは、それぞれのスペシャリティが最も活かせるであろうグループに配属されました.

当社の若手エンジニアがどのような仕事に取り組み,何を感じ,何をしているのか.本連載では,その一端を紹介していきたいと思います.

SPA 開発,セキュリティ診断,プロダクト開発におけるプロセス運用・機能改善事例などを予定していますので,どうぞ楽しみにしていてください.

初回はフロントエンドエンジニア 辻 健人 からのエントリーです.

はじめに

はじめまして!リクルートテクノロジーズに4月に新卒入社した 辻 健人です!GitHubではmaxmellonで活動しています.

今回は,私が担当しているAirシフトというシフト管理サービスで実施した内容を紹介します.

本記事では,Reactにおける再レンダリングメカニズムを基本的な部分から扱い, SPAにおける再レンダリング最適化での着眼点や改善方法を紹介します.

Airシフトとは

Airシフトは,シフト表の作成はもちろん,スタッフとのやりとりや細かな調整業務もラクになるシフト管理サービスです.

直感的に操作できるシンプルな画面で,簡単にシフト作成が行えます.シフト表と一体となったチャットを使ってスタッフとやりとりができるので,シフトの作成はもちろん,急な調整や連絡ができます.

技術スタックとしては,React/Redux,チャット機能にWebSocketSSRやユーザ認証,ファイルダウンロードにBFFアーキテクチャを採用しています.

背景

Airシフトのユーザを訪問する機会があり,ヒアリングを行った結果,Airシフトの動作が重いという声があがりました. シフト表の表示期間を切り替えると,次の画面が表示されるまでに数秒かかっているようでした. ユーザの利用環境は必ずしもハイスペックなPCというわけではないため,より多くの環境で快適に利用してもらえるよう,パフォーマンス改善を実施することにしました.

それにあたって調査した技術や,実際にプロダクトに導入した技術を紹介します.

課題

今回,Reactのパフォーマンスについて触れるのは,Airシフトにおいてパフォーマンスの課題があったからです. どのような課題かというと,たくさん使ってくれているユーザーほど重くなり,結果として遷移に数十秒かかっているという課題がありました. 特に,今回ヒアリングに行った店舗では,マシンリソースが潤沢ではない環境で操作後に待つ時間非常にが長くなってしまっていました.

実際にどれぐらい遅いのかを,低スペックなPCをエミュレートして計測してみました.

  • 計測環境

MacBook Pro (13-inch, 2017)

項目 詳細
OS macOS High Sierra
CPU 3.1GHz Intel Core i5
メモリ 16GB 2133 MHz LPDDR3
グラフィクス Intel Iris Plus Graphics 650 1536MB
ブラウザ Google Chrome 68.0.3440 (64bit)
追加条件 CPU x4 Slow Down (スペックの低いPCで遅い問題を再現するため)
データ数 15人 2グループ 150シフト/月 (現実的なデータ数)

今回,ヒアリングでスペックの低いPCで著しくこの問題が顕著に現れたので,その環境を再現するために, Google Developer Tools の機能で,CPUの性能を4倍低速にします.

厳密な再現にはなりませんが,低スペック時にどう動いているかを気軽に再現できるので,今回はこの機能を使いました.

計測結果

  • 計測対象の操作

週から月へ変更するという操作

  • APIリクエスト/レスポンス時間

APIも900msecとそれなりに時間がかかっていますが,それ以上にScripting (JavaScript を実行している時間) に時間がかかってしまっていることがわかります.その時間合計するとなんと 15secにもなります.

これを解決するにあたって使った手法解決策を紹介します.

仕組みの理解

マウントと再レンダリング

まず,調査や改善を行う前に,React とはどういう仕組みで動いているかを理解することが重要です. なので,Reactのライフサイクルレンダリング周辺の処理について着目します.

ReactにおけるComponent が レンダリング する場面は,2つあります. それぞれ,マウントと再レンダリングです.

違いとしては,マウントでは,フルにDOMを生成し,親要素にマウントするのに対して, 再レンダリングでは差分を計測し,再レンダリングの必要があるものに対して,最小限の更新を行います.

Tips:

マウントは,公式ドキュメントでは Mounting や Mount と表記されています

レンダリングのことは Updating や Update と表記されています

マウント時のライフサイクル

マウント時には,Component に実装された次の関数が順に実行されます.

レンダリング時のライフサイクル

レンダリング時には,Component に実装された次の関数が順に実行されます.

ここで,重要になるのが, shouldComponentUpdate です.

shouldComponentUpdate 関数は,prevProps, prevState を受け取り,現在の props, state を比較して更新する必要があるかどうかを判定し,その結果をbooleanで返す関数です. 更新の必要がありとした場合は, true を返します. デフォルトでは,常に true  です. つまり,propsのインスタンス,stateのインスタンスが変化したとき,その中身の値が全く同じでも再レンダリングされてしまいます.

レンダリングチューニングする際には,shouldComponentUpdate に着目する必要があります.

React における List と key

リストにおいては,気をつけておくことがライフサイクルに加えてもう一つあります. それはkey です. keyは,繰り返しの要素において同じ要素かどうかを判定し,要素を増減させるための識別子です.

適切なkeyとそうでないkeyで何が変わるかを具体的に見ていきましょう.

次のようなアイテムコンポーネントをリストで表示するとします


1

2

3

4

5

6

7

8

9

10

type ItemType = {

  id: string,

  content: string,

}

function Item({ item }: { item: ItemType }) {

  return (

    <li>{item.content}</li>

  )

}


次のように2つのkeyの付け方で実装したとします

  • 悪いkeyの付け方


1

2

3

4

5

6

7

8

9

10

function List({ items }: { items: Array<ItemType> }) {

  return (

    <div>

      <h1>不適切なkey</h1>

      <ul>

        {items.map((item) => <Item key={Math.random() + ''} item={item} />)}

      </ul>

    </div>

  )

}


  • 良いkeyの付け方


1

2

3

4

5

6

7

8

9

10

function List({ items }: { items: Array<ItemType> }) {

  return (

    <div style={{ display: 'inline-block', width: '25vw' }}>

      <h1>適切なkey</h1>

      <ul>

        {items.map((item) => <Item key={item.id} item={item} />)}

      </ul>

    </div>

  )

}


これらをレンダリングすると次のようになります.(propsの変化がわかりやすいように1秒ごとにitemsを追加します)

緑色に光っている箇所が新しいDOMが生成されている箇所になります.データとkeyが対応していない場合,常にマウントが発生しています. 加えて,再レンダリングではなく,マウントになってしまうので,shouldComponentUpdateによる制御もできません. 非常にコストが高くなってしまいます.

一般的に,APIDBの内容をjsonで返したものを描画するとき,そのデータの主キーや代用キーをReact の key にすると良いでしょう.

keyを指定しなかったときどうなるか

keyが存在するかどうか,あるいはuniqueであるかどうかのvalidationは開発環境でのみReact側がしてくれます.

そして,keyが存在しなかったときは,配列のindexがkeyとして自動的に使われます. しかし,indexをkeyとする場合でも,map((item, key) => <Component key={key} />) のように,きちんと明記しましょう.

Listにおける再レンダリング

データによって一意に定まるkeyを設定することで,マウントを制御できることをここまでで見てきました. ただ,Listでは更に罠があります.特にデータ数が多いものや更新の頻度が高いものは注意が必要です.

少し前に触れましたが,shouldComponentUpdateは常にtrueを返す ということを意識しなければなりません. 特にshouldComponentUpdateを気をつけずにリストを描画すると次のようになります.

keyによって,マウント/再レンダリングを制御できることがわかりました.不要なマウントを再レンダリングにし,ある程度改善ができたと思います. ただ,ここで気をつけなければいけないのが,shouldComponentUpdateを実装していない場合,defaultで常にtrueを返す という点です. デモでみていきましょう.

水色の四角は,再レンダリングが発生している箇所です. shouldComponentUpdateがtrueを返しているので,無駄に再レンダリングしてしまっていることがわかると思います.

実際のコードを見てどう対策するのかを見てみましょう. リストの実装は先程と基本的に同じです.


1

2

3

4

5

6

7

function List({ items }: { items: Array<ItemType> }) {

  return (

    <ul>

      {items.map((item) => <Item key={Math.random() + ''} item={item} />)}

    </ul>

  )

}



1

2

3

4

5

6

7

8

9

10

11

import { Component } from 'react'

class Item extends Component<ItemType> {

  render() {

    const { item } = this.props

    return (

      <li>{item.content}</li>

    )

  }

}


このような,ListとItemの関係において,差分レンダリングを制御するにあたり,Itemに着目します. 汎用的な,shouldComponentUpdate の実装として,PureComponent というものがあります.

PureComponentが具体的にしていることは,propsに対してshallowCompareして差分を見ています.このとき注意なのがshallow なので, 任意の props[key] が object だった場合そのObjectの中身の値が同じかどうかではなく, 同じインスタンスであるかどうか (通常のstrict equalと同じ挙動)を見ます.

なので,たとえObjectが全て同じ値でも,Rest parameters や Object.assign などで コピーしていると異なるインスタンス扱いになってしまうということに気をつける必要があります.

ちなみに,shallowCompare の具体的な実装は,fbjs/shallowEqual です.


1

2

3

4

5

6

7

8

9

10

11

import { PureComponent } from 'react'

class PureItem extends PureComponent<ItemType> {

  render() {

    const { item } = this.props

    return (

      <li>{item.content}</li>

    )

  }

}


これを実際にレンダリングするとどうなるか見てみましょう.

実際に差分レンダリングがされている箇所を見てみると,stateが書き換わっているListのみ再レンダリングされ, 各Itemは再レンダリングされていないことがわかります.

ここでは PureComponent を用いた例を紹介しましたが, Stateles Functional Component を用いている場合はrecompose/pure というものがあります. もし,Functional Component を軸に開発を進めるのであれば,PureComponent を継承する代わりに recompose/pure を利用することで同じ効果が得られます.


1

2

3

4

5

6

7

8

9

import { pure } from 'recompose'

function Item({ item }: { item: ItemType }) {

  return (

    <li>{item}</li>

  )

}

const PureItem = pure(Item)


ボトルネックを調査・計測

chrome developer tools

Reactのversion 16から,react-addons-perf のサポートがなくなりました. その代わりに,Chrome の devtools を使って計測する方法を紹介していきます.

パフォーマンストレースを閲覧する

Chrome の機能を用いて React のアプリケーションのパフォーマンストレースを見られます. React内部でUserTiming API を利用して,それぞれの処理時間を見ることができます. (Reactの内部処理時間は開発環境のみ閲覧可能)

赤枠のボタン押下することで,任意の操作のパフォーマンスツリーを見ることができます. 青枠のボタンは,フルリロードからDOMContentLoaded をハンドルして実行されたscriptingが終わるまでのパフォーマンスツリーを見ることができます.

2018-09-16

Googleストリートビューで3年かけて米国を“横断”、仮想の長旅から見えてきたこと|WIRED.jp 20:24

<title>Googleストリートビューで3年かけて米国を“横断”、仮想の長旅から見えてきたこと|WIRED.jp</title>

Googleストリートビューで3年かけて米国を“横断”、仮想の長旅から見えてきたこと

<header style="max-width: 100%;">

アフリカに住む米国人が「Google ストリートビュー」を使って、米国東海岸から西海岸まで3年もかけて“横断”した。裏路地に入り込み、ときには迷いながらの長旅から見えてきたのは、報道ソーシャルメディアでは得られない本当にリアルな米国の姿だった。いったいどんな「旅」だったのか。

TEXT BY LAURA MALLONEE

TRANSLATION BY MAYUMI HIRAI/GALILEO

WIRED(US)

</header>


ヴィンテージ・カーが緑のなかを走り抜ける。ヴァーモント州ピッツフィールドにて。IMAGE CAPTURE COURTESY OF ©2018 GOOGLE

トランプ大統領ツイートからキム・カーダシアンInstagramまで、インターネット米国について多くのことを教えてくれる。ただし、この国を本当に理解するには、ソーシャルメディアからログオフして、道路を走るほうがいい。しかも、それには自宅のソファーから離れる必要はない。

マシュー・マスプラットは、全米各地を巡る3,700マイル(約6,000km)の旅をした。だが、そのすべては「Googleストリートビュー」を使ったものである。

しかもマスプラットは、ルワンダキガリに住んでいる。それでいて、米国最東端であるメイン州ウエスト・コディ・ヘッドからワシントン州オゼットまで、16州を通って米国を東から西へ横断する放浪の旅を始めたのだ。

「これは実験であり、演習でした」とマスプラットは語る。「デジタルツールを長期にわたって使うことによって、米国について、そして米国内で何を見つけることができるかを試したのです」

スプラットは、それを実行した初めての人物かもしれない。もちろん、クリックの速さを競って、サンフランシスコからニューヨークまでを90時間で走り抜けた若者たちもいる。しかし、本物の「道路の旅」とはレースではない。実のところ、その対極にあるものだ。

ゆっくりと裏街道をゆく旅路

速度を落として、裏通りをゆっくり進む。たぶん、少し道に迷うこともある。「リズミカルなペースでクリックして道を進みながら、ヴァーチャルな世界に没頭していました」とマスプラットは語る。「ひとつの場所が次の場所に変わっていき、すべての風景がつながっていくのを感じることができました。まるで本物の旅のように」

米国出身のマスプラットがこのアイデアを思い付いたのは、キガリで開発コンサルタントとして働いていた2015年2月のことだった。ホームシックになったマスプラットは、Googleストリートビューを開いた。

スプラットは以前、ジャック・ケルアックの小説『オン・ザ・ロード』を読んだことがあった。さらに、『ナショナル・ジオグラフィック』誌の探検家であるマイケル・フェイが1999年に中央アフリカで行なった、「メガ・トランセクト調査」にも興味をそそられていた。これはコンゴ川流域を通る2,000マイル(約3,200km)の直線を徒歩で進み、地域の野生動植物を調査した旅だ。同じようなことをオンラインでやってみたらどうだろうか?

Googleマップのルート検索によると、米国東海岸から西海岸までの道路をクルマでたどる旅は、ノンストップであれば2日強で完了する。しかし、マスプラットの旅は3年かかった。平均時速20〜30マイル(約32〜48km)で移動したことになる。

快適な自宅のオフィスにいる状態で、すべての道をゆっくりとたどった。例外は、ワイオミング州の岩山「デヴィルスタワー」の近くを通った数分間で、このときは時速150マイル(約240km)まで加速した。

理由のひとつは、契約していたルワンダインターネットプランの制約だ。通信量が1日に1GBを超えると、普段でもどうにか我慢している1.5MB/秒の速度が、ゼロ近くまで急激に下がってしまうのだ。

一方でマスプラットは、主要なハイウェイを避けることによって、わざわざ旅を難しいものにしていた。道路がストリートビューの対象になっているかどうかは事前に確認しているが、やむなく引き返すこともある。地図上を飛び越えることを自ら禁じているからだ。

スプラットは頻繁に停まっては、自分の周囲にあるものに関する情報をWikipediaで検索したり、スクリーンショットのかたちでスナップ写真を撮影したりした。

メイン州にあったトウモロコシを宣伝する看板や、ヴァーモント州の緑の山々を走り抜けるヴィンテージ・カーなど、地元の特色を反映する風景を撮影した(写真家のジャッキ・ケニー、ジョン・ラフマン、マイケル・ウルフなども、同じ目的でGoogleストリートビューを利用している)。マスプラットはこれらの画像を、道中で感じたさまざまな想いとともに、「Medium」に定期的に投稿した

荒廃した街が続くという現実

スプラットの旅は2018年8月で終了した。彼はこの旅によって、故郷であるボストンとは大きく異なる米国の各地に対して目を向けるようになったという。それらは、自分がこれまで住んだことのあるすべての場所とも違う世界だ。

滅びつつある中西部の町についてはもちろん聞いたことがあり、数カ所を訪れてきた。しかし不思議なことに、何時間も費やして、ひとつの荒廃した町から別の荒廃した町へとクリックを続けていると、そのことが痛切に感じられたという。

ストリートビューの地平線に見える隆起が、さらに別の荒廃した町になることが絶対確実だとわかっているのは、とてもむごいことです」とマスプラットは言う。

スプラットの試みは、ソーシャルメディアやオンラインニュースに特有の、絶え間のない冗談やおざなりな反応とは違う新鮮なやリ方で、インターネットを使う方法を表している。もっともっとスローダウンすれば、有意義な出会いがあることを示しているのだ。

「外国に住んでいるときに、これほど米国の姿を見せてくれるものはほかにありません」とマスプラットは述べる。「CNNでもなく、『ニューヨーク・タイムズ』紙でもなく、Foxでも、Facebookでも、Twitterでもないのです」

<section style="max-width: 100%;">

SHARE

</section>

Javascript / Node.js で仕事自動化」記事まとめ - ほんじゃら堂 20:22

<title>「 Javascript / Node.js で仕事自動化」記事まとめ - ほんじゃら堂</title>

Javascript / Node.js で仕事自動化」記事まとめ

<header data-brand="hatenablog" style="max-width: 100%;">

ほんじゃら堂

めんどくさい仕事をラクにする作業自動化レシピ集


</header>

<header style="max-width: 100%;">






</header>

piro_suke (id:piro_suke)

<time data-relative="" datetime="2018-09-15T06:29:00Z" pubdate="" style="max-width: 100%;" title="2018-09-15T06:29:00Z">1日前</time>



2018-09-15

async/await 入門(JavaScript10:26

<title>async/await 入門(JavaScript)</title>

async/await 入門(JavaScript

はじめに

今更ですが、JavaScriptasync/awaitに関する備忘録になります。

  • 「今まで$.Deferred()Promiseなどで非同期処理は書いたことがあるが、async/awaitはわからない」
  • $.Deferred()Promiseなどの非同期処理の書き方より、もっと簡潔に書ける書き方があれば知りたい」
  • 「今までの非同期処理の書き方と比べて何が良いのかわからない」

といった人達向けの記事です。

$.Deferred()Promiseなどで非同期処理を書いたことがある前提のため、非同期処理自体に関する説明は記載しておりません。

記載している利用例のコードはChrome(最新)のコンソール上で動きますので、コンソール上で実行して動作を確認してみると理解が深まりやすいと思います。

本記事で用いている用語

Promiseを返す

Promiseオブジェクトを返すこと。

// Promiseを返す
return new Promise((resolve, reject) => {

});

Promiseの結果を返す

Promiseresolveもしくはrejectを実行すること。

return new Promise((resolve, reject) => {
    // Promiseの結果を返す
    resolve('resolve!!');
});

resolveする

Promiseresolveを実行すること。

return new Promise((resolve, reject) => {
    // succes!!をresolveする
    resolve('succes!!');
});

rejectする

Promiserejectを実行すること。

return new Promise((resolve, reject) => {
    // err!!をrejectする
    reject('err!!');
});

async/awaitとは

asyncawaitを利用した、非同期処理の構文のこと。

何故async/awaitを利用するのか

Promiseを利用した構文よりも、簡潔に非同期処理が書けるから。

async/awaitの対応状況

以下は各ブラウザasync/awaitの対応状況。

ECMAScript 2016+ compatibility table

async-await.jpg

全てのブラウザで対応しているわけではないため、利用するならBabel等でトランスパイルする必要がある。

asyncとは

非同期関数を定義する関数宣言のこと。

以下のように関数の前にasync宣言することにより、非同期関数async function)を定義できる。

async function sample() {}

async functionasync宣言した関数)は何をするのか

  • async functionは呼び出されるとPromiseを返す。
  • async functionが値をreturnした場合、Promise戻り値resolveする。
  • async functionが例外や何らかの値をthrowした場合はその値をrejectする。

言葉だけだとわかりづらいため、利用例を見てみる。

async functionの利用例

以下はasync functionPromiseを返し、値をresolve、もしくはrejectしているか確認するための利用例。

※このように利用することはほとんどないと思いますが、async functionがどのような動きをしているのかを確認するために記載しております。

// resolve1!!をreturnしているため、この値がresolveされる
async function resolveSample() {
    return 'resolve!!';
}

// resolveSampleがPromiseを返し、resolve!!がresolveされるため
// then()が実行されコンソールにresolve!!が表示される
resolveSample().then(value => {
    console.log(value); // => resolve!!
});


// reject!!をthrowしているため、この値がrejectされる
async function rejectSample() {
    throw new Error('reject!!');
}

// resolveSampleがPromiseを返し、reject!!がrejectされるため
// catch()が実行されコンソールにreject!!が表示される
rejectSample().catch(err => {
    console.log(err); // => reject!!
});


// resolveErrorはasync functionではないため、Promiseを返さない
function resolveError() {
    return 'resolveError!!';
}

// resolveErrorはPromiseを返さないため、エラーが発生して動かない
// Uncaught TypeError: resolveError(...).then is not a function
resolveError().then(value => {
    console.log(value);
});

上記の通り、async functionPromiseを返し、値をresolve、もしくはrejectしていることがわかった。

上記async function単体の利用例だが、awaitと併用して利用することが多く、「asyncを利用するならawaitも必ず利用すべき」と書かれている記事もあった。

awaitとは

async function内でPromiseの結果(resolvereject)が返されるまで待機する(処理を一時停止する)演算子のこと。

以下のように、関数の前にawaitを指定すると、その関数Promiseの結果が返されるまで待機する。

async function sample() {
    const result = await sampleResolve();

    // sampleResolve()のPromiseの結果が返ってくるまで以下は実行されない
    console.log(result);
}

awaitは何をするのか

  • awaitを指定した関数Promiseの結果が返されるまで、async function内の処理を一時停止する。
  • 結果が返されたらasync function内の処理を再開する。

awaitasync function内でないと利用できないため、async/awaitの利用例を見ていく。

async/awaitの利用例

以下は単純なasync/awaitの利用例。

function sampleResolve(value) {
    return new Promise(resolve => {
        setTimeout(() => {
            resolve(value * 2);
        }, 2000);
    })
}

/**
 * sampleResolve()をawaitしているため、Promiseの結果が返されるまで処理が一時停止される
 * 今回の場合、2秒後にresolve(10)が返ってきてその後の処理(return result + 5;)が再開される
 * resultにはresolveされた10が格納されているため、result + 5 = 15がreturnされる
 */
async function sample() {
    const result = await sampleResolve(5);
    return result + 5;
}

sample().then(result => {
    console.log(result); // => 15
});

上記の処理をPromiseの構文で書くと以下のようになる。

function sampleResolve(value) {
    return new Promise(resolve => {
        setTimeout(() => {
            resolve(value * 2);
        }, 2000);
    })
}

function sample() {
    return sampleResolve(5).then(result => {
        return result + 5;
    });
}

sample().then(result => {
    console.log(result); // => 15
});

2つを見比べてみると、async/awaitの方が簡潔に書けることがわかる。

より複雑な処理の場合でもasync/awaitを利用した方が簡潔に書けるため、いくつか例を紹介していく。

連続した非同期処理

連続した非同期処理(Promise構文)

function sampleResolve(value) {
    return new Promise(resolve => {
        setTimeout(() => {
            resolve(value);
        }, 1000);
    })
}

function sample() {
    let result = 0;

    return sampleResolve(5)
        .then(val => {
            result += val;
            return sampleResolve(10);
        })
        .then(val => {
            result *= val;
            return sampleResolve(20);
        })
        .then(val => {
            result += val;
            return result;
        });
}

sample().then((v) => {
    console.log(v); // => 70
});

連続した非同期処理(async/await構文)

awaitを利用すれば、then()で処理を繋げなくても連続した非同期処理が書ける。

function sampleResolve(value) {
    return new Promise(resolve => {
        setTimeout(() => {
            resolve(value);
        }, 1000);
    })
}

async function sample() {
    return await sampleResolve(5) * await sampleResolve(10) + await sampleResolve(20);
}

async function sample2() {
    const a = await sampleResolve(5);
    const b = await sampleResolve(10);
    const c = await sampleResolve(20);
    return a * b + c;
}

sample().then((v) => {
    console.log(v); // => 70
});

sample2().then((v) => {
    console.log(v); // => 70
});

forを利用した繰り返しの非同期処理も書ける。

function sampleResolve(value) {
    return new Promise(resolve => {
        setTimeout(() => {
            resolve(value);
        }, 1000);
    })
}

async function sample() {
    for (let i = 0; i < 5; i += 1) {
        const result = await sampleResolve(i);
        console.log(result);
    }

    return 'ループ終わった。'
}

sample().then((v) => {
    console.log(v); // => 0
                    // => 1
                    // => 2
                    // => 3
                    // => 4
                    // => ループ終わった。
});

array.reduce()も利用できる。

function sampleResolve(value) {
    return new Promise(resolve => {
        setTimeout(() => {
            resolve(value);
        }, 1000);
    })
}

async function sample() {
    const array = [5, 10, 20];
    const sum = await array.reduce(async (sum, value) => {
      return await sum + await sampleResolve(value) * 2;
    }, 0);

    return sum;
}

sample().then((v) => {
    console.log(v); // => 70
});

連続の非同期処理は、処理を順番に行う必要がない限り利用すべきではないため注意。

例えば、画像を非同期読み込みをする場合、上記のような処理だと1つの画像を読み込みが完了するまで、次の画像の読み込みが始まらない

そのため、全ての画像の読み込みにかなりの時間がかかる。画像は連続して読み込む必要はないため、後述する並列の非同期処理で読み込むべき。

並列の非同期処理

並列の非同期処理(Promise構文)

function sampleResolve(value) {
  return new Promise(resolve => {
        setTimeout(() => {
            resolve(value);
        }, 2000);
    })
}

function sampleResolve2(value) {
  return new Promise(resolve => {
        setTimeout(() => {
            resolve(value * 2);
        }, 1000);
    })
}

function sample() {
    const promiseA = sampleResolve(5);
    const promiseB = sampleResolve(10);
    const promiseC = promiseB.then(value => {
        return sampleResolve2(value);
    });

    return Promise.all([promiseA, promiseB, promiseC])
        .then(([a, b, c]) => {
            return [a, b, c];
        });
}

sample().then(([a, b, c]) => {
    console.log(a, b, c); // => 5 10 20
});

並列の非同期処理(async/await構文)

Promise.allにもawaitを利用できるため、以下のように記述できる。

function sampleResolve(value) {
    return new Promise(resolve => {
        setTimeout(() => {
            resolve(value);
        }, 2000);
    })
}

function sampleResolve2(value) {
    return new Promise(resolve => {
        setTimeout(() => {
            resolve(value * 2);
        }, 1000);
    })
}

async function sample() {
    const [a, b] = await Promise.all([sampleResolve(5), sampleResolve(10)]);
    const c = await sampleResolve2(b);

    return [a, b, c];
}

sample().then(([a, b, c]) => {
    console.log(a, b, c); // => 5 10 20
});

array.map()も利用できる。

function sampleResolve(value) {
    return new Promise(resolve => {
        setTimeout(() => {
            resolve(value);
        }, 2000);
    })
}

async function sample() {
    const array =[5, 10, 15];
    const promiseAll = await Promise.all(array.map(async (value) => {
        return await sampleResolve(value) * 2;
  }));

    return promiseAll;
}

sample().then(([a, b, c
		

2018-09-14

実際のところ「ブラウザを立ち上げてページが表示されるまで」には何が起きるのか 14:12

<title>実際のところ「ブラウザを立ち上げてページが表示されるまで」には何が起きるのか</title>

実際のところ「ブラウザを立ち上げてページが表示されるまで」には何が起きるのか

問題のツイート

面接の質問で「ブラウザを立ち上げてページが表示されるまでの仕組みを全て知ってる限り説明してください」ってのをやると結構Web系の知識どれだけあるか分かると思ってる

— (@tan_go238)








<time datetime="2018-09-10T10:35:58+0000" pubdate="" style="max-width: 100%;" title="Time posted: September 10, 2018 10:35:58 (UTC)">7:35 PM - Sep 10, 2018</time>

解釈

今回は「ChromeURL欄に入力してからページが表示されるまで」をやります。ブラウザの起動云々はWeb系の話じゃないと信じてます。

1. HTTPリクエストが飛ぶ

HTTP2のヘッダ圧縮技術に全て書いてありました。

実際のリクエストヘッダ

:authority: www.google.co.jp
method
GET
path
/
scheme
https
accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8 accept-encoding: gzip, deflate, br accept-language: ja,en-US;q=0.9,en;q=0.8 cache-control: max-age=0 cookie: 🤫 upgrade-insecure-requests: 1 user-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.81 Safari/537.36 x-client-data: CJW2yQEIpbbJAQjBtskBCKmdygEI2J3KAQjancoBCKijygEIh6fKAQ==

今回はリクエストメソッドがGETなのでヘッダのみですが、POSTやPUTの場合はデータがリクエストボディで送られます。詳しくはHTTPメソッド(CRUD)についてまとめたなどを参照してください。

余談ですが、何年か前に【パズル1】ほとんどのエンジニアには解けるが、下位10%のダメなエンジニアにだけ解けないパズル?で遊んだのを思い出しました。楽しくHTTPメソッドについて学べるパズルなので解いていない人はぜひ解いてみてください。

実際のレスポンスヘッダ

HTTP/1.1 200
status: 200
date: Tue, 11 Sep 2018 09:36:30 GMT
expires: -1
cache-control: private, max-age=0
content-type: text/html; charset=UTF-8
strict-transport-security: max-age=3600
content-encoding: br
server: gws
x-xss-protection: 1; mode=block
x-frame-options: SAMEORIGIN
set-cookie: 1P_JAR=2018-09-11-09; expires=Thu, 11-Oct-2018 09:36:30 GMT; path=/; domain=.google.co.jp
alt-svc: quic=":443"; ma=2592000; v="44,43,39,35"

レスポンスヘッダは上みたいな感じで、このヘッダと一緒に届くレスポンスボディが<!doctype html>〜〜というhtmlドキュメントです。

もっと低レイヤーについてはOSI参照モデルまとめが分かりやすいです。

DNS?何ですかそれは。

DNSプロトコルってよく分かりませんしHTTPSで名前解決できたら楽でいいですよね。

2. レンダリングエンジンが描画を行う

レスポンスボディで返ってきたhtmlドキュメントを元にブラウザに搭載されているレンダリングエンジンが画面を描画します。

Chromeの場合はBlinkというエンジンが搭載されています。

レイヤー図

(image from How Blink works by Kentaro Hara)

で、このBlinkで行われているレンダリングプロセスが下図です。

レンダーパイプライン

(image from How Blink works by Kentaro Hara)

htmlドキュメントを解釈してDOMを構築し、styleを当てはめてレイアウトしてから描画です。あとはLife of a Pixel 2018を見てください。マジで分かりやすいのでオススメです。これを見た後じゃあ自分で書き直そうという気にはなれませんね。

でも「どうしてもお前が書いた解説が読みたいんだ!!!」という人の為に書きます。正直これ以降の部分は質が微妙です。プロのあなたの助けを求めています。コメント・編集リクエストお待ちしています。

DOMとは

Document Object Modelの略です。chromiumのDOMのページに実装などの情報がまとまっています。

「いやDocument Object Modelって何やねん」となると思うのですが、端的にいうと木です。tree。

DOMChromeで「⌘+⌥+i」を押すと出現する検証モードの「element」の項目に並んでいるアイツです。キーボードに⌘キーや⌥キーが無い場合はこちらへどうぞ。

(例)google.co.jpDOM

DOCUMENT (always the root)
 └─HTML
   ├─HEAD
   │  └─...
   └─BODY
      ├─DIV
      │  └─...
      ├─SCRIPT
      └─SCRIPT

それぞれのnodeの実装

container node graph

(image from core/dom/README.md by きらきら☆はやとたん)

親はfirstChildとlastChildの情報しか持ってないそうです。連結リストってヤツですね。

レンダリングエンジンはHTML文章を解析し、上記のようなDOMツリーを構築します。

Style

レンダリングエンジンはCSSを解析してCSS Object Modelツリーを構築します。

元のCSS

body { font-size: 16px }
p { font-weight: bold }
span { color: red }
p span { display: none }
img { float: right }

⬇️CSSOM

CSSOM

(image from オブジェクト モデルの構築 by Ilya Grigorik)

DOMとCSSOMを組み合わせるとRender Treeが完成します。

render tree

(image from レンダリング ツリーの構築、レイアウト、ペイント by Ilya Grigorik)

ちなみにこのCSSOMはJavascriptexpose(日本語訳求む)されているのでwindow.getComputedStyle() で要素のスタイルを取得する事ができます。

Layout

レンダリングツリーを元に、個々の要素がウィンドウ内のどこに配置されるかを決めていきます。

css box model

(image from CSS Box Model Module Level 3)

上の画像みたいなCSS Box Modelを使って、親から子へと再帰的に、つまり子は親のcontent内にレイアウトされていきます。CSSでは親要素との相対的な位置関係で記述されていますが、レイアウト処理の出力段階では画面上の絶対的な位置になります。

Life of a Pixel 2018 (1).png

(image from Life of a Pixel 2018)

Life of a Pixel 2018.png

(image from Life of a Pixel 2018)

中のコンテンツがスペースをオーバーしてもOKで、その時の選択肢は全て表示する「visible」、オーバーした部分を表示しない「hidden」、そしてスクロールできるようにする「scroll」の3つです。

  • SCROLLING IN BLINK | スクロールの仕組みについて。position: stickyって初めて知ったけどめっちゃ便利じゃないですか?もっと早く知りたかった……

後LayoutNGなる新しいレイアウトシステムが開発中らしい。

Paint

表示されるべき要素とそのスタイルが計算できたので、最後にそれぞれの要素を実際のピクセルに落とし込んでいきます。

Life of a Pixel 2018 (2).png

(image from Life of a Pixel 2018)

DOMツリーとは関係なく、描画リストの順番で描画されていきます。CSSのz-indexを設定する事で順番を明示的に指定できます。

Life of a Pixel 2018 (3).png

(image from Life of a Pixel 2018)

また、backgroundやfloatなどの要素によってどれが上に来るのかが変わるので、背後の要素が部分的に前に出て来ることもあるらしいです。

この描画工程が終わると画面にページが表示されます。

Compositor thread

ブラウザレンダリング処理は全てmainスレッドという一つのスレッドで行われます。スレッドが一つしか無いというのは、javascriptなどで何か重たい処理を実行してしまいスレッドを埋めてしまった場合にスクロールなど基本的な操作すらおぼつかなくなってしまう危険があるということです。

そこで、スクロールやアニメーション、ズームなど「レイヤーの移動・スケールの変更」で対処できるものに関しては、レンダリングが終わった後に別スレッドへと移動させ、スムーズな操作を可能にしようというのが「Compositor Thread Architecture」です。

Life of a Pixel 2018 (4).png

(image from Life of a Pixel 2018)

プロの方々のコメントや編集リクエストをお待ちしています。よろしくお願いします。

この記事よりもLife of a Pixel 2018を読みましょう。ブラウザレンダリングについて学ぶなら最高にオススメのスライドです。

2018-09-12

M社の採用について · GitHub 07:27

<title>M社の採用について · GitHub</title>

M社のエンジニア採用について

自分がやめた時点でのバックエンドエンジニア採用フロー

  1. 各プロダクトの開発責任者1名(規模が大きい家計簿・会計は +1名)が採用担当者
  2. 応募が来たら各採用担当者が自分のチームにほしいかどうか(会いたいか会いたくないか)を決める
  3. 会いたい意思を出したメンバーからMAX4名までを面接官とする。4名以上いたらランダムで4名選出する
  4. 1名につき15 - 30分面接する(ので採用希望者は2時間くらい面接を受ける。。)
  5. 面接官は全員が面接を終えるまで、原則評価を共有してはいけない。全員が終わったら、取る、他のチームならありえる、取らないの3択で評価を共有する
  6. 他のチームならの意見が面接官で一致していて、そのチームの担当者が面接官に含まれていないときだけエンジニア2次面接がある。それ以外であればそのままCTO面接
  7. CTO面接はカルチャーのフィットくらいしかみない。ので実質取るか取らないかは各チームの責任者に委ねられている

↑のフローになった経緯とか

  • 昔、人事が面接に出てきて〜〜みたいな記事がネットでバズったので、基本的にエンジニアだけで合否を決めることになった
  • 以前は一部のエンジニアが面接をしていたため基準が不明確だったので、どういう評価を出すかルール化した
  • チームによって求める人材像を出してみると、意外と求めることが全然違ったので各チームで代表者を出すことになった
  • 以前は4人中一人でも「取らない」の評価を出したら取らない制度だったが、とあるチームが例外で採用した人がチームにマッチしてよく機能していたので、誰かが「取らない」にしたら必ず落とすルールは廃止された

M社が遭遇した失敗パターン

人が足りないから、という妥協

積極的に来てほしいとまでは思わないが、悪くはないので採用、という判断をしていた結果、

エンジニアレベルに格差が生まれ、あとから入ってきた優秀なエンジニアと軋轢が生まれた

最終的にエンジニア文化の違いに耐えられなくなり、やめてしまった

  • どういう文化にしたいかの明確化は必須
  • 人が足りないという誘惑に負けない。悪くないから取るのではなく、来てほしいから取るの徹底

知識はあるがコードを書いてみると、、

面接では高評価だったが、いざ仕事についてもらうとオレオレコードを書く人だった

最終的にコードレビューを無視してマージするなどの横暴が見られたので面談が開かれたが、

最終的に文化の違いでやめてしまった

  • 誰もコードを確認していなかった
  • 会話の雰囲気だけで会社の文化にマッチしていると判断していないか確認が必要

評判だけで高評価採用

rubyの書籍を出したこともあるという話で、面接でも特に問題点は見つからなかったので当時のエンジニア給料平均の2倍近くの報酬で採用した

実際に仕事をしてみると(申し訳ないが、、)スキルの低い人だった

数年後、人事施策給与レンジを定めることになった際にレンジから大幅に外れているにもかかわらず、評価が全く伴っていないという自体になった。

通常の給与レンジまで減給するかやめてもらうかしかないという厳しい面談をすることになり、結局やめてしまった。

その噂が広まり、給料を公開すべき/しないべき論争まで発展して大炎上した

  • スキルレンジと給与レンジをある程度決めておくべきだった
  • 本を書いてるから優秀、といったうわべの評価ではなく、実際のスキルを確認するべきだった
  • 優秀な人を金の力で採用する手段は何かが壊れる気がする。エンジニア給料がインフレしているので見劣りしない額は必要だが、通常ではありえない額は昇給で出すほうが低リスク
  • ちなみにM社では給与額はCTO以上が決めていたので、採用を決めてもいくらになったのかは不透明なままだった

採用関連でやっていたこと

内部向けにやっていたこと

会社としてどういうエンジニアがほしいのかブレスト

  • 参加者は各チームの開発責任者がmustでその他希望者
  • まずはどういうエンジニア文化にしたいのかを共有した
    • こういうのはいい、こういうのは嫌だとかざっくり
  • そのためにはどういう人が来てくれるとありがたいかを共有

チームごとに欲しい人像を決める

  • チーム内のエンジニア全員で話し合う
  • フォーマットにしたがって具体的にどういう条件が必要かをまとめて記事を共有

本読む

この辺を読んでいる前提でいろいろ会話されていたと思う...

外部向けにやっていたこと

エンジニアブログ

  • 当番制で毎週誰が書くかローテされていた
  • ローテ以外でも書きたい人が書くのはOK
  • だんだんネタがなくなって書かなくなっていった...
  • 採用受ける側からしたらあったほうが印象が良い。書く意欲がある人がいるならやるべき

チーム紹介、エンジニア紹介の記事を作る

Rubyコミッター採用

  • 知名度や露出機会の増加には相当効果があった
  • 技術に強くない企業相手なら技術力の証明としてのセールストークにも使えた
  • コミッターの方がいい人だったのでRuby以外でも技術的相談に乗ってくれたりしていた
  • Rubyへのロックイン感は否めず

カンファレンス等のブース展開、協賛

FAQ

何人くらい受けに来て何人くらい通ったか

月に5 - 20くらいは来ていた

多分30人に1人くらいしか合格していない。年間で10人くらい

どこから来ていたか

主にエージェント、wantedly、紹介

エージェントは高い割に質が微妙だった

紹介が圧倒的に質が高いので、そもそもエンジニアネットワークが広い人を採用するのがよい

フロントエンド、スマホインフラエンジニアデザイナーはどうしていたか

基本的にどういう人がほしいかチームで議論して記事を書くところまでは共通

どういう面接フローにするかはそれぞれバラバラ

(例えばインフラエンジニアは1対多メンバーで1時間面接等)

2018-09-10

Google Apps ScriptsでTypescriptが超簡単に使えるようになった! - アクトインディ開発者ブログ 18:47

<title>Google Apps ScriptsでTypescriptが超簡単に使えるようになった! - アクトインディ開発者ブログ</title>

Google Apps ScriptsでTypescriptが超簡単に使えるようになった!

morishitaです。

Cloud Functions と並ぶ(?)Googleサーバレスな JavaScript 実行環境といえば Google Apps Scripts(GAS)です。

GAS ってあの Excel で言う VB スクリプト環境のようなものでしょう? と思ったあなた!

このエントリでその認識が変わると思います。

以前は使いやすいとは言い難かったGASですが、最近は使いやすくなってきました。

といっても、GAS 自体がアップデートされたのではなく周辺ツールが整備が進み開発・運用しやすい状況が整ってきたからです。

そして、なんと最近Typescript でとても実装しやすくなったので、それをご紹介したいと思います。

google/clasp

以前の GAS は Web エディタ上でしか実装できず、コードを VCS で管理することもままならない状況でしたが、Google からgoogle/claspがリリースされ、状況が改善されました。

これは GAS を管理するための CLI ツールで、Google Drive 上の GAS のコードをローカルに pull したり、逆に Google Drive 上の GAS のプロジェクトに push したりできます。

ということは、Git で管理しながらローカルの使い慣れたエディタでコードを書いて、GAS に push して実行するという開発ができるのです1

google/clasp が、この平成最後の夏にリリースされた v1.5.0 でなんと Typescript をサポートしたのです。

これまでも Webpack や Babel を使ってトランスパイルして ES6 や Typescript で GAS の開発はできました。

しかし、どんどんバージョンアップする Webpack や Babel に追従しようとしてアップデートするとビルドできなくなるようなトラブルも起こりがちでした。

でも、その苦労から解放されたのです。

少々、前置きが長くなりましたが、実際に使ってみましょう。

@google/clasp のインストールとローカル環境の初期化

google/clasp は Node.jsモジュールです。Node.js 4.7.4 以上が必要なので、用意してください。

Node.jsの準備ができたら、次のコマンドで、ローカル環境を作ります2

$ mkdir clasp-ts-sample
$ cd clasp-ts-sample
$ npm init -y
$ npm install @google/clasp tslint -D
$ npm install @types/google-apps-script -S
$ tslint --init # tslint は必須ではありませんが、大人のたしなみとして導入しましょう。


Typescript は明示的にインストールしなくても@google/claspが依存しているのでインストールされます。2018/09/10時点では Typescript 2.9.2がインストールされます。

@types/google-apps-script も導入することにより VSCode 等ではコード補完されるようになります。

SpreadsheetAppなど、GAS 固有のクラス群も定義されています

素晴らしい!!

GAS プロジェクトの作成

次のコマンドで、GAS プロジェクトのファイルを Google Drive に作成します。その後、生成されたコードをローカルに pull します3

$ clasp create clasp-ts-sample
$ clasp pull


ここまででできたファイル構成は次の通りです。

clasp-ts-sample/
├── .clasp.json
├── node_modules/
├── package-lock.json
├── package.json
├── Code.js
├── appsscript.json
└── tslint.json


rootDirを設定し、ソースファイルを src に移動する

実装を開始する前に、環境準備にもうひと手間かけます。

というのも、このまま、 clasp pushを実行すると、node_modules以下のすべての JS を読み込もうとして失敗します。

.claspignore を作って無視してやることもできますが、オススメは .clasp.jsonrootDirを定義する方法です。

次の様に.clasp.jsonrootDirを追加します。

{
  "scriptId": "******-***************************************************",
  "rootDir": "src"
}


そして、src ディレクトリを作って、clasp pushの対象となるファイルを移動します。

$ mkdir src
$ mv appsscript.json src/
$ mv Code.js src/Code.ts


これで準備は終了。次のようなファイル構成になります。

clasp-ts-sample/
├── .clasp.json
├── node_modules/
├── package-lock.json
├── package.json
├── src/
│   ├── Code.ts
│   └── appsscript.json
└── tslint.json


Typescript のコードを PUSH してみる

clasp のリポジトリにあるサンプルをコピーして試してみます。

それが次のCode.ts です。alert を使っていた部分は、GAS では動かないので修正しています。

// 型定義
const isDone: boolean = false;
const height: number = 6;
const bob: string = "bob";
const list1: number[] = [1, 2, 3];
const list2: number[] = [1, 2, 3];

enum Color {
  Red,
  Green,
  Blue
}

const c: Color = Color.Green;
let notSure: any = 4;
notSure = "maybe a string instead";
notSure = false; // okay, definitely a boolean

function showMessage(data: string): void {
  // Void
  Logger.log(data);
}
showMessage("hello");

// クラス
class Hamburger {
  constructor() {
    // コンストラクタ
  }
  public listToppings() {
    // メソッド
  }
}

// テンプレート文字列
const name = "Sam";
const age = 42;
console.log(`hello my name is ${name}, and I am ${age} years old`);

// Rest arguments
const add = (a: number, b: number) => a + b;
const args = [3, 5];
add(...args); // same as `add(args[0], args[1])`, or `add.apply(null, args)`

// スプレッド構文 (array)
const cde = ["c", "d", "e"];
const scale = ["a", "b", ...cde, "f", "g"]; // ['a', 'b', 'c', 'd', 'e', 'f', 'g']

// スプレッド構文 (map)
const mapABC = { a: 5, b: 6, c: 3 };
const mapABCD = { ...mapABC, d: 7 }; // { a: 5, b: 6, c: 3, d: 7 }

// 分割代入
const jane = { firstName: "Jane", lastName: "Doe" };
const john = { firstName: "John", lastName: "Doe", middleName: "Smith" };
function sayName({ firstName, lastName, middleName = "N/A" }) {
  console.log(`Hello ${firstName} ${middleName} ${lastName}`);
}
sayName(jane); // -> Hello Jane N/A Doe
sayName(john); // -> Helo John Smith Doe

// Export (The export keyword is ignored)
export const pi = 3.141592;

// Google Apps Script の独自サービスの利用
const doc = DocumentApp.create("Hello, world!");
doc
  .getBody()
  .appendParagraph("This document was created by Google Apps Script.");

// デコレータ高階関数
function Override(label: string) {
  return (target: any, key: string) => {
    Object.defineProperty(target, key, {
      configurable: false,
      get: () => label
    });
  };
}
class Test {
  @Override("test") // invokes Override, which returns the decorator
  public name: string = "pat";
}
const t = new Test();
console.log(t.name); // 'test'


どうでしょう、次のような Typescript ならではのものを含むモダンな実装を含んでいます。


そして、Google Docs を扱う DocumentAppを利用するコードも含んでいます。

では、Google Drive 上の GAS プロジェクトに push してみましょう。

次のコマンドだけで、自動的にトランスパイルして、GAS に push してくれます。

$ clasp push


tscなどを使って事前にトランスパイルする必要はありません

tsconfig.jsonすら用意不要です4

Javascript のコードを push するように Typescript のコードも push できます。

続いて GAS プロジェクトに push されたコードを見てみましょう。

clasp open コマンドを実行すると Google Drive 上の GAS プロジェクトがブラウザで開きます。

次の様にファイル Code.gs としてトランスパイルされています。

var exports = exports || {};
var module = module || { exports: exports };
var __assign =
  (this && this.__assign) ||
  Object.assign ||
  function(t) {
    for (var s, i = 1, n = arguments.length; i < n; i++) {
      s = arguments[i];
      for (var p in s)
        if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
    }
    return t;
  };
var __decorate =
  (this && this.__decorate) ||
  function(decorators, target, key, desc) {
    var c = arguments.length,
      r =
        c < 3
          ? target
          : desc === null
            ? (desc = Object.getOwnPropertyDescriptor(target, key))
            : desc,
      d;
    if (typeof Reflect === "object" && typeof Reflect.decorate === "function")
      r = Reflect.decorate(decorators, target, key, desc);
    else
      for (var i = decorators.length - 1; i >= 0; i--)        if *1
          r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
    return c > 3 && r && Object.defineProperty(target, key, r), r;
  };

// 型定義
var isDone = false;
var height = 6;
var bob = "bob";
var list1 = [1, 2, 3];
var list2 = [1, 2, 3];
var Color;
(function(Color) {
  Color[(Color["Red"] = 0)] = "Red";
  Color[(Color["Green"] = 1)] = "Green";
  Color[(Color["Blue"] = 2)] = "Blue";
})(Color || (Color = {}));
var c = Color.Green;
var notSure = 4;
notSure = "maybe a string instead";
notSure = false; // okay, definitely a boolean
function showMessage(data) {
  Logger.log(data);
}
showMessage("hello");
// Classes
var Hamburger = /** @class */ (function() {
  function Hamburger() {
    // コンストラクタ
  }
  Hamburger.prototype.listToppings = function() {
    // メソッド
  };
  return Hamburger;
})();
// テンプレート文字列
var name = "Sam";
var age = 42;
console.log("hello my name is " + name + ", and I am " + age + " years old");
// Rest arguments
var add = function(a, b) {
  return a + b;
};
var args = [3, 5];
add.apply(void 0, args); // same as `add(args[0], args[1])`, or `add.apply(null, args)`
// スプレッド構文 (array)
var cde = ["c", "d", "e"];
var scale = ["a", "b"].concat(cde, ["f", "g"]); // ['a', 'b', 'c', 'd', 'e', 'f', 'g']
// スプレッド構文  (map)
var mapABC = { a: 5, b: 6, c: 3 };
var mapABCD = __assign({}, mapABC, { d: 7 }); // { a: 5, b: 6, c: 3, d: 7 }
// 部分代入
var jane = { firstName: "Jane", lastName: "Doe" };
var john = { firstName: "John", lastName: "Doe", middleName: "Smith" };
function sayName(_a) {
  var firstName = _a.firstName,
    lastName = _a.lastName,
    _b = _a.middleName,
    middleName = _b === void 0 ? "N/A" : _b;
  console.log("Hello " + firstName + " " + middleName + " " + lastName);
}
sayName(jane); // -> Hello Jane N/A Doe
sayName(john); // -> Helo John Smith Doe
// Export (The export keyword is ignored)
exports.pi = 3.141592;
// Google Apps Script の独自サービスの利用
var doc = DocumentApp.create("Hello, world!");
doc
  .getBody()
  .appendParagraph("This document was created by Google Apps Script.");
// デコレータ高階関数
function Override(label) {
  return function(target, key) {
    Object.defineProperty(target, key, {
      configurable: false,
      get: function() {
        return label;
      }
    });
  };
}
var Test = /** @class */ (function() {
  function Test() {
    this.name = "pat";
  }
  __decorate(
    [
      Override("test") // invokes Override, which returns the decorator
    ],
    Test.prototype,
    "name"
  );
  return Test;
})();
var t = new Test();
console.log(t.name); // 'test'


動作確認

GAS の Web エディターでは 3 つの関数が実行対象として選択できると思います。

その中から試しにOverrideを実行してみます。

Override以外の関数は実行されませんが、関数外の部分は実行されます。

もちろんちゃんと動きます。

console.logの出力はStackdriver Loggingに次のように出力されます。

f:id:HeRo:20180908100232p:plain

また、DocumentApp.createして、中に文字列を書き込んでいる部分がありますが、

その出力として次のようなGoogle Docのファイルが Google Driveの中に作成されます。

f:id:HeRo:20180908100329p:plain

とても簡単です。

また、clasp pushにはwatchモードまであります。

次のコマンドを実行しておけば、コードの変更を検知すると自動的に再 push してくれます。

$ clasp push --watch


これで実装->実行->また実装 のサイクルが少し楽になりますね。

まとめ

どうでしょう、これまで GAS を使ってきた方には、今までのやり方がバカバカしくなるほど簡単に Typescript で実装できることがおわかりいただけたと思います。

もう Typescript で GAS を実装しない理由が見当らないでしょう?

GAS は Cloud Functions に比べると制約が多く、Google Drive 上のアプリケーションの拡張用と思われがちです。

しかし次のような特徴を備えており、ユースケース次第では大変便利に使えるサービスです。


特に、BigQuery や Analytics のデータを集計して、レポートを作成する作業を自動化するには最も便利な環境だと思います。

SheetsやSlidesのファイルとしてGoogle Drive上に出力するのが簡単ですし、Gmail経由でメールも出せますし、定期実行できますし。

また、去年次の 2 つが使えるようになり、ますます運用しやすくなりました。

  • Apps Script dashboard
    • GAS 専用の管理ダッシュボード。
    • Google Drive に散らかりがちな GAS プロジェクトを一元管理できます。
    • Sheets ファイルなどに含まれる container-bound な GAS プロジェクトも管理できます。
  • Stackdriver Logging
    • 汎用のロギングサービス。
    • console.log等の出力がログとして記録されます。
    • デバッグや実行状況の確認が格段にやりやすくなりました。


うまく使えば業務の効率化に大いに役立ってくれる GAS を Typescriptモダンに開発しましょう。

参考


最後に

アクトインディでは エンジニアを募集しています。

actindi.net


  1. このような開発スタイルを最初に実現し、エポックメイキングなツールだったnode-google-apps-scriptはすでにディスコンとなっています。

  2. claspnpm install -g @google/claspでグローバルにインストールしてもいいのですが、私は ndenv で複数バージョンの Node.jsインストールしており、プロジェクトごとに Node.js のバージョンが異なったりします。それで、グローバルなインストールは避けています。代わりに、./node_module/.binPATH に追加してプロジェクトディレクトリインストールしたコマンドを実行できるようにしています。

  3. これまで、claspを使ったことがなければ、ログインと、API の有効化が必要になります。参考:GAS の Google 謹製 CLI ツール clasp

  4. claspts2gasを利用してトランスパイルしています。コンパイルオプションはこちら =>compilerOptions

  5. GAS のスクリプトの実行自体は無料ですが、有料サービスの API 呼び出た場合、別途課金されます。


*1:d = decorators[i]

2018-09-08

Vue.jsとFirebaseで最速でウェブサービスを作るための学習教材3ステップ【完全独学】 - katonobo’s blog 14:45

<title>Vue.jsとFirebaseで最速でウェブサービスを作るための学習教材3ステップ【完全独学】 - katonobo’s blog</title>

Vue.jsとFirebaseで最速でウェブサービスを作るための学習教材3ステップ【完全独学】

この記事は、

・実際に何か自分でウェブサービスを作って見たいけどどうすればいいかわからない。

・Vue.jsを使って何か作って見たい

という方向けの記事です。

私は、何かウェブサービスを作って見たいと考えている人には、Vue.jsとFirebaseを利用したサービスの作成をオススメしています。

なぜなら、この二つを習得するとすごく簡単にウェブサービスを作ることができるからです!シンプルな理由ですし、これが一番大事ですよね。

私のブログには多くのプログラミング初心者やVue.jsを勉強している方が訪問してくださっています。

その方々の参考になるよう、自分の今までの学習した教材や内容を書き出し、本当に必要で、そして最短で技術を身に付けるにはどのような教材をどの順序でやるのが一番効果があるかを書き出しまとめました。

この教材にたどり着くまでに、私はかなり多くの書籍や学習動画を購入し実際に試しています。その中で絶対に外せない3つの教材を厳選しました。この記事は、貴重なお金と時間を節約できる、かなり価値のある情報であると自負しています。 なんか煽りみたいになってしまってすみません。けど、それぐらい自信があります。

対象の方は、HTMLCSSJavascriptの経験がある方です。できればPHPなどのサーバサイド言語の経験があればなお良いです。ただし、私自身もPHPの経験はあったものの、Javascriptはやっていなかったので、これから勉強する予定の方なら当てはまらなくても大丈夫と思います。

ステップ1:Vue.jsとFirebaseで作るミニWebサービス


Vue.jsとFirebaseで作るミニWebサービス (技術書典シリーズ(NextPublishing))

この教材で身に付けること

・Vue.jsの設定方法

・Vue.jsの基本的な扱い方

・Firebaseの設定方法

・Vue.jsとFirebaseの連携方法

・サービスをデプロイまで持っていく方法

Vue.jsとFirebaseを使ってウェブサービスを作ろうと思ったとき、最初に読むのは本書一択でしょう!それぐらい良く構成されています。

この本の素晴らしいところは、本書にしたがって進めていけば、あっという間にウェブサービスを公開するところまでできてしまうことです。

実際に自分でサービスを作り、それを世に出す(デプロイ)するところまで説明してくれる本はそうそうありません。

初心者の立場にしっかり立って書かれており、つまずくこともほぼなく最後まで学習することができると思います。

しかし、この本ではサービスを作りながら学ぶため、Vue.jsの応用的な部分まではさすがにカバーできていません。「Vue-router」や「Vuex」と行った、Vue.jsの実践レベルの知識を体系的に習得する必要があります。そこでステップ2です。

ステップ2:基礎から学ぶ Vue.js


基礎から学ぶ Vue.js

この教材で身に付けること

・Vue.jsの基礎を体系的に学習する

・Vue-routerやVuexという機能を身に付ける

・なんかわからないことがあったときに辞書的な使い方をする

本書は「基礎から学ぶ〜」と題名にあるように学習は基礎から始まりますが、それでいて、すごく詳しい部分まで解説されています。ここで、一気にVue.jsについての全体像を押さえておきましょう。

ただし、この本の内容を全てしっかり学習するのはかなり骨が折れるので、まずはざっと目を通し、サンプルなどをいじりながら、全体を把握し何かサービスを作っているときなど必要が出てきたときに都度本書を開くと行った辞書的な使い方がいいと思います。

サポートページがあり、ここがすごく学習の手助けをしてくれるので、本書を買ったらこちらのページを使い倒しましょう。

cr-vue.mio3io.com


ステップ3:Build Web Apps with Vue JS 2 & Firebase

f:id:katonobo:20180905111819j:plain 

Build Web Apps with Vue JS 2 & Firebase

この教材で身に付けること

・Vue.jsのおさらい

・実際にレベルの高いウェブサービスを作成する

ステップ2までで基本的にはVue.jsとFirebaseは使えるようになっています。簡単なウェブサービスならすでに作れる基礎力はついています。

ステップ3で、本格的なウェブサービスを作れる実力を身につけます。

この「Build Web Apps with Vue JS 2 & Firebase」は、Udemyという動画学習サイトの教材です。なので、書籍ではなく、動画での学習となります。

内容は英語なので、ちょっと抵抗がある人もいると思いますが、動画なので何をしているかは目で確認できるので英語がわからなくて動画をしっかり見て真似をすれば問題ありません。

この動画をやり終えれば、

LINEのようなチャットサービス

・位置情報を利用しグーグルマップを使った伝言板サービス

が作れるようになります。つまり、大体のWebサービスが作れる実力がつくでしょう。

まとめ

この3ステップをこなせば、あなたはもう相当な技術を身につけているはずです。

この3つの教材をベースに、グーグルの検索やQiitaを活用し、自分が作りたいウェブサービスを作ってください! 

2018-09-07

「5億円稼いだら辞めると決めていた」カカクコム創業し、28歳でリタイアした男の今|新R25 - 20代ビジネスマンバイブル 12:56

https://r25.jp/article/586737603776383066

2018-09-06

ReactとVueってどう違う?全く同じアプリをReactとVueで作成してみて分かった相違点 | コリス 11:51

<title>ReactとVueってどう違う?全く同じアプリをReactとVueで作成してみて分かった相違点 | コリス</title>

ReactとVueってどう違う?全く同じアプリをReactとVueで作成してみて分かった相違点

UX道場 -UXデザインの基礎知識からUI/Webデザインに役立つ情報、Adobe XDの最新情報まで

日常的にVueを使用している開発者が、Reactはどうなのだろうと思い、ReactとVueで全く同じアプリを作成した時のそれぞれの工程を比較して分かった相違点を紹介します。

サイトのキャプチャ

I created the exact same app in React and Vue. Here are the differences.

下記は各ポイントを意訳したものです。

※当ブログでの翻訳記事は、元サイト様にライセンスを得て翻訳しています。

  • 隣の家の芝生は青く見える
  • VueとReactで作成したアプリの見た目を比較
  • VueとReactはデータをどのように変更させるか
  • アイテムの新規作成
  • アイテムの削除
  • イベントリスナーを渡す
  • コンポーネントにデータを渡す
  • コンポーネントにデータを戻す
  • 終わりに

隣の家の芝生は青く見える

私は現在の職場でVueを使用しており、Vueがどのように機能するかかなり理解していると思います。しかし、隣の家の芝生はどんなものなのか非常に興味があります、その芝生とはReactのことです。

Reactのドキュメントを読んで、チュートリアルのビデオをいくつか見てみました。それは参考になったのですが、私が本当に知りたかったのは、ReactとVueがどのように異なるのかということでした。異なるというのは、仮想DOMとかレンダリングなどのことではありません。コードレベルで具体的にどう違うのかが知りたいのです。

しかし、いくら探しても見つけることができませんでした。そこで私は、類似点と相違点を知るためには、自分自身で記事を書かなければならないことを認識しました。この記事がここに存在するように、私はプロセス全体をドキュメント化しました。

VueとReact

VueとReact

ドキュメントを書くにあたり、TODOリストのアプリを作成しました。機能は、アイテムを加えたり、削除できるだけの簡単なアプリです。どちらもデフォルトCLI(Reactではcreate-react-app、Vueではvue-cli)を使用しました。

CLIとは、Command Line Interface(コマンド・ライン・インターフェース)の略。

VueとReactで作成したアプリの見た目を比較

TODOリストのアプリ

左: Vueで作成したアプリ、右: Reactで作成したアプリ

CSSのコードは両方とも全く同じですが、置き場所が異なります。そのことを念頭において、アプリのファイル構造を見てみましょう。

アプリのファイル構成

左: Vueのファイル構造、右: Reactのファイル構造

VueとReactで、ファイル構造はほとんど同じです。唯一違うのは、Reactには3つのCSSファイルがあることです。VueにはCSSファイルが一つもありません。その理由は、create-react-appではReactコンポーネントがスタイルを保持するためのファイルを持ち、Vue CLIでは実際のコンポーネントファイル内でスタイルが宣言されている包括的なアプローチを採用しているからです。

2つは共に同じことを達成しており、ReactとVueであなたのCSSを違った方法で構築することはできません。これは完全に個人の好みでしょう、CSSをどのように構造化するべきかは、開発者コミュニティで活発に議論されています。現時点では、両方のCLIに配置された構造に従います。

先に進む前に、VueとReactの典型的なコンポーネントを見ておいてください。

Vueのコンポーネント

Vueのコンポーネント

Reactのコンポーネント

Reactのコンポーネント

VueとReactはデータをどのように変更させるか

まずは「データの変更」とは、何を意味するでしょうか? 変更とは、保存したデータを変えることです。例えば、名前の値をJohnからMarkに変えたいのであれば、「データを変更させる」ことになります。このやり方が、ReactとVueでは大きく異なります。

Vueでは基本的にdataオブジェクトを作成しますが、データを自由に更新できます。Reactではstateオブジェクトを作成し、それを更新するには少し作業が必要となります。Reactのこの少しの作業には、正当な理由があります。まずは、VueのdataオブジェクトとReactのstateオブジェクトを見てみましょう。

左: Vueのdataオブジェクト、右: Reactのstateオブジェクト

左: Vueのdataオブジェクト、右: Reactのstateオブジェクト

ラベルは異なっていますが、同じデータを渡しています。つまり、最初のデータをコンポーネントに渡すことは非常によく似ているということです。しかし、前述したように、このデータをどのように変えるかは、両方のフレームワークによって異なります。

例えば、名前が「Sunil」というデータ要素があるとします。

Vueでは、「this.name」で参照できます。「this.name = 'John'」と呼び出すことで、更新することができます。これで名前は「John」に変更されました。

Reactでは、「this.state.name」で同じデータを参照します。ここでの主な違いは、Reactには制限があるため、単に「this.state.name = 'John'」と書くことができないということです。Reactでは「this.setState({name: 'John'})」と書きます。

これはVueで達成したことと同じですが、Vueはデータが更新されるたびにsetStateの自身のバージョンを組み合わせているため、追加の書き込みがあります。つまり、ReactではsetStateとその内部の更新データを必要としますが、Vueではdataオブジェクト内の値を更新すると仮定して実行します。なぜReactではVueと同じにしないのでしょうか? そしてなぜsetStateが必要なのでしょうか? この説明はRevanth Kumarに委ねます。

それは、Reactがstateが変わるたびに特定のフックを再実行しようとしているためです。例えば、componentWillReceiveProps, shouldComponentUpdate, componentWillUpdate, render, componentDidUpdate, whenever state changes など。setState関数を呼び出すと、stateが変更されたことが分かるでしょう。もし、stateを直接的に変更させた場合、Reactは変更を追跡し、フックを実行するなど、もっと多くの作業を行う必要があります。それを簡単にするために、ReactはsetStateを使用します。

Vueでは「this.name」を使用する

一方はシンプルじゃないね

データの変更について、VueとReactの相違を理解できたので、アプリ作成に戻ります。

アイテムの新規作成

Reactの場合


1

2

3

4

5

6

7

8

9

10

11

12

createNewToDoItem = () => {

    this.setState( ({ list, todo }) => ({

      list: [

          ...list,

        {

          todo

        }

      ],

      todo: ''

    })

  );

};


Reactの場合では、inputフィールドにvalueという属性があり、このvalueは双方向バインディング(説明は後述)を作成するために結合された2つの関数を使用して自動的に更新されます。onChangeイベントリスナをinputフィールドに加えることによって、双方向バインディングを作成します。どのようになるか、inputフィールドのコードを見てましょう。


1

2

3

<input type="text"

       value={this.state.todo}

       onChange={this.handleInput}/>


handleInput関数は、inputフィールドのvalueが変更されるたびに実行されます。これは、inputフィールドに何かが入力されると、stateオブジェクト内にあるtodoを更新します。関数は、下記のようになります。


1

2

3

4

5

handleInput = e => {

  this.setState({

    todo: e.target.value

  });

};


ユーザーが+ボタンを押して新しいアイテムを追加すると、createNewToDoItem関数がthis.setStateを実行し、関数に渡します。この関数は2つのパラメータを受け取り、1つ目はstateオブジェクトのリスト配列全体、2つ目はtodo(handleInput関数で更新)です。この関数は新しいオブジェクトを返し、新しいオブジェクトは前のリスト全体を含み、最後にtodoを追加します。リスト全体は、スプレッド演算子を使用して追加されます。

最終的には、todoを空の文字列に設定して、inputフィールド内のvalueを自動的に更新します。

Vueの場合


1

2

3

4

5

6

7

8

createNewToDoItem() {

    this.list.push(

        {

            'todo': this.todo

        }

    );

    this.todo = '';

}


Vueの場合では、inputフィールドにv-modelと呼ばれるハンドルを使用します。このハンドルにより、双方向バインディングを行うことができます。inputフィールドのコードを見てましょう。


1

<input type="text" v-model="todo"/>


v-modelは、このフィールドに入力された値をtoDoItemというdataオブジェクトのキーに結びつけられます。ページが読み込まれると、toDoItemには「todo: ''」のような空の文字列が設定され、「todo: 'add some text here'」のようなデータが既にある場合は、inputフィールドにテキストを追加して読み込みます。空の文字列に戻ると、inputフィールド内に入力したテキストはtodoの値にバインドされます。これは実質的に、双方向バインディングと同じです(inputフィールドはdataオブジェクトを更新でき、dataオブジェクトはinputフィールドを更新できます)。

createNewToDoItem()コードブロックでは、todoの内容はlistの配列にプッシュされ、todoを空の文字列に更新することが分かります。

アイテムの削除

Reactの場合


1

2

3

4

5

deleteItem = indexToDelete => {

    this.setState(({ list }) => ({

      list: list.filter((toDo, index) => index !== indexToDelete)

    }));

};


deleteItem関数ToDo.jsの中にありますが、ToDoItem.js内の参照を最初に作成することができます。deleteItem関数を<ToDoItem/>のpropとして渡すには次のように書きます。


1

<ToDoItem deleteItem={this.deleteItem.bind(this, key)}/>


このコードではまず、子にアクセスするために関数を渡します。ここではkeyパラメータを渡すだけでなく、thisもバインドしていることが分かります。keyとして、どのToDoItemがクリックされたときに削除しようとしているかを区別するために関数が使用するものがあります。次に、ToDoItemコンポーネント内で、次の処理を行います。


1

<div className=ToDoItem-Delete onClick={this.props.deleteItem}>-</div>


コンポーネント内にある関数を参照するために必要なのは、this.props.deleteItemを参照するだけでした。

Vueの場合


1

2

3

onDeleteItem(todo){

  this.list = this.list.filter(item => item !== todo);

}


Vueの場合では、少し違ったアプローチが必要です。ポイントは、3つあります。

第1に、関数を呼び出す要素を用意します。


1

<div class=ToDoItem-Delete @click=deleteItem(todo)>-</div>


次に、子コンポーネント(この場合はToDoItem.vue)内のメソッドとしてemit関数を作成する必要があります。これは次のようになります。


1

2

3

deleteItem(todo) {

    this.$emit('delete', todo)

}


これに加えて、ToDo.vue内にToDoItem.vueを追加すると、実際に関数を参照することに気づくでしょう


1

2

3

4

<ToDoItem v-for="todo in list"

          :todo="todo"

          @delete="onDeleteItem" // <-- this :)

          :key="todo.id" />


これは、カスタムイベントリスナーと呼ばれるものです「delete」の文字列でemitがトリガされるあらゆる状況で実行されます。イベントが起きると、onDeleteItemという関数が呼び出されます。この関数は、ToDoItem.vueではなくToDo.vue内にあります。この関数は前述のように、dataオブジェクト内のtodo配列フィルタリングして、クリックされたアイテムを削除します。

またVueの場合では、@clickに$emit()を書くだけでも大丈夫です。


1

<div class=ToDoItem-Delete @click=$emit(delete, todo)>-</div>


この記述で工程を減らすことができますが、どちらを採用するかは個人の好みです。

まとめると、Reactでは子コンポーネントはthis.propsを介して親の関数にアクセスします(かなり一般的な方法)。Vueでは親コンポーネント内で通常収集されるイベントを子から送出する必要があります。

イベントリスナーを渡す

Reactの場合

クリックイベントなどのシンプルなイベントリスナーは簡単です。ここでは、TODOリストに新しいアイテムを作成するボタンのクリックイベントを例に取ります。


1

<div className=ToDo-Add onClick={this.createNewToDoItem}>+</div>.


コードは非常に簡単で、onClickにインラインのJavaScriptで処理しているかのように見えます。Vueで説明したように、enterキーが押されるたびにイベントリスナーを設定するのには少し時間がかかりました。下記のように、input要素に記述されたonKeyPressイベントが処理されることを必要としていました。


1

<input type=text onKeyPress={this.handleKeyPress}/>.


この関数はenterキーが押されたことを認識するたびに、createNewToDoItem関数を呼び出します。


1

2

3

4

5

handleKeyPress = (e) => {

if (e.key === Enter) {

this.createNewToDoItem();

}

};


Vueの場合

Vueでは、非常に簡単です。@を使用して、次に実行するイベントリスナーのタイプを記述するだけです。例えば、クリックイベントを加えるには、下記のように書きます。


1

<div class=ToDo-Add @click=createNewToDoItem()>+</div>


注: @clickは、「v-on:click」の省略形です。

Vueのイベントリスナーの良い点は、イベントリスナーが複数回トリガーされないようにする.onceなど、連鎖できることです。また、キーストロークを処理するために特定のイベントリスナーを作成する場合には、いくつかのショートカットがあります。

enterキーが押されたときに、Reactでイベントリスナーを作成して新しいアイテムを作成するのにはかなり時間がかかりました。Vueでは、非常に簡単に書くことができます。


1

<input type=text v-on:keyup.enter=createNewToDoItem/>


コンポーネントにデータを渡す

Reactの場合

Reactの場合では、作成されたポイントで子コンポーネントにpropsを渡します。


1

<ToDoItem key={key} item={todo} />


このコードでは、ToDoItemコンポーネントに2つのpropsが渡されているのを確認できます。これにより、this.propsを介して子コンポーネントでそれらを参照することができます。item.todo propにアクセスするには、単にthis.props.itemを呼び出すだけです。

Vueの場合

Vueの場合では、子コンポーネントが作成された時点でpropsを渡します。


2018-09-05

【悲報】E-girlsさん、新体制になって人気急降下 ライブもガラガラwwwwwwwwwwwww : ラビット速報 19:52

http://rabitsokuhou.2chblog.jp/archives/68732608.html

30歳で漫画を描き始め、連載のためにブロックチェーンを絡めたサービスを個人で開発した話 | Leth -レス- 19:04

<title>30歳で漫画を描き始め、連載のためにブロックチェーンを絡めたサービスを個人で開発した話 | Leth -レス-</title>

30歳で漫画を描き始め、連載のためにブロックチェーンを絡めたサービスを個人で開発した話


SYNTHESIZEという漫画の連載を、自分で作ったサービスLeth(このエントリーを掲載しているサービスそのもの)で始めました。

普段は普通のサラリーマンをしたりしています。3年くらい前まではエンジニアをやっていた気がしますが、色々あって今は仕事でコードは書いていません。

今(2018/9月時点)私は33歳なのですが、29歳の終わり頃でしょうか、ふと「漫画でも描いてみるか」と思い立ってから今日こうして無事公開できるに至るまでの話と、今後の展望の話を書き残しておきます。

動機の話

私は20代の半分程をエンジニアとして過ごしていました。幸いデザインも好きだった事もあり、昔から余暇の時間を利用していくつか個人でサービスをリリースしたりしていました。それまでの人生は音楽づくしであったし、「創作」そのものが好きなんだと自己分析しています。プログラミングも創作の一つだと捉えていますし。絵を描くのも好きでした。

思い返せば私の人生はずっと引きこもりで。土日や長期休暇で旅行や外に出かけることは殆どなく、小さい頃から一貫してずっと家で何かを作ったり、本を読んだり、音楽を聴いたりしながら過ごしていました。大人になってからは、四六時中プログラミングしていたと思います。

30歳が目前に迫ってくる頃に、 総合芸術への憧れ自覚します。音楽も、絵も、プログラミングも、サービス開発も、ゲームも、読書も、どれも夢中でやってきた自分だからこそ、全てを総合してユニークな価値に昇華するのも面白いのではないか?と思うわけです。そこから先は割と短絡的でして、「漫画って総合芸術だよな?やってみるか」くらいの感じで挑戦し始めました。

それまでの人生で、一度たりとも漫画を目指した事がなかったので、まぁやりはじめてから何度か「無謀な挑戦やったな…」という思いが脳裏をよぎりながらも、なんとかこうして発表できるまで至る事ができました。

創作そのものの大変さもあったのですが、30歳前後の人生って色々あるじゃないですか。多分。私の場合は、転職、病気、結婚、黒い砂漠というMMOにドハマリ、などのイベントがパラレルで走りながらの創作だった事もあり、大変だったような気もします。勿論それを上回って楽しいんですがね。

漫画リリースまでの道のり

ド素人がどうやって漫画を学んで描き始めたのか、みたいな話は別エントリーに切り出して書いています。文字数が多すぎるので…。

また今後も一話掲載する毎に、「何に挑戦して何を学んだのか」、を創作ログという形で残していこうと思っています。個人的に何事も体系化していく作業が好きなのもあって、恐らく漫画を描くという行為も体系化出来るのではないかと考えている為です。

こうして書き残した事がいつか誰かの為になればと思います。

SYNTHESIZE 1話目の創作ログ

上記エントリーでも触れていますが、やはり1話目というのは難易度が高く最後の最後まで苦戦しました。それでも納得できない所も多いので、そのうち修正版をアップし直したりすると思います。

Lethリリースまでの道のり

最初は漫画を描く事しか考えてなかったのですが、描いた漫画をストックしたり発表したりする場が欲しい、と思い始めました。

私は「定期連載をしたい」とか「プロになりたい」というモチベーションがあるわけでは無かったので、出版社に持ち込んだりweb漫画プラットフォームで掲載したりするのは少し違うな…と。どちらかと言うと感覚としては 自分のホームページがほしい だったんですね。で、どうせ作るなら誰でも使えるような形にしてリリースしよう、とボンヤリ妄想していました。

漫画を描きながら、上記のような事をふんわりと考えて過ごしてる中で、ふと「そこにブロックチェーン絡めると面白いのでは?」と思いつきます。

今思うとコレにしても、偶然的に生み出されたアイデアというものでもなかったりします。結局の所、ブロックチェーンを絡めようというそのアイデアも私にとっては 総合芸術的 と言えるワケです。

というのも私は以前から、ナカモトサトシ氏の「Bitcoin: A Peer-to-Peer Electronic Cash System」を読んだり、OReillyから出ている「Blockchain: Blueprint for a New Economy」を読んだりする中で、ブロックチェーンそのもに大変興味を持ち、サンプル程度ですがEthereumでコントラクトを書いて遊んだりしていました。中でもBlockchain: Blueprint for a New Economyで語られている(確か…)、「ブロックチェーンがあれば国が創れるぞ!!」みたいな発想に強く感銘を受けていました。

ただ、最初はブロックチェーンでなにかプロダクトを作りたい!という気持ちよりも、単なる知的好奇心から技術に触れていたので、「漫画を描こう」「ホームページを作ろう」「ブロックチェーン面白い」という3つの要素の関連を意識した事は無かったのです。

ところが、前述した通り「ふと」3つが結びついた瞬間があったんですよね。ほんとに、ふと。それが2018年3月だった事と、リビングYoutubeを観ていた瞬間だった事だけを覚えています。

その時のアイデアを速攻でKeynoteに纏め、デザインを起こし、ドメインを取得し、会社に一週間の休暇を申し入れ、一ヶ月程でプロトタイプを完成させました。

その後、ブロックチェーンに関する技術及び法律周り、プロダクトの細部に関するデザイン、インフラ周り、などを周囲の仲間を巻き込んで一緒にワイワイしながら、今に至ります。

途中、react nativeでアプリを作ろうと試み、expoを試したり捨てたりしながら、最終的に「アプリいらなくね?」と思って全てを捨て去ったり、あーでもないこーでもないと楽しく過ごしていると、気づけば9月という感じでした。

一つ想定外だったというか、難しかったポイントとして、初期リリースからブロックチェーンをしっかり組み込んだサービスをリリースしようと考えていたのですが、主に法律周りの制限が厳しく断念しています。ただ、ブロックチェーン要素0だとつまらないな〜と思い、「ETHを送金する」という機能…、まぁ投げ銭のようなモノだけを機能として付けて、ブロックチェーンをやっていく気持ちを表明する形でリリースしています。

今後、法律面、技術面もクリアしながら、しっかりブロックチェーンを取り入れたサービスとして、アップデートしていきたいと思っています。

今後の話

さて今後の話ですが、SYNTHESIZE の方は気長に連載を続けていきたいと思っています。頑張ってアニメ化させたいです。

描けば描くほど成長を実感できるフェーズなので、無限に面白くて。更に「どうして成長したと思えるのか、何を工夫したのか」「失敗したポイントはなにか」などの知見も余すこと無く全てを文章にしてアウトプットし続けたいとも思っています。

更に、もうちょっと連載が進んだ頃に、SYNTHESIZEで作った設定集を全て誰でも再利用可能なライセンスで公開していきたいとも考えています。ま、再利用したくなるくらいの価値があるの?って話はありますがね。その話は追々。

更新頻度は1.5ヶ月に一本程度になりそうです。20ページ前後でしょうか。開発、労働、執筆の三足の草鞋でやっていると、どうにもそれくらいが関の山っぽくて。そのうち「労働」の時間を全て開発と執筆に充てられるようになるのが理想ですが、それもなかなか難しい。

Lethに関しては、「 APIの公開 」と「 ブロックチェーン機能のリリース 」を目標として開発していきます。

まだ確定ではないですが、プロダクトのイシューやロードマップなども公開しながら開発を進めていけたらとも思っています。可能な限り非中央集権的に運営していきたいですね。

最後に

私は平日働いた後の寝るまでの時間、土日の全てを執筆と開発に充てています(時々ゲームをしたりはしますが、それも本気です)。飲みにいく事も少ないし、行ったとしても必ずタクシーで帰り、少しでも創作に充てられる時間と体力を確保するようにしています。

何事も「何かを始めるのに、遅すぎるということは無い」ということを体現しながら生きていけたらと願っています。

「30歳から漫画を描き始める!」といった無謀に思える挑戦でも、しっかり空いた時間をその目標に対して捧げて、且つ効率よく学んでいき、それを継続することが出来ると、案外ある程度のアウトプットは捻り出せるのではないかと、希望的観測かもしれませんが…私はそう考えています。

無闇矢鱈に努力するのではなく、自分の頭で考えて効率的に失敗を繰り返すスキルさえ身につけば、後天的に何にでもなれるのではないか、と。

そんな私やLethの事を応援するよ!という心優しい方がいましたら、「ETHを送金する」ボタンからETHを送って頂いたり、少しでも多くの方にこのエントリーを読んで貰えると嬉しいので、SNS等でシェアして頂けたら、死ぬほど喜びます。

最後まで読んで頂き、ありがとうございました。

なにか連絡したい事がございましたら aohige1979@gmail.com までメール下さい。


関連記事:

SYNTHESIZE 1話目の創作ログ

#ブロックチェーン #web漫画 #SYNTHESIZE #leth

日本のWebデザインで見かける10個の特徴 | コリス 18:54

<title>日本のWebデザインで見かける10個の特徴 | コリス</title>

日本のWebデザインで見かける10個の特徴

UX道場 -UXデザインの基礎知識からUI/Webデザインに役立つ情報、Adobe XDの最新情報まで

ここ数年で、日本のWebデザインは大きく進化しました。

洗練されたデザインといえば、海外のものでしたが、今では日本でも数多く見られます。

デザインのスタイル、芸術的アプローチ、高度なソリューション、そして漢字や縦書きの文字を使ったデザインなど、日本のWebデザインで見かける10個の特徴を紹介します。

サイトのキャプチャサイトのキャプチャ

10 Distinctive Features of Japanese-Style Web Design

下記は各ポイントを意訳したものです。

※当ブログでの翻訳記事は、元サイト様にライセンスを得て翻訳しています。

  • 01. ハイテク演出
  • 02. 他とは異なるソリューション
  • 03. 日本独自の配色
  • 04. 縦書き
  • 05. 自然の風景
  • 06. 巧妙なヒーローエリア
  • 07. アニメに影響を受けたイラスト
  • 08. キャラクター
  • 09. 日本の漢字
  • 10. 日本の伝統的な音

01. ハイテク演出

WebGL、GLSL、GSAPアニメーション、Three.js、Nginxなど、これらのライブラリは日本で開発されたものではありませんが、非常に効果的にこれらのライブラリが使用されています。ユーザーはページを開くと期待に胸をときめかせ、圧倒されたりシステムをクラッシュされたりすることはありません。

大切なのは印象を作ることで、ユーザーが経験を楽しむこととの間に絶妙なバランスが保たれています。

サイトのキャプチャ

Masayuki Daijima

ハイテクの要素は、最初の訪問ページだけではありません。Blues Designでは、プロジェクトを通して洗練されたテクノの雰囲気が醸し出されています。スクロール遷移、ナビゲーション効果、3D回転メニュー、ドラッグ操作など、試してみてください。

サイトのキャプチャ

Blues Design

02. 他とは異なるソリューション

他とは異なるソリューションを見かけると、それがどういったものなのか期待する人は多いでしょう。ここで取り上げたWebサイトは、他に類を見ない素晴らしいアイデアでビジターを惹きつけています。

サイトのキャプチャ

Final Fantasy XV

サイトのキャプチャ

History of the Internet

03. 日本独自の配色

色は日本文化にとって、不可欠な要素です。何世紀もの間、身につけられた豪華な着物を思い浮かべてみてください。着物には信じられないほど、美しい色が使用されています。

デザインで独特な配色を使用するには、色調と色相を組み合わせるのがポイントです。ice cream parlour cosmeticsではグレーがかったピンクと派手なネオンのグリーンで、その美しさを得ています。Republicでは明るいグリーン、ブルー、イエロー、ピンクが使用されています。

サイトのキャプチャ

ice cream parlour cosmetics

サイトのキャプチャ

Republic

04. 縦書き

縦方向のリズムは、日本語の言語表記である縦書きにインスパイアされています。縦書きは伝統的なスタイルで、縦方向に文字が書かれるフォーマットです。寒川神社や鮨 みつ川のサイトで、この縦方向のリズムが効果的に使用されています。また、この縦書きの文字は世界的にもトレンド兆しがあります。

サイトのキャプチャ

寒川神社

サイトのキャプチャ

鮨 みつ川

05. 自然の風景

日本のWebサイトの多くで、自然が使用されています。福田茶屋では自然が絵画のように美しく使用されており、クリックしたくなる人も多いでしょう。TAJI MAJIのトップにある素晴らしい花のイラストもビジターの目を惹きつけます。

サイトのキャプチャ

福田茶屋

サイトのキャプチャ

TAJI MAJI

06. 巧妙なヒーローエリア

ここまで取り上げてきた日本のWebデザインでは、ヒーローエリアが本当に魅力的であることを明らかにしました。ここで紹介するのは、自然の美しさと技術の競演で生み出されており、クリエイティティを刺激します。

サイトのキャプチャ

Yuto Takahashi

サイトのキャプチャ

CRAZY

07. アニメに影響を受けたイラスト

アニメに影響を受けたイラストに触れない訳にはいきません。スタジオジブリの信じられないほど才能のあるアニメーターによって再現されたファンタジーの世界を魅了するすべてを覚えていますか? アニメだけでなく、マンガ、コミックは、日本のポップカルチャーの特徴的な要素です。

文字や音楽も忘れないようにしましょう。他のアジア圏内と区別させることができます。

サイトのキャプチャ

Kuon Yagi

08. キャラクター

最初に頭に浮かぶのは、長い髪と大きな目を持つ女の子が登場する古典的なマンガですが、デザインスタイルははるかに多様です。ガラフルでは、かわいい女性キャラクターがいくつか見つかり、セーラームーンとは何の共通点もありません。ポケモンが好きな人には、SHAKE DE 福笑いの背景にいるキャラクターも好きになるかもしれません。

サイトのキャプチャ

ガラフル

サイトのキャプチャ

SHAKE DE 福笑い

09. 日本の漢字

漢字なしで、日本のWebサイトをイメージするのは難しいと言えるでしょう。オカキンでは、言語を英語に切り替える時でさえ、日本語の文字に遭遇する可能性があります。文字は情報を伝達するためだけではなく、運や繁栄や幸福をもたらすと考えられるので、プロジェクトのより精神的な側面を反映します。

サイトのキャプチャ

オカキン

10. 日本の伝統的な音

音・サウンドを使用したWebサイトは、もう珍しいものではなくなりました。数年間には音楽を流しているサイトがあり、それらは現在でもまだ需要があります。

Omikuji Machineでは日本の伝統的な音をユーザエクスペリエンスのために使用しています。美しい音は、Webサイトに不可欠なものです。

サイトのキャプチャ

Omikuji Machine

初心者でもDB設計やデータモデリングについて学べる7つのサイトと本 - paiza開発日誌 07:35

<title>初心者でもDB設計やデータモデリングについて学べる7つのサイトと本 - paiza開発日誌</title>

■新入社員必読、データベースの基本を理解しよう

<header style="max-width: 100%;">

初心者でもDB設計やデータモデリングについて学べる7つのサイトと本






</header>

f:id:paiza:20180903185841j:plain

Photo by

こんにちは。谷口です。

SQLは何となく書けるけど、DB設計はしたことない…」「DB設計について一度ちゃんと学んでおきたい…」という人は多いですよね。

DB設計とは、DBのデータモデル(DBの構成など)を作成する作業です。

DBを一から作ったり、テーブルを追加したりする際は、当然ですが「今あるデータが何となく格納できればそれでOK」ではありません。

テーブルは正規化できていないといけませんし、データの整合性も取れないといけません。また、効率よくデータが取れる構造になっているかどうかも重要です。

一から設計に取りかかるようなケースは少ないかもしれませんが、DBを取り扱うことがあるなら、こうしたDB設計の基本は知っておいて損はありません。むしろ自分が扱うDBの構造はきちんと知っておかないと、「なんか適当にSQL投げたらデータ取れたけど、正しく取れてるのかどうかよくわかんないな」というふうにブラックボックス化してしまいます。

DB設計の基本を学んでおくと、サービス内容や開発言語にかかわらず、役に立つ知識となるはずです。

そこで今回は、DB設計について学べるサイトと書籍をご紹介します。

f:id:paiza:20180903152125j:plain

書き込みSQLのドリル 』の作者の方による日経XTECHの連載記事です。DB入門者向けに、書籍から抜粋された内容が掲載されています。

もちろんDBについてさらに詳しく知りたい人やSQL練習をしたい人は、『書き込みSQLのドリル 』を読んでみるのもおすすめです。

初めてのデータベース設計

f:id:paiza:20180903152838j:plain

こちらもDB入門者向けな技術評論社の連載記事です。データベース設計の全体的な流れから説明があります。

達人に学ぶSQL

f:id:paiza:20180903184444j:plain

CodeZineの連載記事です。記事自体は無料で読めますが、加筆・再編集された書籍『達人に学ぶ SQL徹底指南書』のほうが実例豊富でわかりやすくておすすめです。

■達人に学ぶ SQL徹底指南書

達人に学ぶ SQL徹底指南書 (CodeZine BOOKS)

なお、初心者を抜け出したい人や中級者向けの内容になってはいますが、さらに詳しくDBについて学びたい人には、続編の『達人に学ぶDB設計 徹底指南書 初級者で終わりたくないあなたへ』もおすすめです。

SQLアンチパターン

SQLアンチパターン

SQLの記述方法だけでなく、DB設計の段階から、様々な場面で陥りやすいアンチパターンについて解説されています。アンチパターンというのは「やってはいけない、避けたいパターン」ということです。知らないとついついやってしまうアンチパターンですが、「なぜやってしまうのか、どうすれば防げるのか」がわかりやすく書かれています。

DB設計の経験がある人向けの書籍だとは思いますが、DBを使うことになった新人の人にもおすすめです。

■まとめ

前述の通り、DB設計の基本はサービス内容や開発言語にかかわらず役に立つ知識です。

DBを取り扱うようになると「そうだ、SQL学ぼう」とはなると思いますが、DB設計についても勉強しておいて損はありません。

ちなみにSQLに関しては、paizaラーニングで「DB/SQL入門編」というレッスンも公開しています。

SQLのオンライン実行環境と構築済みのデータベースが用意されているので、面倒な環境構築やデータベースの準備などをしなくても、動画と演習問題を通して楽しくSQLの使い方が学べます。

このように、自分で手を動かして実際のSQL文を打ち込んでみたり、結果を確認したりできます。

paizaラーニングの「DB/SQL入門編」について、詳しくはこちら





paizaラーニング」では、未経験者でもブラウザさえあれば、今すぐプログラミングの基礎が動画で学べるレッスンを多数公開しております。

詳しくはこちら

paizaラーニング

そしてpaizaでは、Webサービス開発企業などで求められるコーディング力や、テストケースを想定する力などが問われるプログラミングスキルチェック問題も提供しています。

スキルチェックに挑戦した人は、その結果によってS・A・B・C・D・Eの6段階のランクを取得できます。必要なスキルランクを取得すれば、書類選考なしで企業の求人に応募することも可能です。「自分のプログラミングスキル客観的に知りたい」「スキルを使って転職したい」という方は、ぜひチャレンジしてみてください。

詳しくはこちら

paizaのスキルチェック

2018-09-03

Basics_of_DNS_that_application_engineers_should_know - Speaker Deck 07:46

https://speakerdeck.com/mamy1326/basics-of-dns-that-application-engineers-should-know-1

井戸落とし穴、家、果ては“海”まで なんでも武器になるRPG「ぶきあつめ」がなんでも過ぎて腹筋崩壊 - ねとらぼ 07:46

<title>井戸落とし穴、家、果ては“海”まで なんでも武器になるRPG「ぶきあつめ」がなんでも過ぎて腹筋崩壊 - ねとらぼ</title>

井戸落とし穴、家、果ては“海”まで なんでも武器になるRPG「ぶきあつめ」がなんでも過ぎて腹筋崩壊

RPG史上屈指のカオス度。何が起きても動じない心持ちでどうぞ。

ニュース






 niconicoRPGアツマールで公開されたフリーゲーム「ぶきあつめ 〜なんでも武器になるRPG〜」がシンプルなタイトルに反して内容が狂いに狂っているとさまざまなジャンルのゲームファンから注目を集めています。「なんでもといったな? でもこれは無理だろ」と思ってゲームを始めると、その“なんでも”ぶりに土下座して許しを請うことになります。看板に偽りなし……。




 ストーリーは、武器屋の主人公が世界のどこかに存在するという最強の武器「ツヨスギテ=クサハエル・ソード」を探すたびに出るという大変シンプルなもの。しかし、ゲーム開始と同時に、このゲームの狂気が一端をのぞかせます。

 スライムに囲まれてしまった主人公「うぇ子」は、「何でも武器にして戦う……それが真の武器商人だ!!」という亡き父の言葉を思い出し、取りあえず周辺にあるものを武器にして戦います。まずは道端に落ちているスコップの前で武器を拾うボタン押すと、武器にできました。さらに、近くにあった「ツボ」も武器にできるもよう。
























 なるほどこれは面白い、と思いさらに茂みにある謎の白骨死体を調べてみると、「しかばね」が“武器”として拾えました。んん……?




 なかなか大胆だな……と思いそのへんに生えている木を調べてみると、木を引っこ抜いて武器として取得。いやいやいや。




 予想以上に何でも拾えるので武器を拾うボタンを連打しながら歩いてみると、茂みに入った瞬間「草むら」を拾いました。いやそれ一個の物体じゃねえぞ!








 さらに連打しながら歩いていると、「道」を取得。拾ったあとには雑草が生い茂っていました。逆じゃね!?




 こうなってくると、普通はゲーム的に「この先に進めない」ことを示すために置かれる高い崖に目が行きます。いや、流石にこれは……まさかそんな……拾えちゃったよ。崖、拾えちゃったよ。崖を拾うってなんだ……?












 あっけにとられながらスライムたちの方に進むと、画面左に池が見えます。こればっかりは……いくらなんでも……拾えた。「蓮の池」を“武器”として取得。さっきまで池があったはずの場所は、雑草が生い茂っています。このゲーム、想像の3万倍は狂ってやがる。








 とりあえず武器は十分すぎるほど補充できたので、戦闘へ。ゲームシステム的にはいわゆる「ローグライク」や「不思議のダンジョン」系になっており、こちらが1歩動くと敵も1歩動くようになっています。

 今回は、とりえあず「蓮の池」を使ってスライムを攻撃。巨大な池をそのまま振り回す「うぇ子」。死ぬほど画面が見づらいですが、「前方6マス同時攻撃というローグライクゲームにあるまじき攻撃範囲」+「池の氾濫で前方3マスに追加ダメージ」による超性能でスライムを圧倒していきます。「蓮の池」つええぇぇっ!




 あっという間にスライムたちを圧倒した「うぇ子」は、無事街に帰還。ここから自由行動になるのですが、開始10秒でフリーダムだった世界はさらに無法地帯に。お手伝いや薬草の販売をしてくれる妹の「ぽん美」に向かって武器を振り回してみたところ、普通に命中。妹はアイテムをドロップしながら即死しました。ぽ、ぽん美ぃぃ! 「うぇ子は3の経験値を手に入れた!」じゃねぇぇ!!




 さらに、家の中にある家具や、商品の販売に使う長机、キッチン、椅子、本棚など全て武器として持ち出し可能。それどころか、自宅やそこら辺にある民家そのものを“武器”として持っていける徹底ぶりです。





RPGアツマール 武器集め

タップで拡大

“武器”を回収していくとこんなことに。床も剥がせます






 しかも家を持ち出すと、本来扉から入ると別のマップとしてつながっている家の中や住人が町マップの一部として表示されるようになるというこだわりぶり。この辺でだんだんと、「ああ、このゲームは全てが狂っているんだなぁ」と気付き始めてくるはずです。








 さらに、町の住民は全員攻撃可能となっており、ご近所さんたちをぶっ飛ばしてレベル上げも可能。たまに貴重品もドロップするようなので、やらない手はありません。近所の家を武器としてもぎ取り、中の住人をさっきまで住んでいた家でぶっ飛ばしましょう。他人の家のタンスを勝手に荒らすドラクエの主人公が聖人に見えてきました。

 狂気はこれだけにとどまらず、モンスターや町の住民はHPを減らすと“武器”として獲得。さらに、あらゆる武器を自宅で商品として並べられるため、住人を売ってお金に変換もできます。「うぇ子」に拾われてしまったが最後、もはやそこに人格は認められず、“武器”という記号として扱われるのみです。












 なお、ご近所さんは一度町に出入りすれば復活しますし、家や家具などは耐久度が0になって壊れると元の場所に復活するようになっているので、特に気にする必要もありません。好き放題町を荒らし回りましょう。ただ、商品として売れた人は消えたまま帰ってくる様子がありません。完全消滅した……?

 また、拾える武器の性能も面白く、「ガスコンロ」なら物理ダメージ+前方に炎の追加攻撃判定が発生したり、「しかばね」は5%の即死効果があったりと、それぞれ内容に沿った効果が付与されています。剣や斧といった普通の武器も存在しますが、少なくとも序盤はその辺のオブジェで殴るほうが効率的なもよう。

RPGアツマール 武器集め

タップで拡大

“武器”は内容に即した特殊能力が付与されています


 ただし、序盤からこういった強力な武器が手に入るだけに、敵も最初から強め。油断していると、序盤でもサクサク死にます。こまめなセーブを心がけましょう。

 なお、現在Twitterでは、「海」を武器として拾うシーンが大きな話題になっています。筆者はまだそこまで進めていませんが、進むほど信じられないものが拾えるようになっていくもよう。


 なんでもありなカオスぶり+ローグライクが合わさったこの怪作、久々に「すごいゲームが出てきたなあ」と思わせてくれます。実際なかなか面白いので、一度プレイしてみてほしい一作でした。


































前の記事

「もう20年早く知りたかった」 簡単にできるピーマンの種のとり方が便利だと話題に

次の記事

スパイラルノート「使いにくい」しずく型のおたま「ムリゲー」 左利きあるある”描いたイラストに共感集まる










Copyright © ITmedia, Inc. All Rights Reserved.