Runner in the High

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

GPD Pocket Ubuntu版が届いた

 IndieGoGoでUbuntu版をbackしていたのがとうとう届いた。Windows版は「もう届いた」「小さくて最高」みたいなツイートやブログエントリーがネット上でちらほらと散見されたのにもかかわらず、Ubuntu版は随分時間がかかっているんだなと思い若干本当に届くのか疑っていたが、とりあえず届いたのでひと安心した。GPDのロゴが散りばめられた非常にそれっぽい梱包でなかなかどうして悪くない。 f:id:IzumiSy:20170822101209j:plain

 Ubuntu版も箱自体はWindows版のものとさほど変わらないようだ。若干裏側の板の貼り付けが雑だが、それもそれで味があるというものだ。それにしてもGPDのロゴはかわいい。黒い箱にゴールドという配色に高級感を感じさせようという努力を感じる。 f:id:IzumiSy:20170822101619j:plain

 クリスマスプレゼントをもらったこどものように箱を開封して、さっそく端末のセットアップを始める。確か公式のアップデートでは、マウスコントローラのラバーにはいくつか交換できるものが同梱されるとかなんとか言っていたような気がするが、入っていなかった。なくてもさほど困るものではないのでいいとしよう。
 IndieGoGo上のアップデートでUbuntu版のデモをみたとき、あまりにもディスプレイの解像度が高すぎて、もしかしたら文字が読めないかもしれないと心配したが、まだ20代の僕にはどうにか読めるレベルで安心した。僕は小学生のころからPC漬けの毎日を過ごしていながら、いまだに両目とも1.5という比較的恵まれた眼を持っている。これに関しては両親に感謝するばかりだ。結局のところ、僕にはこれくらいの解像度のほうが丁度よい。 f:id:IzumiSy:20170822103841j:plain

不具合対応

 やはりというか、もともと予想していたとおり様々な不具合に遭遇した。基本的にはディスプレイ周りの不具合が多く、解決にはUbuntuに関するある程度の知識(たとえばログイン・マネージャがlightdmと呼ばれるものであると知っている、など)が必要になったので、確かに全くLinuxを知らない、という人にとっては優しい製品ではなかった。かと言って僕自身もそんなに詳しいわけでもないが、この21世紀の今、ある程度の情報であればGoogleの大いなるチカラを使ってどうにか見つけ出すことができる。また、GPD Pocket Windows版にわざわざLinuxディストリビューションを入れる世界中の酔狂なひとたちも、様々な情報をネット上で提供してくれているので、彼らの奉仕精神に感謝することにしよう。

不具合レスキューQ&A

  • 起動時のコンソールが横向きになってしまっている

 起動時にブートログが流れるが、それが横になってしまっている。これを治すためにはGRUBの設定ファイルからGRUB_CMDLINE_LINUX_DEFAULTのオプションを見つけ出し、そこへfbcon=rotate:1を追記する。もし設定ファイルを見つけ出せなければ、Grub Customizerなどを使ってもよい。ネットの他のブログエントリーにはこのオプションに加えてnomodesetも追記しているものを見かけるが、僕の場合は追記すると、ログイン後デスクトップのローテーションが効かなくなったため、ここでは勧めないことにする。

  • ログイン画面も横になってしまっている

 GPD Pocketで使われているログイン画面の設定を変更するには、ログイン・マネージャーであるlightdmに関するコンフィギュレーションを弄らねばならない。この不具合に対する最も簡単な解決策は~/.config/monitors.xml/var/lib/lightdm/.config以下にコピーすることだ。おそらくではあるが、この設定を行う前にはGPD側から配布されているUbuntu版の不具合解決に関するPDFを参照のこと、ログイン後のデスクトップをしっかりと正しいローテーションに変更する必要がある。
(参考)https://askubuntu.com/questions/408302/rotated-monitor-login-screen-needs-rotation

  • Unity Dashがおかしい

 Unity DashというのはデフォルトでUbuntuのUnityデスクトップに搭載されているアプリケーション/ファイルの横断検索機能のようなものだ。Macを使ったことがある人ならば、内臓機能のSpotlightやAlfredなどのアプリケーションを思い浮かべるだろう。僕はデスクトップでもUnityを大活用しているため、スーパーキーひとつで起動できるこの検索機能はとてもお気に入りだ。
 しかしながら、デフォルトではGPD PocketのUnity Dashはモードがデスクトップ用になっていないため、下記のようなシルエットになっており、あまりうれしくない。下の写真はネットから拾ってきたものだが、まさにこんな感じになる。 f:id:IzumiSy:20170822170015p:plain  これは実際には不具合ではなく、おそらくただのありがた迷惑だ。GPD Pocket自体はNetbook扱いなので、GPDは端末をNetbookとしてUbuntuのカスタマイズを行ったのではないかと考えられる。僕の場合はターミナルから以下のコマンドを実行して設定をデスクトップのものに戻した。

gsettings set com.canonical.Unity form-factor ‘Desktop’

(参考)https://ubuntuhut.wordpress.com/2014/10/02/change-unity-dash-overlay-size-in-ubuntu/

そのほか

 RedditでもLinuxをGPD Pocketでちゃんと動かそうと頑張っているひとたちがいて、Linux on GPD Pocketというスレを中心に活発な(?)議論が行われている。そうしたかいもあってか、親切なひとがgpd-pocket-ubuntu-respinというWindows版へのUbuntuのインストールの不具合も含めたさまざまなLinux on GPD Pocketのための応急処置の詰め合わせのようなリポジトリを公開している。たとえば僕の場合は、ログイン画面のローテーションがおかしい問題の解決にこのリポジトリを参考にした。おそらくGPD Pocketを手にする人々というのは、一般的にはアーリーアダプター、すなわち人柱的存在であるが、それでもこうした集合知の助けを借りられるというのは十二分に心強い。

さいごに

 ここまで長ったらしく不具合がどうのこうのと書いてきたが、端末自体は全く満足のいくもので、ひさしぶりにいい買い物をしたと思う。過去にNECから販売されていたLifetouch NOTEというクラムシェル型Android端末にも手を出したが、最終的にはあれ自体はあまり使い物にはならない端末だった。けれど、GPD PocketはAndroidではなくちゃんとしたLinuxで、無茶なハックをせずともvimを動かしたり、コーディングをすることができる。性能の差も大きい。予てからこのような端末を待っていただけに、手にしたこの喜びはひとしおだ。

フレームワーク・ライブラリを選ぶということ

とりあえず、ググったら大抵解決しそうなんでReduxを使おうと思います

 2016年の夏、僕はあるフリマアプリで有名なECスタートアップでインターン生として、商品を販売するユーザー向けのアプリケーションのプロトタイピングをしていた。ほとんどすべてのアプリケーション(ソフトウェア)開発のプロセスがそうであるように、僕もまたアプリケーション開発の前段階として「どのような技術スタックを採用するのか」という選択をするフェーズにさしかかった。Reactを採用するのか、Vueを採用するのか。Refluxを採用するのか、それともReduxを採用するのか。それぞれのフレームワーク/ライブラリに一長一短があり、それらの特徴や長所・短所を踏まえたうえで最も最適な選択が「技術選択」というタイミングで求められる。そこでぼくは、とりあえずRedux+Reactの組み合わせを採用した。なぜなら、それが一番情報量として多かったし、なにより困らなさそうだったから!

 多くの割合を占める技術選択の多くが、「それを使っておけばとりあえずは困らなさそうだから」という理由に始まると言ってしまっても、さほど多くの人は「?」という顔をしない。例外なくほとんどの人は大きな失敗だけは避けたいと考える。無名の誰が作ったか分からず、ドキュメントのほとんどないフレームワークや、数年間もメンテされていないライブラリを使うことで、アプリケーション開発にリスクが生まれるということは誰にでも分かる。ゆえに、多くの人が使っていて、ちょっとググるだけでブログ記事やStackoverflowの回答がポコポコひっかかるようなフレームワークは人気がでやすい。その人気は、なんらかの問題が起きても解決策はどこかに用意されているから、という安心感から来る。大抵の場合、この安心感はポジティヴに「エコシステムが成熟している」「採用事例が豊富」などと形容される。

 成熟したエコシステムや、豊富な採用事例がアプリケーション開発における技術選択の一要素になることは問題ではないし、間違いでもない。個々の組織の方針やなんらかのやむを得ないケースによる場合もある。しかしながら、どのような場合でも選択の理由としてそれらを受け入れることが正しいかどうかという点に応えることは簡単ではない。いかなるアプリケーションであってもMVCはスケールしないからFluxをアーキテクチャとして採用すべきなのか。Flux実装ライブラリとしてReduxを採用すべきなのか。日本で流行っていてネットに知見も多く転がっているからRoRを使うのか。RoRにデフォルトで乗っているからActiveRecordを使うのか。etc…

 生き馬の目を抜くこの世の中を生きる私達は、常日頃から選択を繰り返しながら生きている。だが、その中でも合理的選択には大きな負荷が伴う。選択の理由のほとんどは感情的で非合理的だ。深く思考せずにされる選択は、水のように重力に従って低いとこへと流れるままに流れる。そしてある日、自分たちのアプリケーションがフレームワークやライブラリに縛られ、毎日だましだましの小技やハックを繰り返しながら終わりのない成長痛に悩まされていることに気づく。アプリケーション開発における選択は、普段の私達の思考回路とは外れた場所にある。

 どんなフレームワークやライブラリにも(大抵の場合)なんらかの解決しようとした問題がある。合理的選択のヒントはその解決の対象となった「問題」がどのようなものであるのか、という点を深く理解し、自らのケースに応用できる可能性を探ることだ。TodoMVCなどを除いて、多くのケースでは、アプリケーションを開発するためにフレームワーク/ライブラリを使うのであって、フレームワーク/ライブラリを使うためにアプリケーションを開発するわけではない。もちろん、(たとえば僕のような)学生の個人開発や、ちょっとしたフレームワークの使い心地を試すときには、こんなふうにうるさく合理性に触れる必要はない。でも業務となれば話は別だ。開発者としてアプリケーションを作るということは、もっと大きな責任を抱えこむ。大抵の場合は他にも複数のステイクホルダーがいて、様々な利害関係が渦巻いている。それゆえに、簡単にアプリケーションをポイと捨てることはできない。常に変化し、スケールし続けるアプリケーションは、開発者よりもずっと長生き*1だ。それだけに、ステップの一つとして合理的なフレームワーク/ライブラリを選択をするという重要性は簡単に無視できるものではないし、少なくとも骨を折らねばらないものである。

 2016年の夏、ぼくはそんなことは考えていなかった。ただReactが超アツいと聞いていて、Fluxアーキテクチャを採用することがすごくイケてるとネットで見ただけで、実際はペアーズで出会った女の子に夢中*2だった。そういう意味では、2017年のいま、こういうふうに思えるようになったことは、なにかとても大事なことのような気がする。

参考文献

ビジネスとアプリケーション開発の両方からソフトウェア・アーキテクチャを考えるのによい本。この記事を書くきっかけになった。

*1:この場合は人間の寿命という尺度ではなく、一生同じ開発者がひとつのアプリケーションを開発しつづけないという意味において

*2:そのあとブロックされて凹んだ2016年の思い出

モデルの中でセッションを使う

ときたまセッションに関連するロジックをモデルの中に作りたいときがある。ところが、原則的にRailsではセッションをモデルの中で操作することができない。

この問題を解決する最も簡単な方法は、モデルに生やしたメソッドへセッションのインスタンスを渡す引数を追加し、それを経由してロジックを書くというものだ。

class User < ActiveRecord
  def your_method(session, count)
    session[:items_count] = count
  end
end

こうすることで、やりたいことは実現できる。

...
def update
  user.your_method(session, count)
end
...

SRP(単一責任の原則)に則る

これによって、実際にやりたいことは実現されたが、上のコードはSRP(単一責任の原則)から見て必ずしも正しいものではない。 基本的にはActiveRecordパターンであるRailsのモデルには、そのモデルが1:1で紐づく入出力すなわちデータベース・テーブルへの、アクセスオブジェクトとしての役割がある。セッションも見方を変えれば、小さく揮発性の高いストレージのひとつであるが、ひとつのモデルにいくつもの永続化のロジックが混入するのは責務の観点からみて適切ではない。こうした実装は、テストを書く際やアプリケーションのスケールの際に問題になりやすい。

こうした問題を解決するひとつの方法として、セッションを扱うロジックをカプセル化し、責務を分離することで、疎結合な実装にすることができる。

class TemporaryCart
  def initialize(session)
    @session = session
  end
  
  def add_item
    @session[:temprary_cart][:items_count] += 1
  end
end

TempraryCardクラスを実装したことによって、コントローラは以下のようになる。

...
def update
  TemporaryCart.new(session).add_item
end
...

セッションの永続化モジュールがモデルから分離されたことで、見通しの良いコードベースになった。モデルがそれ自体の正しい責務を守ることは「驚き最小の原則」にも則るという面で利点がある。

参考: Setting a Session Variable in a Model - Stack Overflow

コントローラを名前空間で分離して責務の分割をする

Deviseなどを使って、ひとつ以上のスコープを持つアプリケーションを開発している際に、RESTfulなコントローラとビューが1対1対応をしていると、コントローラがどうしても複数のスコープが絡みついた見通しの悪いコードになりがちである。

たとえば、ECカートを実装する例を考えるとする。まず、ChargesControllerがあって、newアクションとcreateアクションはUserスコープによって決済を行う、いわゆるカートの画面を表示にまつわるもの。そして、showアクションはAdminスコープのみでアクセスできるよう認証を実施し、決済情報の詳細を見れるものである。

class ChargesController < ApplicationController 
  def show
    authenticate_admin!
    ... 
  end
  
  def new
    ...
  end
end

この段階ではコントローラはまだ小さいので、さほど問題は感じない。だが、開発をすすめていくうちに、ユーザーによる決済の執行の過程で、エラーが起きた際に、特別な処理をしなくてはならない必要性が出てきたため、コントローラの中にrescue_fromブロックを用意し、DRIな実装を試みようとした。

class ChargesController < ApplicationController
  rescue_from do
    # ここでnew/createでの例外を拾う
  end

  def show
    authenticate_admin!
    ...
  end

  def new
    # 例外が起こる可能性がある処理
  end
    
  def create
    # 例外が起こる可能性のある処理
  end
end  

このようなコードを書くと、今度はshowアクションの中にある例外も、同じくrescue_fromの中で拾われてしまい、Adminスコープとして必要な処理とUserスコープとして必要な処理がコントローラの中に混在してくことになる。また、authenticate_admin!のような認証系の処理も、今例の短いコードであればよいが、コードの量が多くなればなるほど、ひと目ではどのアクションがどのユーザースコープに限定されたものであるのか理解しづらくなる。

こうしたコントローラの問題は、アプリケーションが肥大化した際にコントローラ内部のスコープの責務がすぐにはわかりづらくなり、スケールする際にバグを生みやすいという点である。このような責務の混在を解消するためのアプローチのひとつとして、コントローラを名前空間で分離し、責務の分割を図るという方法が有効である。

実装

Railsでは、ディレクトリの階層構造が名前空間を作るため、ディレクトリ構造は以下のようにUsersAdmins以下にそれぞれのChargesController.rbを作成する。

もしも、すでにDeviseでscoped_viewtrueにしてオーバライド用のコントローラを生成していれば、controllers以下にはスコープ名のディレクトリが存在しているはずなので、その中にコントローラを作ればよい。

- app
  + assets
  + channels
  - controllers
    - admins
      ...
      * charges_controller.rb
    - users
      ...
      * charges_controller.rb
    * application_controller.rb
  ...

コントローラへ名前空間を付与し、RESTfulに従いながらスコープに応じて必要なアクションを実装していく。

class Admins::ChargesController < ApplicationAontroller
  def show
    ...
  end
end
class Users::ChargesController < ApplicationController
  rescue_from do
    ... 
  end
  
  def create
    ...
  end
  
  def new
    ...
  end
end

上記のようにコントローラへ名前空間が付与されたため、ルーティングでは以下のコードのようにscope module: xxxなどを使う必要がある。

Rails.application.routes.draw do
  scope module: :users do
    resources :charges, only: %i(new create) 
  end
  
  scope module: :admins do
    resource :charges, only: %i(show) 
  end
end

これで、もとのChargesControllerは、Users::ChargesControllerAdmins::ChargesControllerに分割され、ひとつのコントローラ内の責務を適切に分割することができた。

まとめ

このテクニックは、実際に業務で遭遇した問題と、POSTDで寄稿された「DHHはどのようにコントローラを書くのか」という記事からインスピレーションを経た。このPOSTDの記事はいかにRESTfulのルールを維持しながら、Railsのコントローラを書くかというベストプラクティスのひとつであったが、その方策はDeviseを使う場合でも応用できる。

肥大化したRailsアプリケーションのリファクタリングのための最初の一歩は、(もしまだやっていなければ)きれいなコントローラを書くことだ。そのために、こうしたベストプラクティスをできるだけ多く取り入れて、気持ちの良い開発をしていければいいと思う。

その他

ひとつ思いつく別の解決策として、StandardErrorを継承したUserErrorAdminErrorなどのような独自例外を定義し、それぞれのスコープに関連するアクションからrescueブロックを用いて更に例外を投げ直すという手も考えられる。これであれば、コントローラの分割をする必要はない。だが、いずれにしてもアプリケーションが肥大化するにあたっては、コントローラの分割が最もよい手法であると思う。

【Quora】あなたが職場でやった悪いことを教えてください。

Read Josh Nymon's answer to What is the most immoral thing you have done in the workplace? on Quora

Josh Nymon

上司の机の上でセックスをしたことがある。当時僕はとある家族経営の店で働いていて、そこでは土曜日にひとりで商品を客に発送しないといけないことがたまにあった。その職場にはひどいコカイン中毒のジキルとハイドみたいな二重人格の上司がいて、そいつは「いい人」のときもあれば、僕達に平気で週50〜60時間オーバーの残業をさせる暴君にもなるやつだった。とはいえ、店を経営していた家族はけっこう気に入っていた。権威を振りかざすそいつみたいなタイプの上司がキライだっただけで。

そのはなしとは別に、僕は昔通っていた学校で一緒だった女の子と付き合っていた。彼女はだいたい車で8時間ぐらいかかる場所に住んでいて、ある週末、ぼくがひとりで働いているときに、たまたま彼女が僕の住んでいる街に来る予定が重なった。最後に彼女にあったのが数週間前だったというのもあって、ぼくは結構ムラムラしていた。恋する若人にとって三週間というのは永遠の別れと同じだ。丁度ぼくが仕事をきりあげかかっているときに、彼女は早めに着いたのでどこにいるか教えてほしいと連絡してきた。あまりにもムラムラしていて、正直数秒も待てる気がしなかったので、職場で会おうと伝えて、駐車場で彼女と落ち合い職場に招き入れた。お互いもう情動と性欲でいっぱいいっぱいになっていて、とりあえずどこかに窓のないスペースがないかどうか探し始めた。そのときたまたま見つかったのが上司の部屋で、当然わかるとおもうけれど、鍵もかかっていなかった。

次の月曜日、僕らがセックスをした机の上で昼飯をたべているのを見たときはほんとに笑えたよ。

(抄訳)

Chrome Extensionのbackground pageでconstを使うのに気をつけよ

 Chrome Extensionではbackgroundを使っている方々各位にお伝えしたいのがなんといつのまにやらconstで定義した変数がextension.getBackgroundPageメソッドから取れなくなっているということ

background.js
...
const NOTIFY_ID = "default";
const ITEMS_ID = "Items";
...
popup.js
...
var BG = chrome.extension.getBackgroundPage();

console.log(BG.NOTIFY_ID); // "default"
...

 これまではこれでぜんぜんよかったはずが、いまはなぜかconstで定義された変数がすべてundefinedになってしまう! getBackgroundPage関数からはwindowが帰ってきていて、background.jsの中で定義された変数やら関数やらは全てwindowに生やされる形になるのだけれど、どうやらconstはだめらしい。これのせいで公開してた拡張機能が動かなくなっていたのですごく憎い。まあ気づいたから良かったものの、、、
 ということでおとなしくvarを使って定義しましょう。

いま大学生がSpeeeのbizTechインターンに参加すべき5つの理由

 どうもみなさん、2015年夏のBizTechインターンに参加しました@IzumiSyです。現在は別の企業にてインターンをしているのですが、あまりにSpeeeのインターンが素晴らしすぎたのでアドベントカレンダーの一日を拝借して記事を書かせてもらいました。僕自身、趣味でJavaScriptばっかり書いている文系大学のろくでもないエンジニア志望学生ですが、そんな僕にエンジニアを目指す学生ならすぐにでも参加すべき理由を5つばかり紹介させてください。

 

1. RubyRails)力がアガる

 ご存知RubyKaigiのスポンサーもつとめているのがこのSpeee。会社全体で開発言語のRubyRails)化を推し進めていて、エンジニアの方たちもRubyに造詣が深いことは目に見えて明らか。僕もSpeeeのインターンに参加するまでRailsを満足に触ったことは正直なかったのですが、度重なるレビューの嵐で否応なしにRails力が向上します。とはいえ、そもそもRubyに限らず技術自体に明るい人しかいないのでJavaScriptでもScalaでもドンと来い!という人が実際にいます。その辺を考えると、そもそもRubyの力どころか技術力全般がアガると思ってます。ちなみにRuby化の話では@nisshieeさんの「Ruby初心者チームが「Ruby日本一」を目指して半年の話」が僕的にはおすすめです。

 

2. メンターがアツい

 個人的な話になりますが、夏のSpeeeのインターン含めこれまで5, 6社で短期〜中期インターンに参加していました。つまり少なくともそれだけの会社のメンターの方たちを見てきたわけですが、その中でも最もインパクトのあったのが、正直なはなし、Speeeの是澤さんでした。
 SpeeeというTechカンパニーの重鎮という感じがハンパないです。Speeeには技術顧問としてMatzさんと元クッ社の井原さんを招いていますが、とはいえアツさでは経歴・思想ともに個人的には是澤さんを推したいです。ちなみにSpeeeのインターンでは是澤さんから直接1on1でアツいフィードバックがもらえて、大抵このフィードバックでみんな一皮むけます。

 

3. どうしたら強くなれるかを知れる

 2と少し絡むはなしですが、Speeeのインターンで得られるのは、いわゆる1weekとか1dayのインターンのようなものとは違うと個人的には感じています。Speeeのインターンは、実際にプロダクトを作るためのビジネス的な視点だったり、自分が技術的・人間的に成長するための謙虚な精神をいかに養うか、のようなよりエンジニアとしての根底的な成長に関わってくるものだと思っています。
 「自分になにが足りないか、そのためには何をすべきか」という問題意識をもって、Speeeでは自分の成長への距離を常に計っていました。学生のうちに自分に何が足りなくて、何を足せばもっと(エンジニアとして)強くなれるのか、ということを知れるのは今後の自分が何をすればよいのか、という指針になるはずです。

 

4. ビジネスの視点を垣間見れる

 Speeeという会社自体がそもそも全体的に頭脳集団という印象が強いので、なんとも言えないのですが、数字やデータを効率的に使ってビジネスを推し進めている会社です。口外禁止と釘を差された内容もあるので、多くは語れませんがインターンに参加して中に入ってみると、いろんなビジネスをロジカルに広げているのがよく分かるはずです。(実は本当にいろんなことをやってます)
 インターンでもまた、このビジネスの視点というものを継承していて、プロダクトの開発から実際に設計をしてコードへ落とし込むまで、ひとつひとつをユーザー側の視点や意図に立ちながら客観的な物事の見方のもとに訓練されます。ここがまさに学生にとってはタフな部分なのですが...これが経験できるのがひとつデカいところです。

 

5. おいしいコーヒーが飲める

 Speeeにはコーヒー文化が強く根付いています☕
そして、僕がインターンをしている期間中にはなかったのですが、最近新しくスター◯ックスみたいなフロアが増えたらしいです。どうやらバリスタの人もいるらしいです。(http://speee-blog.jp/?p=279

f:id:IzumiSy:20161118174735j:plain


さらにこのフロア、技術力強化の一環でなんとオライリーの本が全部揃っているらしいです!!技術を勉強したい学生は行くしかない!!!!11