UberがRuntime Validationを実現するRaveのv2を公開していた

HOW UBER ENGINEERING VERIFIES DATA AT RUNTIME WITH THE ANNOTATIONS YOU ALREADY USE を公開していた。
彼らが、Androidでよくある問題(NPEとか)に対して、model層の例えばAPIの結果をvalidationし、その結果が期待していないものなら必要な例外を投げて、意図しない値を不用意に使わないようにするとか、NPEになるようなExceptionの発生を抑制してしまおうとか、そういう話のようですね。この判定はRuntimeに行われます。

それにより、意図しないデータが帰ってきたとか(例えばnonnullなはずなのにnullがAPIで得られたとか)に対して必要な処理を実施できるようになる、と。


( reference from: https://eng.uber.com/rave/ )

https://github.com/uber-common/rave が対象となるリポジトリ。

Ecceptionを一様にCrashlyticsにnon-fatalで送るとか、クライアントのエラーログをサーバに蓄積するとかも良いですが、こういう形でそのエラーを区別できるようになると監視なども捗って良さそう。

[Kotlin]Kotlin in Action vol3

Kotlinを学んでいて、

みたいな感想を受けました最近。

class Button : Clickable, Focusable {
    override fun click() = println("I was clicked")

    override fun showOff() {
        super<Clickable>.showOff()
        super<Focusable>.showOff()
    }
}

interface Clickable {
    fun click()
    fun showOff() = println("I'm clickable!")
}

interface Focusable {
    fun setFocus(b: Boolean) =
        println("I ${if (b) "got" else "lost"} focus.")

    fun showOff() = println("I'm focusable!")
}

fun main(args: Array<String>) {
    val button = Button()
    button.showOff()
    button.setFocus(true)
    button.click()
}

Kotlin、このように複数interfaceを受けてsuperで順序選択するんですね。
Kotlinでは、初期では final がデフォルト。open class Hoge : Neko {} を使う場合、そのクラス内で宣言されるoverrideなんかは open が暗黙的に宣言されるので、final にしたい場合は final を宣言する必要があるらしい。

まだ先は長いですが、徐々にKotlinに取り組むことができ始めた。

[Swift]try!Swiftで学んだことまとめ

私は職場で作ってきたテストの話のうち、UI Testに近いところの話をしました。

英語での発表は初めてだったのですが、一部想定通りに話せなかったところがありながらも無事に終えることができ、ホットしました。日本以外から来た人含め、いろんな人から英語も聞き取りやすかったし内容も良かったと言って貰えて、ひとまず安心しました。

お題の悩み

私はSwiftを使ったテストの話(Unit Test)をするかとか、protocolベースのDIの話をテストに絡めるか、UI Testの話をするか悩んでいました。

推薦されたことで話すことができるようになったので、try!Swift全体の中でそれぞれの話す内容が重ならない程度の話題にした方がバリエーション豊かになって良いかなと思い、UI Testsやその周辺の話をしました。

ただ、このレイヤの話はSwift自体でそこの話をするにはネタがない。XCUITestとかだとSwiftではなくiOSフレームワークの話になりますしね。半端にSwift x XCUITest(内部コードとか)の話をするよりは、テスト全体とUI Tests、Re-Engineeringnの話をする方が独自性を持った話ができるかと思い、結果的には話すことにしました。

結果的には、unit test関係で想定していたセッションの内容は他のスピーカーの方々が行なっていたので、重ならずに良かったかもしれません。

運営の方からは良かったとフィードバックをいただけたので、推薦いただいたことに対しては役目を果たせたと感じてはいます。

他のセッション

すでに nowsprinting さんがまとめを書いていたので、テストに関してはそこにお任せ。
http://nowsprinting.hatenablog.com/entry/2017/03/05/061441

内容自体はprotocolやstruct付近を使った話で、functional programmingもかじっていると理解を深めることができる内容でした。

The Two Sides of Writing Testable Code

ここで出てきた “co-effect” に関しては以下が参考になるらしいので、少し読んでみようと思います。

ReactNative

3日目のハッカソンでは、その間に行われたReactNativeのゲリラワークショップを経験しました。

ReactNativeのテストには、JSレベルでは jest、UIレベルだと testID を付与してからのUI Test系ですね。
JSの世界でテストが実行できると、unit testでもXCTestよりも素早くテストのサイクルを回すことができて良いですね。

最後に

本当にお疲れ様でした & ありがとうございました

「Swift実践入門」を読んだ

同僚や、知人が書かれていることもあり、Swift実践入門を読んでSwift言語への理解を深めてみました。

私個人のスキルでいうと、公式のThe Swift Programming Languageの2.1向けのものや、Functional Swiftとかの英語書籍を読んだり写経したりして簡単なSwiftプログラムを書いたり読んだりはできる感じです。iOSエンジニアとして会社でコードを書き続けているわけではないです。

内容は、うろ覚えだったり把握していなかったとところを補足することができ、言語自体の学びを整理することにとても役立つ書籍でした。iOS周辺の開発になると、こことは別にAPIへの理解も必要なのですが、私はそこはまだまだ足りていない…

全体的に、Swiftの様々な機能をどういう形で使うと良いのか、というところで参考になりました。以下、私が読んでいてメモしておきたかったところをメモしておきます。

2章

Swiftにおける範囲型、Optionalの話とか、復習になった。特に、 ?! のforce unwrapの話。実行時に評価されて無理やり値を取り出す ! と、 .none になる ? の話とか。

テストコードだと、例えばEarlGreyのようなやつだと実行時評価が必要なことが多く、 ! を使ったりしていた。けれど、Swiftの理想でいうとやっぱり ! は思想に反する(実行時にしか評価されないし、クラッシュするし)のでやぱりよくないのだなーと。

as? によるダウンキャストや as! as? によるアップキャストの話もちらほら。

3章

switch の制御で以下のようにかける形、Erlang/Elixirを学んでいたので自然な感じだった。こういうの書き始めると、Androidの世界にも時折欲しいと思う時がある…

switch a / 2 {
case let b where b < 2:
    print("lower than 2")
case let b where b >= 2:
    print("more than or equal to 2")
default:
    print("no")
}

繰り返しの for ... in ... {} は使ったこともあるのですが、 case 使う場合もinを支えたのですね。把握していなかった…

for value in 1...4 { print("\(value)") }
for case let (2, value) in [(1, "a"), (2, "b"), (3, "c")] { print("\(value)") }

switchの中、 break を置くことはよくやることですね。Javaとかやっていると。これ、breakしないと多くの場合は次々と case を実行していくのですが、swiftでは明示的に fallthrough を与えないといけないのですね。

let a = 10

switch a / 2 {
case let b:
    print("first")             // "first\n"
    fallthrough
case 5:
    print("after fallthrough") // "after fallthrough\n"
    break
    print("after break")
default:
    print("no")
}

あと、 breakやcontinueの遷移先を制御するために label をつけることができるとは知らなかった…

4章

@discardableResultがあったのですね。 _ = someMethods で処理を書いていた。どのみち、使わない、使わなくて良いことを明示するスタイル。

Swift、以下のような形で副作用をもたせた書き方もできたのですね。JavaとかRubyといったオブジェクト指向の書き方では書いていたのですが、Swift(のstructとか)Elixirとかみたいな関数型をメインで触っていると、こういうことが頭から離れることが多い…

func add(_ x: Int, _ y: Int, _ a: inout Int) {
    a += x + y
}

var a: Int = 10
add(10, 10, &a)
a // 30

7章

protocolの話。
Swiftはprotocol oriented programmingと言われるように、このprotocolが重要になります。
associatedTypeによる、protocolでは抽象的な文字を定義しつつ、具体的な型はそれを受け継いだstructなどで定義する。それらの定義は明示しなくとも類推されて補完されもします。個人的には、Swiftは明記によって安全性を表現しているので、推論ばかりに頼りたくない(明示していきたい)なーとも思います。

protocol SomeProtocol {
    associatedtype AssociatedType

    var value: AssociatedType { get }
    func someMethod(value: AssociatedType) -> AssociatedType
}

struct SomeStruct : SomeProtocol {
    typealias AssociatedType = Int

    var value: AssociatedType
    func someMethod(value: AssociatedType) -> AssociatedType {
        return 1
    }
}

struct SomeStruct2 : SomeProtocol {
    var value: Int
    func someMethod(value: Int) -> Int {
        return 1
    }
}

struct SomeStruct3 : SomeProtocol {
    struct AssociatedType {}

    var value: AssociatedType
    func someMethod(value: AssociatedType) -> AssociatedType {
        return AssociatedType()
    }
}

指定する型とそれを受け継いだサブクラスの話。
それら。

where 句によるprotocolに対するextensionの制御の話。例えば、以下だとWebContentの型を持ったやつ。

protocol Item {
    var name: String { get }
}

protocol WebContent {
    var url: String { get }
}

extension Item where Self : WebContent {
    var description: String {
        return "hi"
    }
}

struct EBook: Item, WebContent {
    let name: String
    let url: String
}

struct Book: Item {
    let name: String
}

いくつかの標準ライブラリに付与されるプロトロル。

8章

Any関数はダウンキャストが必要。

if let int = something as? Int {
  // something
} else {
  // else
}

なので、ジェネリクス良いですね。

10章

参照型のクラスと、値型の構造体。その選定基準がとても為になった。

クラスは参照型なので、新しくインスタンスを作ってもそのインスタンスに保持されている値はつながっている。つまるところ、副作用がたくさんあるということですね。一方、structはimmutableに物事を扱うことが可能、と。

class Temp {
    var c: Double = 0
}

class Country {
    var temp: Temp

    init(temp: Temp) {
        self.temp = temp
    }
}

let t = Temp()
t.c = 25
let c1 = Country(temp: t)
t.c = 40
let c2 = Country(temp: t)

c1.temp.c
c2.temp.c

そのため、クラスは何らかのライフサイクルに添いたいところや参照を共有する必要がある。

11章

OptionalとImplicitlyUnwrappedOptionalの使い分けの話。どう使うべきか、という話。
クロージャを使うときの、キャプチャリストと weak / unowned の違い、その使い分けも。

let closure = { [weak object1, unowned object2] () -> Void in
    print(object1)
    print(object2)
}

第11章の話の中では、いくつかのデザインパターンの説明も出て来た。これは通知をやり取りするための手法として。その中にObserverパターンがあった。

import Foundation

class Poster {
    static let notificationName = Notification.Name("SomeNotification")

    func post() {
        NotificationCenter.default.post(name: Notification.Name("a"), object: nil)
    }
}

class Observer {
    init() {
        NotificationCenter.default.addObserver(
            self,
            selector: #selector(handleNotification(_:)),
            name: Notification.Name("a"),
            object: nil)
    }

    deinit {
        NotificationCenter.default.removeObserver(self)
    }

    @objc
    func handleNotification(_ notification: Notification) {
        print("I got a message")
    }
}

var observer = Observer()
let poster = Poster()
poster.post()

12章

非同期処理の話。GCD(Grand Central Dispatch)をSwiftから使う話とか。DispatchQueueの話。Foundationに含まれる Operationを使った話も。
ここら辺はやっぱり複雑なところになるので、中身を調べた上でなにかのライブラリに乗っかりたいですね。

13章

Resultによるエラー処理の話などだった。enumで定義した成功/エラーを switch を使って分けていく方法ですね。

enum Result<T, Error> {
    case success(T)
    case failure(Error)
}

Erlang/Elixirの {:ok, xxx}{:error, xxx} に対するパターンマッチなどん処理を思い浮かべました。
毎回 switch を書く必要もありますが、ここは将来パターンマッチ含まれるともっとErlang/Elixirに似た記述になりそうですね。

do-catchはまとめてエラー処理を描きたいときなど

エラー処理の選定

エラー処理を行う --no--> リリース時のプログラムの
    |                        終了を許容 ----no--> assert
   yes                             `----yes---> fatalError(_:)
    |
エラー処理の詳細が必要 ----------------------no--> Optional
    |
   yes
    |
同期処理 ----------------------------------no--> Result
    `------------------------------------yes-->  do-catch

まとめ

この書籍、やっぱり良いですね。Swiftに関して、言語仕様ではなく経験からどう使うと良いのか、という話がまとまっている。
これを読む/読まないで知識のつけ方が大きく変わりそう。

ありがとうございました。

[Mac][RedwoodHQ]Run on Mac

RedwoodHQ on Macを過去書いた時点ではMacで動かすことができていなかったのですが、最近見て見るとLinux/Mac上でも動作するようになっていました。

http://redwoodhq.com/redwood-download/

からダウンロード・展開して、

$ ./start.sh

を実行、 http://172.0.0.1:3000 へブラウザからアクセスする、です。私はNode 4.7.2で実行していました。

ちなみに、このRedwoodHQは以下にフォークされてPRなどが取り込まれていました。

https://github.com/wolterskluwer-redwoodhq/RedwoodHQ

もともと作ってた人は退いたのかな。

[Java][Android]Error patternを検出する

Google製のFindBugsみたいなもののようです。

これのパターンに何があるのかは以下に書かれていました。

ざっと見てみると、DaggerなどのDIツールを使っている時のルールもありました。
独自ルールも追加できるみたいですね。

なので、何らかの自社製ライブラリへ適合させる時も使いやすいのかな。


Bazelを見ると、Bazelではすでにこれが組み込まれてて、デフォルトONなのですね。

https://github.com/bazelbuild/bazel/blob/c4e92b1ba06fba48121e4db8050a69b6d998e2e9/src/java_tools/buildjar/java/com/google/devtools/build/buildjar/BazelJavaBuilder.java#L108

もう少し話がそれると、Bazelでは以下がデフォルトで組み込まれているのですね。

https://github.com/bazelbuild/bazel/blob/c51d506eb83f1e5974e3317c53532f6e81ca50d8/third_party/BUILD#L310


以下、試しに適用してみたコミットになります。

これに対してビルドすると、generated codeに対してwarningが確認されました。
内容は http://errorprone.info/bugpattern/MissingOverride なのですが、ここら辺を見ているとGoogleのJava style gideに合致しているかも見ているのですね。

[app]fuse

ちょうど、 https://www.fusetools.com/ というツールを見つけたので触ってみた。

期待としては、やっぱり簡単にアプリの雛形を作ることができ、その雛形を参考にAndroid/iOSの各プラットフォームでプロダクトを開発することができる状態でしょうか。

少し触った感じ、previewがうまく動かなかった…
マシンスペックも関係するのか。。。
まだBetaなので、もう少ししたらまた触ってみよう。

こういうのを試してみようとした。
https://www.fusetools.com/examples/circle-menu