Google Play services out of date
問題
Androidアプリ開発時以下のようなログが出力され、アプリが落ちることがあった。
Google Play services out of date. Requires xxxxxxx but found yyyyyyy
xxxxxxx や yyyyyyy バージョン番号。
解決
「Google Play 開発者サービス」アプリをアップデートする。
もしかしたら、アップデート後 Android Studio を再起動する必要があるかも。 なぜかというと、アップデート後 マニフェストファイルにパーミッションを追加せよ、というエラーが出力された。でも、そのパーミッションはすでに追加されていた。Android Studio を再起動したところその問題は解消されたので。
リンク
UNIXの哲学と関数型プログラミング
UNIXの哲学と関数型プログラミングは共通しているところがあるよね、というのを最近同僚と話した。
ここでいうUNIXの哲学とは
- スモール・イズ・ビューティフル
- 一つのプログラムには一つのことを うまくやらせる
- ソフトウェアの挺子を有効に活用する
など(「UNIXという考え方-その設計思想と哲学」より)。
それらと、関数型プログラミングの、一つの機能に絞った小さな関数を組み合わせ、大きな関数を作っていくという部分が似ているなと。
とりわけ強くそう思うのが、UNIXでコマンドをパイプで繋げて自分の期待する結果を得るところ。関数型プログラミングだと、関数合成にあたる。
UNIXの操作に慣れている人なら、関数型プログラムもしっくりくるのでは。
PHPのjson_encode
少数点以下の数が0の場合はコンパクトになる!
<?php echo json_encode(['foo' => 123.45, 'bar' => 658.00]) . PHP_EOL; # => {"foo":123.45,"bar":658}
これが原因か...
不正なHTTPヘッダ
リバースプロキシとしてアプリケーションの前にnginxを置いている.
あるとき, アプリケーションにリクエストヘッダが渡らないんですけど, という問い合わせがきた.
うーん, 自分が使っている分にはヘッダは渡ってきてるんだけどな...
とりあえず, どんなリクエストを投げてるのか教えてもらったので, 試してみたところ, 報告通りヘッダが渡ってこない.
nginx を通さずに直接アプリケーションにそのリクエストを投げるとヘッダが渡ってきた. 原因はnginxにあることが判明した.
どうなっているかを把握するため debug ログを出すことにした.
/etc/nginx/nginx.conf
- error_log /var/log/nginx/error.log warn; + error_log /var/log/nginx/error.log debug;
すると以下のログが出た.
2015/01/21 09:00:16 [info] 3057#0: *2 client sent invalid header line: "X-Hoge : 1234" while reading client request headers, client: 127.0.0.1, server: localhost, request: "GET / HTTP/1.1", host: "localhost"
client sent invalid header line
...不正なヘッダを送っているため、nginx で落とされているようだ.
rfc2616 によると Message Header は
message-header = field-name ":" [ field-value ] field-name = token
となっていて, token は
token = 1*<any CHAR except CTLs or separators> separators = "(" | ")" | "<" | ">" | "@" | "," | ";" | ":" | "\" | <"> | "/" | "[" | "]" | "?" | "=" | "{" | "}" | SP | HT
となっている.
field-name と ":" の間にコントローコードやセパレータががあってはいけない.
今回は field-name と ":" の間に空白があるため, 不正なヘッダとして扱われたようだ.
nginx の設定で ignore_invalid_headers をoff にすればヘッダを落とさずにアプリケーション側に投げてくれる.
けど, まあ空白なしがRFC的に正しいので, 空白を削除してリクエストを投げてもらうことで解決.
Data.Sequenceメモ
高速なキューData.Sequence.
空のキュー
Prelude Data.Sequence> empty fromList []
キューの先頭に要素を追加
Prelude Data.Sequence> 1 <| 2 <| 3 <| empty fromList [1,2,3]
キューの末尾に要素を追加
Prelude Data.Sequence> empty |> 1 |> 2 |> 3 fromList [1,2,3]
先頭から要素を一つ取り出す
Prelude Data.Sequence> viewl $ 1 <| 2 <| 3 <| empty 1 :< fromList [2,3]
viewl は Seq a の a を返すのではなく, ViewL a を返す。
Prelude Data.Sequence> :t viewl viewl :: Seq a -> ViewL a
ViewL のパターンマッチ
foo :: ViewL Int -> Int foo EmptyL = -1 foo (x :< xs) = x
末尾から要素を一つ取り出す
Prelude Data.Sequence> viewr $ 1 <| 2 <| 3 <| empty fromList [1,2] :> 3
viewr の場合は ViewR a が返る。
bar :: ViewR Int -> Int bar EmptyR = -1 bar (xs :> x) = x
畳み込み
Seq a は Foldable クラスのインスタンス。
import Data.Sequence import qualified Data.Foldable as F foo :: Seq Int -> [String] foo = F.foldr bar [] where bar :: Int -> [String] -> [String] bar x ys = show x : ys
*Main> foo $ 1 <| 2 <| 3 <| empty ["1","2","3"]
今のところ、これらだけでなんとかなっている。
変数のスコープ
日頃 JavaScript を書かないのがたたって、変数のスコープがどこまで有効なのかわからなかった。
問題となったのは以下のコード。変数hoy
はcatch
節でも有効なのかどうか。
try { var hoy = "HoyHoy"; throw "exception"; } catch (e) { console.log(hoy); }
結果はというと、有効でした。
% node hoy.js HoyHoy
試した環境は
% node -v v0.10.33
以上、本日のメモ。