Runner in the High

技術のことをかくこころみ

D言語でstd.signalsを使ったオブザーバー実装

std.signalsというモジュールを使うとオブザーバー・パターンの実装が簡単にできる。 この例ではひとつのオブザーバーしか登録していないが、複数のオブザーバーを登録した上で一気にシグナルを発行できる。

dlang.org

import std.signals;
import std.stdio;

enum SignalTypes {
  INCREASE,
  DECREASE
};

class SignalObserver {
  private int signalCounter;

  this() {
    signalCounter = 0;
  }

  void watch(SignalTypes type) {
    switch (type) {
      case SignalTypes.INCREASE: signalCounter++; break;
      case SignalTypes.DECREASE: signalCounter--; break;
      default: break;
    }
  }

  @property int counter() const {
    return signalCounter;
  }
}

class SignalTrigger {
  void update(SignalTypes type) {
    emit(type);
  }

  mixin Signal!(SignalTypes);
}

__gshared SignalTrigger trigger = new SignalTrigger();
__gshared SignalObserver observer = new SignalObserver();

void main() {
  trigger.connect(&observer.watch);

  trigger.update(SignalTypes.INCREASE);
  trigger.update(SignalTypes.INCREASE);
  trigger.update(SignalTypes.INCREASE);

  writeln(observer.counter); // 3

  trigger.update(SignalTypes.DECREASE);
  trigger.update(SignalTypes.DECREASE);

  writeln(observer.counter); // 1
}

D言語でCtrl-Cのシグナルハンドラを登録する

whileループからCtrl-Cで抜ける処理を横取りしたいときに。

import std.stdio;
import core.thread;
import core.stdc.stdlib;
import core.sys.posix.signal;

extern (C) {
  void cleanup(int signal) {
    writeln("cleanup");
    exit(1);
  }
}

void main() {
  sigset(SIGINT, &cleanup);

  while (true) {
    writeln("waiting...");
    Thread.sleep(dur!("seconds")(1));
  }
}

ポイントはクリーンナップコードをextern (C) { ... }の中で定義することと、integer型の引数を与えること。 SIGINT以外にもいろいろハンドラが登録できるっぽい。ちなみにちゃんとexitしないと、killコマンドで殺さないといけなくなるので注意。

github.com

10月にしたLTまとめ

 唐突に、この10月にした4つのLTに関して振り返ってみようと思う。

 これまで自分は勉強会などでいわゆるライトニング・トークというものをしたことがなかったが、内定先の師匠と話をしていてちょっと試しにやってみるのも悪くはないなと思い始めたのがきっかけだった。仮になにかテキトウなことをLTの中で話してしまったとしても、まさか命までは取られまい、という思いでえいやとやってみようと思ったのだ。

Meguro.rb #7

 これはちょうど直近で参加できそうなRubyの勉強会を探していて、初めて参加したMeguro.rbでのLT。
 ROMと呼ばれるヘキサゴナル・アーキテクチャで実装されたデータ・マッパー・パターンの永続レイヤのライブラリについて話した。普段は僕もRailsActiveRecordをガンガンに使っているが、ドメインモデルと永続化の責務を分割したいと思うならROMという選択肢も充分にありえるのではないかと思う。ROMの思想を一番よく表しているのが、永続化レイヤをDBだけのものとして考えず、WebAPIへのリクエストなども永続化の責務としてアダプタブルにできるものとして扱う、という点で、レイヤード・アーキテクチャが好きな僕としてはとても感動した。
 これが人生で初めてのLTだったので、割と早めに資料を作ってちょいちょい練習っぽいこともした。何事も初めてであれば練習をしすぎるということはない。参加者のひとたちも、発表が終わったあとに話しかけてくれたりして、初めてのLTとしてはいいスタートを切れたと思う。

WEBエンジニア勉強会 #3

 WEBエンジニア勉強会も、connpassで何かLTができそうな手頃な勉強会がないかなと探していたときに見つけた勉強会のひとつだ。この第三回目は新橋のコワーキングスペースで開催された。
 このスライドは、フロントエンド・アプリケーションにおけるバリデーション・ロジックの責務をどこにおくのか、という問題提起をしてみたくて作ったスライドだ。基本的に、フロントエンドのバリデーションというと、ビュー側に意識が寄ってしまうことが多い。なぜなら、バリデーションというのは、バリデーション自体のロジックと、そのエラーの表示というものがワンセットになっていると考えがちだからだ。だが、アプリケーションの種類問わず、バリデーションというのはビジネス・ルール含むことが多く、基本的に「バリデーションを実行する」という責務はドメイン・レイヤに置き、「バリデーションのエラーを表示する」という責務のみをビューに置くのが最適解なのではないかと僕は考えている。
 そのような趣旨でこのスライドを作ってはみたものの、実際に勉強会に来てくれているひとたちのなかにフロントエンド開発をしている人がさほど多くなかったので、次回からはもう少し勉強会に併せて話す内容を工夫したほうがいいかもな、という反省を得た。

 ちなみにではあるが、上のスライドで登場するvalidatable-recordはnpmで公開してある

www.npmjs.com

izumisy-tech.hatenablog.com

第12回若手Webエンジニア交流会

 知り合いのiOSエンジニアが主催していた勉強会を偶然connpassで見つけたのでここもLT枠で突撃した。仰々しいタイトルだが、僕のスタックオーバーフローのREPは500程度しかない。この勉強会は開会と同時に飲酒開始なので、LTも非常に気持ちよく話せてとてもエキサイトした。発表が終わったあと、すごくおもしろかった!的な声を数人から頂いて、やはり「トピックx話し方」でLTのウケは結構変わるんだな〜とも思った。あと酒を飲むと非常に饒舌になれるので、シャイな自分はあらかじめ酒をちょっと入れておくというイイということを学んだ。
 このスライドはもともと、僕が今年に入ってからスタックオーバーフローでいくつか回答をし始めて、思ったよりもREP稼ぐハードルって高くないんだな!と思ったところからアイデアを得た。スタックオーバーフローというと外国のすごそうなエンジニアがじゃぶじゃぶいるようなイメージだが、実際には我々日本人の英語力であれば全くコミュニティに貢献できること間違いなしだ。僕でもできるからみんなでやろう、という意気込みをぶつけるスライドだ。
 ちなみに参加者の中にJapanese Languageで4000REPくらいもっているという人がいて、ヒエ〜となった。是非そういう人からより具体的なREP稼ぎのノウハウを聞いてみたいものだ。

第33回 PORTもくもく会

 おととしのインターンで知り合った三人でちょっとした開発チームのようなものを組んでいるので、僕含めその三人でLTをしようとこのもくもく会に参加。会場は新宿にあるでっかいビルだった。
 これまでの勉強会と比べて集まっている人たちがほんとに様々で、Vimプラグインをめっちゃ作っている人や、Rubocopのコントリビューター、自分の本を書いている人、などなど思ったより幅広かった。そこで僕がしたLTがchooというウェブ・フロントエンド・フレームワークに関するものだったが、そもそもまたフロントエンドを触っている人がそんなにいないということもあり、ウケが微妙だった。
 このLTでchooを取り上げた理由は、chooはフロントエンド・フレームワークの中でも関数型プログラミングの雰囲気を持つように設計されていて、いわゆるVue.jsやReactで言うところのコンポーネントが、chooにおいては純粋なDOMを返す状態を持たない関数となるように実装できるというところが好みだったからだ。
 フロントエンドにおける「状態」はもはやコンポーネント単位のステートという形で責務分けするのではなく、ビューから切り離された状態というそれ自体の責務になるほうが、スケーラビリティがある。この考え方をすれば、そもそもビューを「ステート→DOM」の単なる変換に専念させられるし、ビューとステートが密結合になりづらくなる。なお、この話関しては別の記事で書いたのでこちらを参照のこと。

izumisy-tech.hatenablog.com

4回LTしてみて

 LTをする前は、まだまだ僕には話せることなんてそんなにないと思っていたけれども、実際にLTに申し込んでスライドを作り始めると、思った以上に話すことがでてきたり、なにより人前でマイクを持って話すのがわりと興奮(?)したりするということが分かった。Twitterで誰かが、「まずLTに申し込む。アイデアはあとからでてくる。」と言っていたのを思い出して、ん〜たしかにそのとおりだった、と思う。
 とはいえ、勉強会によっては参加者の層的にあんまりLTの内容が伝わらなかったりすることがあるので、そういう点でもみんながわかりやすい/共感しやすいLTがこれからはできていけたらいいなという所存。いつかはでっかいカンファレンスとかで発表ができるといいな。

10月のOneTapBUY

 先月書いていたOneTapBUYに関する記事から少し評価額で変化が合ったのでちょろっとだけ記事にしようと思う

f:id:IzumiSy:20171026181216p:plain:w300

 前の段階では3000くらいの利益だったが、とうとう10000を切り始めた。投資額から見てこの伸び幅がすごいのかすごくないのかはわからないが、12万で1万の利益が出るような金融商品はあまり他にはなさそうなので、これはこれでいいパフォーマンスだと思う。とはいえ僕個人は株のプロフェッショナルでもなんでもないので、とりあえず「伸びがありそうな株」と「配当がそこそこでそうな株」の2軸だけに絞ってVISA, XEROX, INTELの3つに投資している。VISAは長期的に見て必ず上がり続ける株のようなので、配当は関係なくとりあえずだらだらと長期的な保有を考えている。

 とはいえ、おそらくOneTapBUYで選べる株式のほとんどどれもが、長期的に持っていればこれくらいのパフォーマンスをだすものなんではないかな、と思う。それは、OTB指数というもののパフォーマンスで分かる。

onetapbuy.hatenablog.com

 余談だが、つい最近クラウドバンクも始めた。いまのところ投資額はOneTapBUYと同じくらいだが、パフォーマンスで言うと年6〜7%といったところらしく、さほどリスキーではなさそうな利幅でよろしいと思う。こちらもどういう風にお金が増えるのか楽しみだ。

SAMパターンの大雑把な理解

 SAMパターンというのを勉強している。

www.infoq.com

 この記事は少しだけはてブでバズったが、実際コレを読んだだけでは例えば実際に実装に落としたときにどういうデータ・フローになるのか、というところまでは若干理解しづらい。この記事の作者のDubrayはsam.js.orgでいろんなサンプルコードを紹介しているので、それらを参照すると若干理解が捗る。

 ちなみに今のところ自分の中で整理しきれた雑なSAMのデータ・フローはこれ。

f:id:IzumiSy:20171014171004j:plain

 パッと見の雰囲気はFluxアーキテクチャと全く違う、という感じではない。SAMはState-Action-Modelのアクロニムで、ベースになるのもその3つの要素だ。それぞれの要素の名前はこれまでのアーキテクチャを知っている人からすると、比較的馴染みやすいものではあるかと思うが、SAMの場合はそれぞれが担う責務が若干異なる。なので、たとえばStateと聞いたときにそれが何を意味するのかというのは、既存のアーキテクチャの考え方からではなく、SAM独自の考え方から理解するのがよい。

 ということで、SAMにおける主要な3つの要素に焦点をあてて、sam.js.orgでの解説を元に、簡単な責務の説明をしてみたいと思う。

Model

 SAMにおけるModelとは、Actionから受け取った計算結果を保持し、それをビューに反映させるトリガを提供するだけの存在だ。すなわち、ここにはドメインロジックなどは一切入り込まない。

The model contains all the application state and (logically) exposes a single method: present(data)

 上のデータ・フロー図ではModelの中にPresentという関数がいるが、これがModelの唯一持つ関数としての責務だ。Presentが行う大きな責務は、フロントエンド・アプリケーションで言うところのレンダリング処理のトリガだ。現在の状態を元に、ビューに状態を反映させるトリガをキックする。また、そこで使われる「現在の状態」は全てModelが持っている。

The model is also solely responsible for the persistence of the application state.

 加えて、この説明が示すように、Modelはデータの保持の責務(Fluxで言うところのストア)も持っている。SAMは単なるアーキテクチャのため「メモリに載せる」「localStorageを使う」などの、どう永続化するかという「方法」の点では一切の言及がない。この責務をどう実装するかという点は自由だ。

Action

 SAMにおけるアクションは、データを受け取り、そのデータをもとに実行したビジネスロジックの結果をModelへPresentを介して送りこむ関数だ。Actionのトリガはビューと、後述するNAPによって行われる。

Actions are responsible for implementing context specific logic.

 SAMパターンにおいて、Actionとはドメインモデルに対する操作を行う場所だが、実際にここをどう実装するかに対する方針はSAMでは言及されていない。再利用可能なドメインモデルに具体的な操作は委譲し、ここではそれらのビジネスルールを用いて得られる結果のみをモデルに対して送るというのがおそらく良いかと思われる。

In the context of SAM, actions play another important role with respect to invoking 3rd party APIs.

 加えて、ActionはAPIコールなどを行う場所でもある。

State

the State does not hold any “state”, it is a pure function which computes the view and the next-action predicate, both from the model property values.

 SAMにおけるStateはFluxアーキテクチャのそれとは異なる。Reduxを使っている人なら、Stateと聞くとストアの中にあるデータ構造のことをイメージするかもしれないが、SAMの場合にはStateの具体的な責務は、Modelが保持しているデータ構造と、ビューで必要とされるデータ構造間のインピーダンス・ミスマッチの解消に近い。StateはModelから受け取ったデータを元にビューで必要となるデータに変換を行う関数でしかない。

the State is responsible for invoking the next-action predicate (nap)

 NAPはNext-Action-Predicateのアクロニムで、Stateが持つもう一つの責務を指すもの。これは、見方を変えればStateの副作用だ。NAPは現在のModelの状態から、次にトリガされる必要のあるActionを呼び出す。sam.js.orgのStateセクションでは、ロケット発射台のプログラムが例になっている。ロケットのカウントダウン・カウンタを減算していくActionがあり、そのアクションによってカウンタが0になったとき、Modelの状態を見て自動的にロケット発射のActionをトリガする。

 NAPの利点は、ビューを単なるStateの写像にするために、特定条件下でトリガされるアクションの条件分岐という責務をビューから取り払うことができるという点だ。Fluxアーキテクチャにおいて、Actionの発火元は常にビューだったため、例えばswitch文で記述される状態に関連したアクションの発火(たとえば状態を見てナビゲーターによって遷移を起こさせるなどのロジック)をビューに記述していく必要があった。これは場合によってはビューの肥大化につながることもあるが、SAMはNAPによってビューからそのような責務を分離している。

まとめ

 SAMパターンが最も意図しているところは簡単で、ビューがアプリケーション全体に影響を及ぼすことがないようにしよう! というだけのことだ。そのために様々なMVCやらMVVMやらが考案されてきたが、SAMはより関数型のアプローチをしようとしているアーキテクチャだということが分かる。ほとんど日本語の資料がないので、少しづつSAMの公式ページを読んでいくしか今のところ学ぶ手段はないが、それでも充分読んで見る価値がある。

 また、大事なことはSAMというフレームワークやライブラリがある、ということではないということだ。つまり、SAMというアーキテクチャに関して、どう実装するかは十人十色だ。実装にReactを使うのか、それともChooかVanillaJSか、という点はSAMにおいてはまったく重要ではない。大事なのはアーキテクチャとしての考え方だ。

 とはいえ、InfoQで掲載された記事についているぶコメは、記事を読んでそうに見えて、いくつかはあんまり関係のないものがあった。「サンプルコードでXSSできるから微妙なのでRedux使っとこう」「ナマのJSで良いという主張だということが分かった」「htmlを文字列連結で書くなんて」というあたりのコメントだが、これはおそらくアーキテクチャ自体ではなく、それを実現するために使う言語やツール、すなわち「手段」に関して興味が寄りすぎている。

 手段それ自体への興味はとても良いが、あまりにそこへ指向の比重が寄りすぎてしまうと、どうしても手段が設計に影響を及ぼしかねない。アプリケーションを作るにあたって、手段がなにかを規定してしまうのは大抵の場合よくない。技術をやっていると、どうしてもそこが面白くなってしまうことが多いが、一歩身を引いて設計という観点からものを見直すというのは、いつでも重要なのではないかと思う。

Yeomanに代わるNode.jsのスキャフォルディングツール4選

 ハッカソンや個人開発でよく使う自分でこしらえたアプリケーションのスケルトン・コードをGithubに置いて、それを気軽にスキャフォルディングしたい。こんな欲求はだれしもあると思う。スキャフォルディング・ツールの王道といえばYeomanだが、ちょっとYeomanは...という人は少なくない。ということで、今回の記事では、Yeomanの代替になるような、Node.js製のスキャフォルディング・ツールを紹介しよう。

khaos

f:id:IzumiSy:20171012230404p:plain:w500

GitHub - segmentio/khaos: A super-simple way to scaffold new projects.

  • segment.ioが作っていたシンプルなGithubレポジトリベースのスキャフォルディングツール
  • 機能が小さく纏まっており、マスタッシュ記法をサポートするスキャフォルディングができる
  • テンプレート中のマスタッシュから、CLIが勝手に入力項目を指示してくれるので、設定ファイルなどが不要。
  • ほぼメンテされてないっぽいのが気になる

slush

f:id:IzumiSy:20171012230712p:plain:w150

GitHub - slushjs/slush: The streaming scaffolding system - Gulp as a replacement for Yeoman

  • gulpを内部で使っているYeomanの代替を目指した大型スキャフォルディングツール
  • http://slushjs.github.io/generatorsに使えるテンプレートがリスティングされている
  • テンプレートになるslush-xxxというnpmをグローバルにインストールしないといけないのがちょっとイヤ
  • プロジェクト生成時に新しいディレクトリを作ってくれないという罠がある(これはいいのか?)
  • 使い勝手は(おそらく)Yeomanと近い。

pollinate

f:id:IzumiSy:20171012231207p:plain:w400

GitHub - howardroark/pollinate: Template your base files and generate new projects from Git(Hub).

  • この中でもわりとイチオシのGithubレポジトリベースのスキャフォルディングツール
  • 機能的にはsegment.ioのkhaosと近いが、こちらのほうが高機能
  • template.jsonというファイルをテンプレートのレポジトリに配置することで、スキャフォルディング時に無視するファイルや、ファイルのリネームなどができる
  • シンプルながら、汎用性が高くてよい◎

degit

GitHub - Rich-Harris/degit: Straightforward project scaffolding

  • マスタッシュ記法によるテンプレート化などを一切サポートしないGithubベースのスキャフォルディングツール
  • クローンせず、ただレポジトリをダウンロードするだけなので非常に高速
  • 作者「git clone --depth 1でもいいけど.gitディレクトリがついてきたりするから、こっちのが良いぜ」
  • テンプレート化とかとにかく考えないでリポジトリをスケルトンとしてつかうんや!みたいな用途には最適っぽい

(番外編) cooking

f:id:IzumiSy:20171012231647p:plain:w170

cooking - 更易上手的前端构建工具

  • 毛色が違うがslushのテンプレートを探していて見つけたので最後に紹介
  • webpackを使うフロントエンド・アプリケーションの開発に特化したスキャフォルディングツール
  • slushのテンプレートを検索していると、slush-cooking-xxxというのがでてくるが、それがcookingのテンプレート
  • cooking initを実行するとデフォルトでslush-cooking-vueが指定されたり、ナチュラルに中国語が出てきたりするので挙動がよくわからないときがあるが、そのあたりさえ割り切れればわりと使いやすそうな雰囲気がある

まとめ

  • おそらくこの中で使うならdegitとpollinate
  • 特にpollinateは機能面ですごく申し分ないし、それにロゴも緑のエコロジーな感じで○
  • プライベート・リポジトリ対応などは調べていないが、どのツールもあまり望めないと思われる

Reactの優位性は関数っぽいアプローチができるところなのではないかと思う

 何が言いたいのかというと、Vue.js, React, Angularなどここ最近のフロントエンド界隈を賑わせているフレームワークはたくさんあるけれども、その中でビューレイヤという責務に対して最も薄いアプローチをしているのがReactで、もっとも関数らしい副作用のないアプローチができるんではないかなと思ったということだ。僕自身、よっぽどPerformance-consiousなウェブ・アプリケーションを作るのでもない限り、フロントエンド・フレームワーク最強論議はすごくナンセンスだと思っていたけれどアーキテクチャの観点から考えるのであればフロントエンド・フレームワークの良し悪しが出てくるのは比較的意味のあるものではないかと感じる。

 僕はフロントエンド・アプリケーションにおけるビューをV=Component(State)のように考えている。この数式臭いものが表すのは、コンポーネントはステートを食ってビューを返すだけの純粋な関数だというところだ。アプリケーションにはFlux実装のようなビューレイヤ以外の責務*1が常に存在することを前提にしているが、よっぽどペライチのウェブサイトを作るでもない限り、とりわけSPAであればアプリケーションにおけるデータ管理の責務はもはやビューに置くには適さないと考えているからだ。

 つまり、ステートはすべてFluxアーキテクチャの上で管理し、コンポーネントはビューを作るだけに専念させたい。ビューとは純粋な関数だ。ステートを受け取り、HTML(JSX)を返す。このアプローチができる最近のナウいフレームワークはReactなのではないかと思う。たとえば、ReactではReact.SFCというのがTypeScriptで使える。うれしい。

interface Greeter {
  name: string;
}

const GreeterComponent: React.SFC<Greeter> = ({ name }) => {
  return (
    <div>Hello! {name}</div>
  )
}

React Stateless Functional Component with TypeScript

 このような関数っぽいアプローチを優れた点は、まず副作用が少なく安全だったり、テストしやすいということだ。そして、コンポーネントがステートを持つことができるというReact.Component継承クラスのコンポーネント定義をやめることで、常にステートはコンポーネントと別責務として考えることができる。「ここのコンポーネントのステートは他のコンポーネントで使っていないのでローカルにします」「いやいや...」みたいな議論をするのをやめて、ステートは常に決まった場所で管理しようという方針立てにつながる。つまり、コンポーネントはステート管理の場所ではなくなり、あくまで「ステートの写像*2でしかなくなる。

 「コンポーネント・ライフサイクル・ハンドラが無いんだけど、それが絡む処理はどう書けばええねん??」という話もでてくるだろう。けれど、コンポーネント・ライフサイクルに頼るべき処理が必要になるということは、おそらくコンポーネントのなかでステート管理をしようとしている可能性が高い。コンポーネント・ライフサイクルは見方を変えればコンポーネント内にあるローカル・ステートの変更検知だ。これはコンポーネントの中でステート管理をしているということと限りなく近い。純粋な関数としてDOMのレンダリングのみにフォーカスするコンポーネントはこうしたステート管理とは切り離して考える必要がある。

 さて、これをやるだけなら実際jsrenderyo-yoHandlbars.jsとかでええやんけ、という話もありそうだが、確かによいと思う。ただ、パフォーマンスの観点ではきっとReactのが優れているような気がしなくもない。そういう意味で、Reactに優位性があるのではないかと思う。

*1:Fluxのデータフローの責務が、果たしてビューにあるかないかはここでは話さない

*2:http://mizchi.hatenablog.com/entry/2017/10/02/074916

Unihertz Jelly Pro が届いた

 IndieGoGoでBackしていたJelly Proというめちゃくちゃ小さいスマホがとうとう届いた。

f:id:IzumiSy:20171001234830j:plain:w400

 つい最近GPD Pocketが届いたばかりな気がするのに、また性懲りもなくこういうガジェットを買ってしまったわけだけれど、これもまたほんとに買って正解なシロモノだった。そもそもスマートフォンが小さくて困るのは、キーボードの打ちにくさだと思う。ディスプレイが小さければ小さくなるほど、キーボードの割合も小さくなるからだ。けれど、実物を触ってみるとそんな心配はほとんど杞憂だったなと思わせた。

 Jellyがクラウドファンディングで募集される前にも、ElephoneQという小さいスマホがあったのだが(僕は持ってない)、それは画面のサイズが小さすぎるが故に、キーボードを出すと画面のほぼ半分以上を埋め尽くしてしまうというレベルの小ささのようだった。その記事を見て「Jellyもこんなだとイヤだな。とりあえず音楽プレーヤー的に使うか。」という風に一旦心を落ち着けていた。もちろん音楽プレーヤーとして使えれば充分御の字だし、小さければ邪魔にもならないと踏んでいたということもある。

 だが、実際に届いてみると、そのモノ自体の可愛さもさることながら、実際に実用にも充分耐えるのではないか、と思わせんばかりの使い心地で驚いた。僕自身は目が割と良いほうなので、ディスプレイの文字サイズを最小にして使っているというのもあるが、それにしても全然Twitterやらその他のアプリが普通に使えるのではないかと思う。キーボードも一見タッチしにくそうに見えるが、Sensitivityを調整するとまったく普通のスマホと遜色ない間隔で入力ができるようになる。

 まさに極小スマホ恐るべし。すごい。

 僕は手が比較的小さく、それだけにJellyを握ったときの異常なまでのフィット感に驚く。いま現役で使っている7インチディスプレイのSO-04Fでも、片手ではときおり操作しきれないことがあるが、Jellyにそんな心配をする必要はない。いつでもどこでも片手でらくらく何でも操作ができる。Playストアもわりといい感じで表示される。

f:id:IzumiSy:20171001235056j:plain:w400

バッテリの持ち

 スマートフォンを選ぶにつけ、必ず気にする項目がある。それはバッテリの持ち。単純に考えて、小さいスマホほどバッテリの持ちが悪い。Jellyもまた、バッテリ容量が950mAHと、さほど多いわけではない。というわけで、とりあえずどんなもんかとチェックする意味も込めて、100%充電から2日間ほど、どれくらい充電が持つのかを確かめることにした。この間はWifiオンで、たまにGPSを使う程度。Bluetoothは使っていない。

 結果から言うと、僕の端末の使い方やインストールしているアプリが関係しているということもあるのだろうが、フル充電で2日間程度は持つということが分かった。下は2日目の夜頃に撮ったスクリーンショット

f:id:IzumiSy:20171001235435p:plain:w300

 他のレビュー記事や2ちゃんねるのスレなどを見ると、あまりバッテリの持ちがよくないというようなことを書かれていたので、あまり期待はしていなかったが、おもったよりも持つな、という印象。僕の今使っている端末が1日使うとほぼ20%くらいというレベルの摩耗っぷりだが、僕の使い方では1日持てばもう充分。それに、IndieGoGoでVoltermanもBackしているので、それが届けばいつでもモバイル・バッテリを持ち歩けるということになる。Jellyは今の端末を完全に置き換えることのできるポテンシャルがあるのかもしれない。