読者です 読者をやめる 読者になる 読者になる

亀岡的プログラマ日記

京都のベッドタウン、亀岡よりだらだらとお送りいたします。

ギルドワークス株式会社に入社してました

blog.guildworks.jp

報告が遅れてしまいましたが、転職してました。4/1よりギルドワークス株式会社勤務となっております。

とはいえ、やりたいこと・やってみたいことは変わっていませんし、これからもこちらで色々発信していきますので、よろしくお願いします。

主要活動場所もあいかわらず京都ですので、また皆様遊んでくださいませ〜。

メソッド名を考えるときに気をつけること

大学時代に、プログラミングだけでAO入試で入ってきて、部活に熱中しすぎて一年留年して、成績優良で某幸之助じいちゃんの会社に行った奴がいましてね。そいつにずっと言われてたのが

プログラムは自然言語としてよめるべき。コメントはいらないよ。

という話で、そのときは「いやいやwww」と思ってたけれど、最近の僕の思考は、もう「自然言語として読めるか」に尽きるようになってきた。

んで、こんな話。

booleanIshogehogeなのか?

そうであることは多いですよね。でも、例外も非常に多いです

たとえば、

Enumerable.Contains(TSource) メソッド (IEnumerable(TSource), TSource) (System.Linq)

LINQContainsメソッドIs始まりではないですが、これは拡張メソッドとしてインスタンスと結びつくとif(hogeList.Contains(fugaItem)みたいにかけるので、非常に可読性が良くなります。ひゃっほい!

インスタンスメソッドは確かに難しい

isBefore(fromDate, toDate)確かに難しいですね。寄せられた解答としては、

fromDateIsBeforeToDateは現実的な解決策だと思います。if文として読み下してみましょう。

if(fromDateIsBeforeToDate(hogeDate, fugaDate))

・・・うん、苦しい、苦しいですが、まぁ、なんとか!!頑張るなら、

これもありですよね。んで、個人的には、if(ComparableDate.From(hoge).IsBefore(Fuga)とか、静的メソッド使うかな。

「設計が悪いんじゃね?」

はい、僕も一票です。それ、ドメインモデル貧血症感は否めません。なんでそのクラスに持ってないのよ、という。

そう、思い浮かぶ言葉がごちゃごちゃし始める時ってのは、どう考えてもコードの悪い匂いです。僕の経験的にもそう。名前を付けられないオブジェクトやメソッドが出てきた時は、おそらく現実世界とコードが分離しすぎているサインです。

…まぁ、とはいえプリミティブクラス使わざるを得ない場面もありますよね。

拡張メソッドある言語ならそれで逃げよう

さて、C# やら Swift やら Kotlin やら、最近のモダンな言語には拡張メソッドという便利なものが有りましてね。

csharp.keicode.com

qiita.com

blog.codable.co.jp

これだとDate型を割と自然に拡張できます。本当は完全に設計から治すべきとは思いますが、人まずはこれで逃げることが僕は多いですな。。。

CircleCIでiOSビルド!(初級編: シミュレータビルドとテスト)

さて、最近ちょろちょろiOSの話をしているのは、そろそろSwift勉強せななぁ、と勉強し始めたわけでして。 でもなんというか、やっぱ言語そのものよりものの作り方を先にちゃんとしたくなるのはALMの性なのか。

とはいえ、XCodeVisual Studio以上にGUI至上主義を主張している気がします。iOSビルド時のDevloperライセンスとあいまって、ややこしいことこの上ありません。

しかし、最近のCIサービスはMacをサポートし始めましたし、Visual Studioオンラインにも、Xamarinとの関係できっと早晩にiOSビルドが乗っかると思います。 そんな時に焦らないよう、今のうちに動向を把握しておきましょう、ということでひとつ。

なぜCircleCI?

ビルドの並列性のみの価格体系で、並列ビルド一つまで無料、つまり実質(ビルド時間を我慢すれば)プライベートレポジトリが無制限無料、という恐ろしいサービスですのでね。。。 むろんWerkerなど、新しいCIサービスの料金体系はもっと安かったりしますが、iOSビルドをサポートしているのは、Travis・Circleの二大大手しかいない(2015/03/14現在)ので、iOSビルドをスモールスタートするならCircleCI超いいっすよ。

ひとまず、今回のゴールは、シミュレータ上でビルドを通すこととします。

なにはなくとも、iOSビルドを有効にしてもらおう。

さて、ここまできてなんですが、実はiOSビルドは標準では有効になっていません。Experimental Setting(実験的な設定)の中に項目がありますが、、、

これを有効にするだけでもダメです。

Warning: CircleCI has located an Xcode project or workspace in this repository. CircleCI is currently offering beta access to our iOS build system. Please contact support if you would like access. Once you have beta access, you can enable iOS builds in the 'Experimental Settings' section of the 'Project Settings' page.

というわけで、Betaアクセス権をもらわないといけません。

どうするかってゆうと、

ここからチャットウィンドウがひらきまして、

こんな感じで聞けます。ひどい英語ですが、一応通じてるっぽいです。 ちなみに解法はOrganization単位なので、お気をつけて(僕は対象Organizationを間違えて二回お願いしました) ほとんどルーチンワークなんでしょうけど、細かい質問もわりと答えてくれます。

スキーマを共有する。

さて、アクセス権を開放してもらったら、適当なコミットを入れてビルドを走らせましょう。CircleCIの設定ファイルは.circle.ymlですが、実はこれなしでもデフォルト設定で普通にビルドしてくれるのです。 デフォルト設定、というのはiOSシミュレータ上でテストを実行し、テスト結果をjUnitDoc方式でartifactとして保持」となります。

しかしながら、多くの場合だと、こうなってしまうのでは・・・?

No shared schemes were found in your repo. Please ensure you have shared your scheme. See the iOS documention for more information on sharing schemes. Alternatively, you can explicitly set a scheme with the 'XCODE_SCHEME' environment variable.

というわけで、スキーマの共有が必要です。 方法は・・・

で開く画面*1で、sharedにチェックを入れましょう。

これで、ひとまずはビルドが通るようになったはず。記念にビルドバッチを貼っておきましょうね。

Circle CI

実験用レポジトリ

このあたりの実験は以下で行っています。

参考

*1:なんだよこの頭おかしい階層構造…

iOSのipa作成方法はDeployGateが一番わかり易い

ブクマしようにもどこにも記述もなければリンクも取れないので自分で書いておくメソッド

内容はないよう

iOSipaファイル作成って、なんというか、非常にめんどくさい上にXCodeがアップデートされるたびに地味に方法が変わっているし、コマンドライン化するにしても、それ以前の設定でどうしても試行錯誤が必要だったりで、ひっじょーに検索しにくいんですよね。

んで、「こういうのはベータ配布サービスが詳しいやろ」とDeployGateのドキュメント見に行ったら非常にわかりやすかったので、メモ。

に行きまして、ここにいくと。

f:id:posaunehm:20150311010123p:plain

ここに。

まぁ実はこれでもXCode5準拠っぽくて、ちょっと違うんですけどね。 後は雰囲気で。

2015 MVP Community Camp~大阪~ の登壇資料「テストの5W1H」を公開しました

もうほぼ一月になろうかという所で、遅ればせながら公開させていただきました。

とはいえ、内容的に結構荒いのは自覚していまして、そのへんは頑張って今後洗練させていきたいなーと。

意見、ツッコミ、マサカリなどは遠慮なくなげてください。*1

*1:最後のはこわいけど逃げちゃだめだ逃げちゃだめだ逃げちゃry

C#使いから見たSwift

ビッグウェーブに乗り遅れないよう、Swiftをちょっと勉強してみたのでメモ。 勉強がてらに非常にまどろっこしいFizzBuzzを実装してみたので、そのコードを参考がてらにちりばめながら。

全体はここに。ほんとに、ただのまどろっこしいFizzBuzzですがw

気になった機能とか文法とか

変数と定数

letによる宣言にはやっぱりこころが若干ぴょんぴょんはする。

let x = "hoge"
// 再代入はコンパイルエラー
// x = "fuga" 

まぁでも、そこまで深い意味はなくてreadonlyconstのAliasと思っておけばいい気がする。値型だろうが参照型だろうがlet宣言できるし、参照型だったら参照先に変数があれば変更し放題ではあります。 ちなみに変数はvar

var y = "fuga"
y = "piyo"

関数宣言

とても式を宣言している感じがして良い。思考順序と合っている感じ好き。

public func convert (input: Array<Int>) -> Array<String>{
    return ["hoge","fuga","piyo"]
}

まぁ、個人的にはもう少し型推論して欲しいけれど。

Optional

んで、Optionalである。 なんと?をつけて宣言する。どこのNullableだ??

というわけで、たとえば引数にIntのOptionalを含む関数はこんな感じ。

public func convert(input: Int?) -> String{
    return ""
}

ちなみに、Optional<a'>みたいな型になるのではなく、その宣言された値かnillが入る。どこのNu(ry

中身を取り出すには!をつければOK。

public func convert(input: Int?) -> String{
    return "\(input!)"
}

ただし、これだと当然ぬるぽ、ではなくにるぽっておいうか実行時エラーになる可能性があるので、一般的にはifで束縛する構文を書けます。

public func convert(input: Int?) -> String{
    if let temp = input {
        return "\(temp)"
    }
    return "0"
}

とはいえ、上記程度なら所謂"null結合演算子"??が使用できる。

public func convert(input: Int?) -> String{
    return return "\(input ?? 0)"
}

だからどこの(ry

話はそれますけど、文字列に変数を素直に埋め込めるのいいですよね。

let x = うさぎ;
let str = "ご注文は\(x)ですか?"

そしてそして、Optionalで入っているかどうかの確認を大いにすっとばせるOptionalチェーンという呼び方も有ります。

public func convert(input: Int?) -> String{
    if let number =  input {
        return number.fizzbuzz()
    }
    return "???"
}

という書き方が正当な書き方ですが、optionalで渡された関数のメンバ変数として呼べる時のみ、

public func convert(input: Int?) -> String{
    return input?.fizzbuzz() ?? "???"
}

と、自分がnilならnilを返し、そうでないならメソッドを呼ぶ という事ができます。

・・・はい、そうですね、null 条件演算子演算子です。だからおまえはどこのN(ry

パターンマッチっぽいswitch文

関数型言語言えば、パターンマッチですよね!!専用構文はありませんが、Switch Case文が非常にそれっぽい仕上がりにできます。

通常のSwitch Caseは、、、まぁいいでしょ。普通にできます。 あとはTupleによるマッチ。

switch tuple{
    case let (left , 3): //Tupleの片方のみを定数束縛とかできる
        println(left)
    case let (0...3,right): //RangeでのマッチもOK
        println(right)
    default:
        println()
}

whereによる条件マッチなんかも出来ます。

private func convert(input: Int) -> String{
    switch input{
    case _ where input % 15 == 0:
        return "FizzBuzz"
    case _ where input % 3 == 0:
        return "Fizz"
    case _ where input % 5 == 0:
        return "Buzz"
    default:
        return "\(input)"
    }
}

あとはcaseラベルを複数流れさせるfallthroghとかもあるんですが、まぁあんまり好きじゃないのでパス。

関数オブジェクト

さて、関数オブジェクトです。とはいえ、関数宣言をそのまんまletなりvarで定義できる、という感じ。

private let internalFunction: Int -> String
public init(delegateFunction: Int -> String){
    internalFunction = delegateFunction
}

個人の好みとは思いますが、関数宣言を変数に入れると、Let SomeFunction: Int -> String みたいな書き方になって普通にカッコイイと思います(こなみかん)

クロージャの記法

んで、上記のような関数オブジェクトを作ると、当然クロージャの出番となるんです!が!

let SomeFunction: Int -> String = {(input: Int) -> String in
        return "Hoge"
}

なんでこんなにまどろっこしいの・・・

正確に書きますと、

{(引数名1: 引数の型1, 引数名2:引数の型2, ...) -> 返り値の方 in
    ステートメント
}

となってまして、ほんとにこれだけはまどろっこしいと言わせていただきたい。

まぁさすがにこんな書き方することは少なくて、例えばこんな型があって

public class DelegateFizzbuzz: FizzbuzzFunction{
    
    private let internalFunction: Int -> String
    
    public init(delegateFunction: Int -> String){
        internalFunction = delegateFunction
    }
}

これの関数の引数として*1関数オブジェクトを渡す際際には省略記法が書けます。 即ち、

  • 関数オブジェクトがその関数の最後の引数のとき、カッコから出してそのまま定義式に続けられる
  • 型推論が効くようになる

という2つの恩恵が受けられるため、

let fizzbuzz = DelegateFizzbuzz(){input in
                return "\(input)"
}

と、ここまで記述を減らせます。

さらにもう一歩進むと、上は全ての引数、返り値に関する型推論は完了しているはずで、ただ内部のステートメントinputという名前を使いたいがためだけに上記のような記法となっているわけです。 swiftでは他の言語では"Trailing Clusure"と呼ばれる記法が使用できます。これは、関数の引数を$0, $1, ... みたいに参照できる記法です。この記法を使うと最初の記述まで不要になり、

let fizzbuzz = DelegateFizzbuzz(){"\($0)"}

と、一行で書けるようになっています。

ただし、上記2つの省略記法は使用箇所がわりと限定されるので注意が必要ですね。

プロパティオブザーバ

さて、これもなかなかおもしろいなー、と思ったのがプロパティオブザーバ。これは何かって言うと、、、

var notifyProperty: String{
    willSet{
        println("\(newValue) will be set")
    }
    didSet{
        println("\(oldValue) has been replaced")
    }
}

こんな感じで、値が変更される直前にwillSetが呼ばれ、その中で新しい値newValueを参照できます。また、値が変更された時にdidSetが呼ばれ、今度は変更された後の値がoldValueで参照できます。 これの使いドコロは、、、やっぱUI周りでの通知でしょう。うまく連鎖させれば、通知の機構を組めそう。*2

拡張クラス

クラスを自由に拡張できます。例えば、int型の整数をFizzBuzzした文字列に変換する関数を考えてみましょう。

private func convert(input: Int) -> String{
    switch input{
    case _ where input % 15 == 0:
        return "FizzBuzz"
    case _ where input % 3 == 0:
        return "Fizz"
    case _ where input % 5 == 0:
        return "Buzz"
    default:
        return "\(input)"
    }
}

この処理を、int型の拡張として定義することができます。

extension Int{
    func fizzbuzz() -> String{
        switch self{
        case _ where self % 15 == 0:
            return "FizzBuzz"
        case _ where self % 3 == 0:
            return "Fizz"
        case _ where self % 5 == 0:
            return "Buzz"
        default:
            return "\(self)"
        }
    }
}

あとはこれを宣言している部分が見える状態(同じファイルに書くか、importする)にしてやれば、

1.fizzbuzz() // "1"
3.fizzbuzz() // "Fizz"
5.fizzbuzz() // "Buzz"
15.fizzbuzz() // "FizzBuzz"

と呼ぶことが出来ます。

プロトコル

実装を持たないクラス。これを継承した場合は、定義されている全てのメソッド・プロパティを実装しないといけない感じになっています。 複数継承可能です。

public protocol FizzbuzzFunction {
    func convert(input: Int?) -> String
}

・・・えっと、ようするにinterfaceです。以上!

いや、名前がいいなと思ったんですよね。確かに、これってクラス間の通信規約 = プロトコルだよなーと。

例外

・・・がないんです。意外。Optional使えということなんでしょう。

全体的な印象

さて、ざっと見ましたけれど、どう思いました?最も新しい言語らしく、うまくトレンドを取り入れている印象は強い。関数オブジェクトやクロージャあたりの書き方(省略記法のほうね)もそう。つまりこの言語って、「(C# | Java | Ruby | その他いろいろ)みたいな」言語なんですよね。恐らくかなりな言語やってる人が、「swift自分のしってる○○に似てる」と思うのでは。

そんな中で嬉しいところはコンパイルできて静的型付けされている、ということでしょう。Xcodeさんに色々不満もありますが、動的型付けでやるよりははるかにマシです。

だから、「ついに関数型言語の波がiOSに!!」みたいな最初の見た目に反して、そこまで突き抜けてる言語とは思えなかったかな。*3

結局、例外がなくて、ほぼNullableのOptionalであって、プロパティオブザーバみたいなUIに寄り添う機能があって、とかを見ていると、どうもswiftiOSのUI開発言語として割と特化しているのかなぁと。1割の人が使うすげえ言語機能をオミットする代わりに、9割の人が楽しくプログラミングできるように考えられている、気がする。

なので言語としては非常にコンパクト。iOSアプリをさくさくっと書いていくなら、きっととても楽しい言語に見えます。

読んだ本

ひとまず全部読んだのは、これ。

あと、Swiftの言語リファレンス的にこっちも買った。

詳解 Swift

詳解 Swift

他にオススメあれば教えるといいと思う!

*1:そういえばコンストラクタはinit関数なんよね。これもC#er的には面白い

*2:この辺りは、そもそもiOSMVC的なアーキテクチャどう組むのか分かっていなくて色々考える所なんですが

*3:CPUの歓声は僕には聞こえなかった。残念。

乗り換えてわかった。ASUS ZenFoneはとんでもなく名機

発売直後に手に入れたASUS Zenfone、割っちまいましてね… 

でも、MVNOに乗り換え済みだったので、慌てず騒がず、換えを買いに行ったわけです。んで、同じのを買うのもなー、と思いHUAWEIのAscend P7にしました。決め手はやはり、低価格帯スマホとしてはかなりレアなNFCを搭載してるとこですね。

先に言っときますけど、P7自体、そんなに悪い機種じゃないです。ただ、ZenFoneが良すぎるだけで。

ZenFoneの凄さ

ZenFoneは地味に電波のつかみが良い

さて、P7に乗り換えてまずはセットアップでハマります。電波の掴みが微妙なのです。奥まったところだと、割と電波が弱くなる、ようにエンドユーザの体験としては感じるのです。モバイルデータ通信のオンオフで復帰したりもするので、ハードよりもソフトかしらん、って感じもします。

ZenFoneのオリジナルホームUI(Zen UI)の出来が非常に良い

あと、ホームUIの完成度です。Acend P7のホームUIは、いわゆる「iPhoneぽい」ってやつです。Android独特の、インストールされてるアプリ一覧と、ホーム画面に出してるアプリ一覧ってのを敢えて区別していません。これはAndroidのカスタマイズが楽しいとこでもあり、わかりづらいとこでもあるので、これはこれで英断だと思います。
とは言え僕苦手で、ホームを変えたんですが、どうも標準ホーム以外の動作はあまり考慮されてない気がして、フリーズ頻発したので標準に戻しました。まぁ使えなくはないので仕方ない。
んで、ASUSのZenUIは素晴らしいです。Androidの中でちゃんと独自の世界観を築こうとしてます。What's Nextとかカッコいいし。適度なアニメーションと豊富なウィジェットで、Androidらしさを満足できます。

パフォーマンスチューニングが素晴らしい

でも一番イライラしちゃうのは操作全体のもっさり感。P7もそこまで遅いとは思わないけれど、比較しちゃうとZenfone圧倒的。とくにブラウザのレンダリングはかなり力入れてチューニングしたんじゃないかなー。もちろん、FullHDをあえて諦めている所も効いてそう。ハイビジョンを捨ててレスポンスのUXを高めたんだとしたら、大英断だと思う。

スペック競争を超えていきたい、けれど。。。

失敗した、とまでは思ってないけど、同じの買えばよかった!と割と思ってます。んで、強く感じたのは、ホント今更ですが、細かいスペックとかで比べてもどうしようもねーなー、という感じ。正直カタログスペックで比較するとZenfone、よくないんですよね。
先も言ったようにFullHDではないし、NFCもついてない。CPUもP7と比べるとコア数と同じものの、性能的にはぐっと落ちる。でも体験としての品質の高さは言うことなしです。
しかし、これ、どうユーザに伝えればいいんでしょ。僕も騙されちゃったし、MVNOとか契約しちゃう人は割とスペック見てしまうんじゃない?と思う。口コミとか、信頼貯金とか、そういうことなんだろうけれど、本当にこの凄さが多くの人に伝わっているのか、正直疑問であったりする。
なのでとりあえず、ここでは主張しておきましょう。格安スマホ、今はZenfoneを買っておくのがベスト。スペックじゃ測れない気持ちよさが有りますよん。

んで。

割れた画面でひとまず使うか(´・ω・`) もうすぐ新型でそうだしな(`・ω・´)


ZenFone 2 5インチモデルの実物写真が流出 | ガジェット通信