YAPC 2日目に行ってきました

YAPC初めて行きました。

1日目も行きたかったんだけど、諸事情(2つ前のエントリ参照)により来週から入院することになってしまい、ドタバタしたため行けませんでした。2日目も午後から参加です。PHP のやつ聞きたかったけど残念。

一番良かったのは Github の Andy さんによる「Changing the tires on a moving car: a case study in upgrading legacy architecture」。自分も仕事で最近はずっと古いシステムからの移行をやっているので、どこも大変だな〜と共感できるだけでも良かったです。サービスが大きくなるにつれてアーキテクチャを変えて行くのは難しいけれど Web エンジニアとしてはやりがいのある仕事だと思います。

後から考えてみると Grit から Rugged への移行で RPC を監視しているという話がいまいちわからないような。。。静的な解析ではだめなんだろうか?

あとこのセッションは同時通訳のクオリティに驚きました。専門性が高いテーマでもできちゃうんですね。

「モバイルアプリとAPIのありかたを考える2014」とか「Mobile Application Development for Perl Mongers」とか見たせいか、全体として Android/iOS のモバイルに移る Web エンジニアが増えたなという印象が強く残りました。自分も Java は書けるんだしそろそろ Android くらいには手を出しとこうかという気分になりました。

「趣味開発のためのクラウド/VPS活用術」もよくある話ではあるけれど実際に使ってみた結果としての各サービスの比較はあまりないので参考になりました。どうでもいいけどスポンサーに Conoha 並んでるのに Conoha の話が全然出てこないのがドキドキしました。

悪かった点としては席が全然足りていなかったこと。4並列でやっていたら偏りが出て座れない部屋が出るのは当然としても足りなすぎでした。最後のほう2時間くらいはずっと立ちっぱなしになり、体調も悪かったので途中で帰りました。1300人以上の参加者に対して藤原洋記念ホールのキャパ500人は少なすぎると思います。

それから YAPC ASIA というイベント名なのに、壊れた自撮りグッズのことをチャイナクオリティと言ったおっさんには不快感を覚えました。フィリピンの女性がうんぬんも場所によったらアウトでしょうね。

主に体調が悪いせいであまり楽しめなかったけれど、トークのクオリティは全体的に高くて面白いし、エンジニアが大量にいるのはそれだけで面白いので来年は全参加したいです。

YAPC運営・スピーカー・参加者の皆様お疲れ様でした。

「メンテナンス大変なのでサービス閉じたいです」

Web サービスの会社にはイケイケなサービスの陰に隠れて、かつてイケイケだったけど今はイケテナイサービス、とか、ぶっちゃけ最初っからあんまりやる気なかった☆サービス、これどこで拾ってきちゃったのサービス、などなど、惰性で続いちゃってるようなサービスがごろごろあったりします。

そういうイケテナイサービス群はメンテナンスの手間を取らせる物なので、エンジニアとしては閉じてしまいたい。でも非エンジニアとしては閉じたくない。いや、本当は閉じたい!でもちょっとは儲かってるし、閉じるとわずかながら存在するユーザーからクレームくるし、連携先の企業とやりとりするのめんどいし、まあいろいろめんどうそう。

そこで、「イケテナイサービスにはできる限りメンテナンスの手間を払うな」という話がエンジニアのとこにきて「お前なーっ!そのメンテナンスの手間がなーっ!」となり、話がループを始めます。なぜこういう噛み合わない話になってしまうのか。

エンジニアがメンテナンスの大変さを説明するのに「フレームワークのバージョンアップとか大変なんですよー」とか言っても、非エンジニアは「ふーん、そうなんだ(無理にバージョンアップしなければ良いんじゃね?)」とか思ってそうです。自分エンジニアだからわからないけど多分そう。

エンジニアは「Webサービスは(言語・ライブラリ・関連しているサービスの影響などで)メンテナンスしないと壊れる。」などと思っているのに対して、非エンジニアはなんとなく「ほっとけば動いてそう。」と思ってる気がします。

なので、最近は「メンテナンス大変なんですよー」じゃなくて「ほっとくと壊れるんですよー」とかよく言ってます。なにか他にもっと気の利いた言い方あります?

WEB+DB Press 82 に PHP の記事を書きました

PHP

WEB+DB PRESS Vol.82

WEB+DB PRESS Vol.82

  • 作者: 山口徹,Jxck,佐々木大輔,横路隆,加来純一,山本伶,大平武志,米川健一,坂本登史文,若原祥正,和久田龍,平栗遵宜,伊藤直也,佐藤太一,高橋俊幸,海野弘成,五嶋壮晃,佐藤歩,吉村総一郎,橋本翔,舘野祐一,中島聡,渡邊恵太,はまちや2,竹原,河合宜文,WEB+DB PRESS編集部
  • 出版社/メーカー: 技術評論社
  • 発売日: 2014/08/23
  • メディア: 大型本
  • この商品を含むブログを見る

8月23日発売の WEB+DB Press 82 で PHP の記事を書きました。

大規模な PHP プロジェクトをどうやって安全に、というか事故らずに運用していくかという視点で書きました。まあそんなの無理なんで、内容としてはかなり保守的に見えるかもしれません。イケイケ PHP プログラマは嫌がるのかな、わからん、とか思って書きました。

大規模になってくると、もう PHP がどうとかそういう大変さよりは、負荷が...ストレージが...コネクションが...とかのパフォーマンス問題や、あっ、PCサイトバグってる、よし直した、あっ、iPhone アプリ...し、死んでる!!みたいなマルチデバイス対応の辛さ、などなどばかりで、あまり PHP 関係ないんじゃないかな、と思うんですが、そう思って原稿書いてたら「なんか PHP の連載なのに PHP のこと書いてないですね」「ですよねー!!」となり、頑張って PHP のことも書きました。

特徴的な点としては、PhpStorm について詳しめに書いていることでしょうか。それから最近の弊社開発チームでの取り組みなどについても少し書いてあって面白いと思います。

ところで、書いてる途中、お腹痛いなーと思ってたら腸に穴が空いていました。お尻から血が噴き出して、死ぬのかな?って思いました。やっぱ PHP 体に悪いのかな...ちなみにまだ治ってません。

ということで、WEB+DB Press 82 買ってください。10 冊買っても内視鏡検査より安い。なんてこった。

Feedly と Github timeline を twitter に流すようにした

FeedlyTwitter に流す

昔は Google Reader があったころは RSS をチェックしていたんだけれど、Google Reader が終了して Feedly を使うようになってからは見ることがほとんどなくなった。別に Feedly が気に入らないのが理由ではなく、その頃にはもう Twitter 見るようになっていたから、情報が Twitter 経由で目に入るようになっていた。

Feedly をたまに見ると面白い記事はあるので少しもったいないなと思うこともあったが能動的に RSS をチェックしにいくという習慣はもう戻らなかった。サイト巡回とか、RSS をチェックとか既に終わったインターネットって感じがして、やったら負けかなみたいな気持ちもあった。あと RSS リーダーは見に行かないとどんどん未読が増えてどんどん見に行く気がなくなる。

要は記事が自分の視界に勝手に入ってきて、興味を持たない限りは通り過ぎて欲しい。自分が毎日見るのは今は Twitter くらいしかないので、Feedly で購読してるフィードを全部 bot 経由で Twitter に流すようにした。FeedlyTwitterAPI があるのでそれを叩くスクリプトを書けば良い。Twitter に投げるときに URL を短縮したいこともあるのでそれには bitly を使った。

The feedly Cloud API

Bitly API Documentation

Feedly API についてはこの記事も参考になった。

Feedly APIメモ - Qiita

スクリプトPython で書いた。最近は Requests: 人間のためのHTTP — requests-docs-ja 1.0.4 documentation が便利。

tototoshi/feedly-tweet

Twitter への投稿だけ面倒になって API を直接叩くのではなくライブラリを使った。

sixohsix/twitter

Jenkins でまわす

あとはこれを jenkins っていう cron に登録して5分おきとかで動かす。

こんな感じで TL に流れてくるようになった。

ついでに未読がたまる問題も自動で既読にする処理を入れて乱暴に解決した。

Github のタイムラインを Twitter に流す

見逃しがちな Github のタイムラインも Twitter に流すようにした。異常な量のリポジトリをウォッチしてる xuwei-k さんも Github のフィードを Twitter に流してるらしい。

tototoshi/github-timeline-tweet

これでめでたし。

Python/Flask と Backbone.js で Markdown エディタを作った

Atom はまだいまいちだし、Sublime Text は使ってると金を要求してくるし、emacs はそろそろ引退かな。Markdown 書くのに Mou とかは便利だけど、長い文章を書いてるとだんだんもっさりしてくる。と、普段使いのテキストエディタをどれにすればいいかここのところずっと考えている。

それとは別に、保存したテキストファイルたちをどう管理すればいいかもよく考える。ファイル名を考えるのがめんどくさい。どこに保存したのか忘れる。ファイルツリーをたどるのがめんどくさい。⌘+s を押すのすらめんどくさい。正直エディタのほうでなんとかしてほしい。

Evernote とか便利だけど、勝手にフォーマットされて困る。コードとか貼付けられない。

というわけで少し前に自分用の Markdown エディタを作った。

tototoshi/gfm-editor

左側にエディタ、右側にリアルタイムプレビューが表示される。Markdown エディタとしてはよくある UI。左上にあるプルダウンでメモを選択することができる。メモはサーバーのポスグレに保存される。保存は左側のエディタに書き込みをした時点で自動で行われる。保存ボタンはない。

簡単な Web アプリだけど自分の用途としては必要十分な感じ。 UI のほうは Backbone.js で APIPython/Flask で作った。Python にしたのは Pygments が使いたかっただけ。

Pygments は py-gfm というライブラリと一緒に使うことで Github Flavored Markdown も扱えるようになる。それについては、「Python で Github Flavored Markdown をレンダリングする」 で書いた。

Backbone.js については使うのほぼ初めてで苦戦したけれど、慣れると確かにきれいに書けるなってことで気に入った。Angular よりいいんじゃないかな。(Angular 使ったことない人のご意見です)

あと _.debounce を覚えたので使った。(こういうの毎回自分で実装してた...) javascriptで発生するイベントを間引く - 終わる世界とコンテンツ

Fluid でネイティブアプリ化する

Web アプリとして作ったのでアクセスするには当然 Web ブラウザでアクセスするんだけど、ネイティブアプリにしたほうがよくわからないけどなんかかっこいい気がする。

node-webkit とか試してみたりもしたけど、モチベーションに対して頑張り過ぎな気もしたのでやめた。

そうこうしてたら Fluid という Web アプリをネイティブアプリっぽくみせかけるアプリを見つけたのでこれで適当にネイティブアプリ化した(ことにした)。

http://fluidapp.com/

先のスクリーンショットは Fluid を作ったので Web アプリなのにネイティブアプリっぽい見た目になっている。あと、アプリケーションのアイコンも設定できるようになる。iconfinder でフリー素材落としてきてつかった。

これでだいたい目的は達成できた。めでたしめでたし。

Scala.js が sbt プロジェクト以外でも使えるようになっていた

Scala.js 0.5.0 では standalone 版が配布されるようになりました。

http://www.scala-js.org/news/2014/06/13/announcing-scalajs-0.5.0/

これで sbt プロジェクトでなくても Scala.js が使えるようになりました。 以下の URL で配布されています。

http://www.scala-js.org/downloads.html

このパッケージには 3 つコマンドが含まれています。

  • scalajsc
  • scalajsld
  • scalajsp

scalajsc は Scala.js のコンパイラです。 scalac のラッパーになっていて、scalac を起動するときに Scala.js の jar もクラスパスに加えてくれるだけの単純なもの。

試して見ましょう。次のような Hello.scala を用意します。

package hello

import scala.scalajs.js
import js.Dynamic.{ global => g }

import js.annotation.JSExport

@JSExport
object Hello {

  @JSExport
  def hello(): Unit = {
    g.alert("Hello")
  }

}
$ scalajsc Hello.scala

すると、hello というディレクトリが生成されました。この中にクラスファイルが含まれています。

$ tree hello
hello
├── Hello$.class
├── Hello$.sjsir
└── Hello.class

0 directories, 3 files

sjsir ってなんだよって感じですね。これは Scala.js が生成する中間ファイルで、気にしないで良いですが、気になる人は scalajsp コマンドでのぞけるっぽいですよ。

$ scalajsp hello/Hello\$.sjsir
module class Lhello_Hello$ extends O ancestors O {
  hello__V(): <notype> {
    <global>["alert"]("Hello".cast[dyn])
  }
  $$js$exported$meth$hello__O(): any {
    this.hello__V();
    undefined
  }
  "hello"(): any {
    this.$$js$exported$meth$hello__O()
  }
  export "Hello"
  hello__(): any {
    this.hello__V();
    undefined
  }
}
;

生成されたクラスファイルをリンクして js を生成するには scalajsld コマンドを使います。 scalajsld コマンドには引数としてクラスパス(つまりhelloディレクトリ)を渡し、 出力先の js ファイルを -o オプションとして渡します。

$ scalajsld -o hello.js hello
Fast optimizing hello.js
Inc. opt stats: reused: 0 -- invalidated: 2726 -- trees read: 219

scalajsld のヘルプを見ればわかりますが、optimize の仕方は fastOpt(-f), noOpt(-n), fullOpt(-u) から選ぶことができます。デフォルトは fastOpt です。

これで、hello.js というファイルが生成されてめでたく使えるようになりました。

<html>
  <head>
    <script type="text/javascript" src="hello.js"></script>
    <script type="text/javascript">
      Hello().hello();
    </script>
  </head>
</html>

f:id:tototoshi:20140622004359p:plain

ちゃんと動いた。

sbt のプロジェクトどころか Scala のプロジェクトである必要もないですね。めでたしめでたし。

PHP の file_get_contents は get どころか post も put も delete も upload もできる

PHP

stream_context_create と組み合わせて使います。

手元でてきとーに動かしてた REST API とかで試してます。

get

普通ですね。

<?php
$content = json_decode(file_get_contents("http://localhost:5000/api/note/161"));

post

<?php
$context = stream_context_create(
    array(
        'http' => array(
            'method'=> 'POST',
            'header'=> 'Content-type: application/json; charset=UTF-8',
            'content' => json_encode(
                array(
                    'title' => 'file_get_contents で POST',
                    'raw' => "file_get_contents で POST\nPHP すごい...\n"
                )
            )
        )
    )
);

file_get_contents('http://localhost:5000/api/note', false, $context);

なるほど〜。file_get_contents は file_post_contents だったのか〜。

put

<?php
$context = stream_context_create(
    array(
        'http' => array(
            'method'=> 'PUT',
            'header'=> 'Content-type: application/json; charset=UTF-8',
            'content' => json_encode(
                array(
                    'id' => 162,
                    'title' => 'file_get_contents で PUT',
                    'raw' => "file_get_contents で PUT\nPHP すごい...\n"
                )
            )
        )
    )
);

file_get_contents('http://localhost:5000/api/note/162', false, $context);

なるほど〜。file_get_contents は file_put_contents だったのか〜。

delete

<?php
$context = stream_context_create(
    array(
        'http' => array(
            'method'=> 'DELETE'
        )
    )
);

file_get_contents('http://localhost:5000/api/note/162', false, $context);

なるほど〜。file_get_contents は file_delete_contents だったのか〜。

upload

<?php
$upload_content = file_get_contents('upfile.txt');

$context = stream_context_create(
    array(
        'http' => array(
            'method'=> 'POST',
            'header'=> 'Content-Type: multipart/form-data; boundary=-PHP_FILE_GET_CONTENTS',
            'content' => "---PHP_FILE_GET_CONTENTS
Content-Disposition: form-data; name=\"upfile\"; filename=\"upfile.txt\"
Content-Type: text/plain

{$upload_content}
---PHP_FILE_GET_CONTENTS
"
        )
    )
);

file_get_contents("http://localhost:5001/test_upload.php", false, $context);

なるほど〜。file_get_contents は file_upload_contents だったのか〜。

ひとこと

無理すんなや。