オライリーブックスの概要をTOKIOのメンバーがしゃべるブックマークレットを作った

とくに意味はない

f:id:laiso:20150312204619p:plain

var members = ["長瀬", "松岡", "城島", "山口", "国分"];
var textList = $("#detail p").text().split("。");
textList.pop(); // remove
var newText = textList.reduce(function(a, t, i){
  return a+members[i % members.length]+"「"+t+"」<br />";
}, "");
$("#detail p").html(newText);

http://let.hatelabo.jp/laiso/let/hJmfgdzokMhO

undefinedのスクリーンショットはおもしろかったので残しただけで上記コードだと長瀬が二回しゃべる

Wantedly Author デビューした

先日会社の求人情報の文書を書く機会があって。そもそもやる人が居ないのと、好き放題書いてもいいというので引き受けた。以下がそれ。

ユビレジのiOSアプリを開発するエンジニアを募集 - 株式会社ユビレジの求人 - Wantedly

Wantedly Author という言葉は別にないけど CPAN Author みたいなものとして使っている。

*

個人的にIT業界入りしてからここ数年ずっとITベンチャーの求人フィード(今の主戦場はFind Job ! からWantedlyに移っている)をチェックし続けていたので*1書き手の側になるのは感慨深かった。

僕と同じようにWantedlyの求人の文書を書くことになってしまった人のために知見を伝授すると、モバイルアプリでAppleやGoogleのUIを参考にするように、迷ったらWantedly, Inc. の人たちの募集の真似をすると良い。

https://www.wantedly.com/companies/wantedly/projects

彼らはかなり頻度でドッグフーディングしているように見えるし、プラットフォーマーの強みで内部的なKPIも設定しやすいのだろうし、実際バリバリ採用もしていっているいるから間違いないと思う。

*

僕自身においてはここ数年のウォッチ体験を通じた結構なこだわりがあったので、それを好きなようにぶつけた。

まず「必須条件」「優遇条件」みたいなものは書かない。Wantedlyでこれらが書いてある募集は比較的少いけど、基本的にダイレクトに採用する場所ではないので、必須条件でフィルタリングする必要がないし。応募者すべてにリアクションする必要もないし、選考コストも全然ないので(というのはよくできている)ので窓口を狭める必要は全くないからである。あと「Faceboookのソーシャルグラフ1,2HOPまで」のような制限も加えられるが同じ理由で全解放を推奨したい。

会社が応募者に求めるものをつらつらと書くのではなく、応募者が求めていることを書いて選んでもらうというのが望ましい。

あとこれはWantedly特有の空気感なんだけど、誰と何をやるか? にフォーカスしているあまり文面からやりがいを感じはするものの、給与の話が全然出てこない。というのをずっと思っていたので勝手に給与の記述を入れた。Wantedlyに何か書くならこれは外せなかった。

*

ということでこぞってご応募ください。また「応援」をして募集記事の可視性を上げると、それは採用につながり、社内における私の発言力が増すのでおすすめします。FaceboookとTwitterのチェックボッスをオフにして応援すると、ステルス応援できるので(Wantedly上には残る)勝手に投稿されたくない僕はいつもそうしています

iOSの人向けにことわっておくと、岸川さんはもはやユビレジへの出社義務ないので*2 オフィスに居ないんだけど、予定が合う時にお願いすれば会えるかもしれない(国外に居るかもしれないけど)。ぐらいの感覚です。

*

あとついでにとても重要なことを思い出したんだけど、岸川さんの最終出社日に例によって東亜飯店面白ハラスメントの話題をしていたんだけど*3。ふと岸川さんから「それは何がおもしろいんですか?」という言葉が出て私は反省の滝に打たれたような衝撃を受けた。

そう、東亜飯店。「それは何がおもしろいんですか」。みなさんもよくこの言葉を噛み締めて欲しい。こんなものは2014年までで終りにしよう、というのを次世代に語り継ぐしかない。

そんな使命感を感じた。

ご祝儀を受け取り続けることでブログが書ける仕組みづくり

f:id:laiso:20150305121351p:plain

はてなダイアリー3つぐらいをマージしてURLが http://blog.lai.so/ に変った。

はてなブックマークのメタ情報移行とダイアリーPermalinkからのリダイレクトも自動で設定された。はてなブログプラットフォームじゃないとできない芸当なのですごい(ロックインが)。

Naked Domain の lai.so に本当は設定したかったんだけどヘルプを見る限り諦めろとのことなのでやめた 。

はてなブログを独自ドメインで利用する - はてなブログ ヘルプ

Github Pages はNaked Domain使えるので、戻してしまうおそれもある。

*

はてなブログ自体はしばらく使っていて、書きやすいし、なぞの著者がどんな記述フォーマットで文章を書いているのか外部へ開示する先進的な機能もあるし、もうダイアリーやグループダイアリーには戻りたくないと感じている。

逆にマイナスだったのはProオプションで laiso.hatenablog.com が全部301リダイレクトされてしまうところ。確か他のブログサービスではユーザーが独自ドメイン設定してもサービス固有URL生きているところもあったはず。あれの方が良い(はてなブックマークやSEO的な都合があるけど)。

なぜかというと単純で、ドメイン管理者が死んだり破産したりする可能性が結構あるからで、そうすると文書がウェブから辿れなくなってしまうというのを気にしている。

Changelog

同僚の吉報で思い出したけど、先日結婚して、第一子をもうけた。先日といっても2011年ぐらいだけど。

あと養子になったので戸籍がアカウントリセットされ、何か犯罪を犯しても生まれが特定されづらくなったという謎の自信に満ちている。

ユビレジのテスト版ベータ配信をCrashlytics/Fabricに移行した

TestFlight has moved.とのことなのでひと月ぐらい前から移行先を検討していて、各社の動向を探りつつ(ネットウォッチで)どのプラットフォームに我々の未来を託すべきか・・と熟考した末。全く記憶から消していて昨日いきなり思い出してやばいと思ってどれでもいいからとすぐに移行した。

https://get.fabric.io/beta

Crashlyticsはクラッシュレポートを収集する組込みSDKを提供していたサービスなんだけどFabric - Twitter's Mobile Development Platformの一部になって(デプロイツールでもフリマアプリでもない)
「Beta by Crashlytics」というモジュールも追加されたのでこれがTestFlightの代替になる。利用は個人でもビジネスでも無償。

ユビレジではクラッシュレポート分析にCrittercismを利用しているのでCrashlytics SDKは組み込んでいないんだけど(Crittercism > Crashlytics と評価しているわけでもなく。そもそもクラッシュ頻度が少なくCoreDataやUIKit深部のなぞエラーばかり来る)
ベータ配信は実質的に Crashlytics.framework の内部コマンドにIPA形式のファイルとAPIトークンを渡せばできるので、アプリケーションにリンクする必要はなかった。

セットアップは基本的にCrashlytics公式のガイドに従っていくとコンプリートできるようにはなっているんだけど。ちょっとめんどくさいのがFabric, Crashlytics, Twitterのそれぞれのアカウントを使ってセットアップするところが非常にわかりづらかった。これはFabricプラットフォーム自体が整備されたら改善しそう。

またAPIトークンを手に入れるにも一度 Fabric.framework という別物のSDKを組込み作業をMacXcodeGUIのセットアップフローでこなす必要があった。個人的にはまわりくどくてめんどくさいと思っていたが、「設定が簡単で気が効いている」という声も結構あるようだ。実際Fabricチームの作るWebアプリのGUIはよくできていると思った。


具体的にやったことはまず、ユビレジアプリはDistributionまわりは可能な限り自働化してあり。Travis-CIをテスト実行だけでなくリモートのOS X上で好きな処理を実行できる汎用のMacマシンとして活用しているので。その過程で肥大化していったRakefileXCJobsという名前でgem化していて。これに組込めるようなものを想定して

notes = 'notes.txt' # リリースノートのテキストファイル
group = 'Dev' # Crashlytics上で設定したグループ名
command = %[./Frameworks/Crashlytics.framework/submit #{FABRIC_API_KEY} #{FABRIC_API_SECRET} -ipaPath #{File.join(BUILD_DIR, "#{SCHEME}.ipa")} -groupAliases #{group} -notesPath #{notes} -notifications YES] # YES でメール通知
sh command do |ok, res|
  puts res
  fail 'Submit to Crashlytics-Beta has failed' unless ok
end

Beta Distribution with iOS build servers – Support for Crashlytics を参考に。

みたいなことをするRakeタスクを定義してTravis-CI上からアップロードしている。Crashlytics自体Fabricの過渡期に巻き込まれてこれからどんどん変わっていきそうなので、方法とかドキュメントとかが落ち着いてきたら見直そうと思っている。xcjobs-0.0.7でもできるようになった(README参照)

APIキーは https://fabric.io/settings/organizations からリンクを辿るとこのへんからも取得できる。

注意点としてはCocoaPodsでインストールできる Crashlytics.framework はオフィシャルのものではなく有志がメンテしている感じなのでFabricのサーバーからダウンロードできるバイナリと比べると古いバージョンだということがあった。そのため上記のセットアップフローを手動で最後までやってFrameworkをまずダウンロードしてくる必要がある。

https://fabric.io/downloads/xcode

ライブラリの選定基準

今回のように「こういうことを実現したいのでライブラリの力を借りる必要がある」というケースに結構出会す。

以前はその界隈の最新の流行のものをとか自分が気に入っているもの、みたいな基準で選んでいたのだけど最近は「1年後のメンテナに恨まれない選択(なぜならこころがつらいから)」という至極後ろ向きな視点を心掛けているので

Vue.js が辛くなってきた | status code 51

とかも結構共感する。

これは良い面をみると経験を積んで長期的で安定で保守的な思考になっているというといわれはいいんだけど、ずばり老いと筋力の低下が影響して公平な判断ができなくなっているんだと予想している。

ssig33.com - インターネットが面白くなくなった

つまり、ライブラリを選定する立場の人やシステムアーキテクトに必要なのは強靭な肉体。自重トレをしろ。

はてなブックマークの検索結果からコメントないfavoritesの人を消すUserScript

// ==UserScript==
// @name         はてなブックマークの検索結果からコメントないfavoritesの人を消す
// @namespace    http://lai.so/
// @version      0.1
// @description  $name
// @author       laiso
// @match        http://b.hatena.ne.jp/search/*
// @grant        none
// ==/UserScript==

setTimeout(function() {
  $('ul.favorite li')
    .filter(function(){ return $(this).find('span.comment').text() === "" })
    .map(function(){ this.style.display = 'none' });
}, 3*1000);

いつもの感じのやつです

f:id:laiso:20150129125444p:plain

これがつらいので

f:id:laiso:20150129125443p:plain

こうする。

この部分非同期に挿入しているようでちゃんと書くのがめんどくさかったので3秒待って実行することにした。

Tampermonkey

はてなブックマークトップのPR記事を消す.user.js

// ==UserScript==
// @name        はてなブックマークトップのPR記事を消す.user.js
// @namespace    http://lai.so/
// @version      0.1
// @description  はてなブックマークトップのPR記事を消す.user.js
// @author       laiso
// @match        http://b.hatena.ne.jp/
// @grant        none
// ==/UserScript==

var entries = document.querySelectorAll('li.entry-unit');
var prs = _.filter(entries, function(entry){ return entry.querySelector('li.pr') !== null; });
_.each(prs, function(entry){ entry.style.display = 'none'; });

Tampermonkey に放り込んでる