一発当てるより健康が欲しい
最近エンジニアとかWeb的な文脈であれやこれやと色々見かける中で「一発当てたい」というのを見つけたが、それについて僕が思ったことは
一発当てるより健康が欲しい
— hiromasa (@xoyip) 2015, 8月 26
である。
不健康(病気、怪我、メンタル)なときは仕事のこととかはどうでもよくなって何もやりたくなくなる。HPは黄色になるしMPもほぼゼロになる。健康あっての仕事だと思うので一発当てるよりも健康を獲得して安定した生活をおくるほうが僕にとっては重要度が高い。すでに健康極まりないって人は好きなことをやればいいので、一発狙うなりなんなりすればいいと思います。
いわゆる不健康自慢
あとはただの不健康自慢ということで不健康ツイートを最新からさかのぼっていってみる。
結膜炎じゃー!
— hiromasa (@xoyip) 2015, 8月 26
多分娘から映った。目が痒いです。
寒暖差アレルギーというらしい。鼻が止まらない
— hiromasa (@xoyip) 2015, 7月 31
エアコンが効いた部屋にいるとときどき鼻水とくしゃみが止まらなくなることがある。最近知ったんだけどどうやらこれはアレルギーの一種らしい。風邪に直結するわけではなさそうだった。
口内炎パッチを貼ったまま飯食ってたら気がついたらなくなってた。。。今ごろ胃の中だろうね
— hiromasa (@xoyip) 2015, 7月 29
口内炎は口の中を噛んだわけでもないのに頻繁にできる上、一度できると1週間以上苦しむことになる。食事は人生において最も楽しいことの一つだと思っているので、その食事を著しく制限する口内炎は本当に最悪。
定期的に通ってる呼吸器内科の先生にまで「痩せた?」ってきかれてしまった
— hiromasa (@xoyip) 2015, 7月 22
体重は順調に減っていて、最近は記憶にある中で最低クラスの57kg台に突入しようとしている。原因は運動しないことによる筋力の低下だと思われる。会う人会う人痩せた?と聞いてくるのですごく心配になる。
風邪引いたら喘息が悪化してて点滴まですることになったよ
— hiromasa (@xoyip) 2015, 3月 30
強靭な身体(免疫的な意味で)がほしい
— hiromasa (@xoyip) 2015, 3月 28
風邪引いたら喘息ぽい咳が再発してまた薬手放せなくなったでござる
— hiromasa (@xoyip) 2015, 3月 26
このへんは確か浜松Ruby会議直前に高熱を出し、その結果収まっていた喘息をぶり返して1ヶ月近く苦しんでいたときのツイートだと思う。大人になってから喘息を発症したけど本当に辛い。これから秋、冬になっていくとまた症状があらわれる可能性があるから注意せねば。
口内炎パッチが1枚100円近くすることに納得いかない。 pic.twitter.com/ZjlL8nm8ku
— hiromasa (@xoyip) 2015, 3月 6
また口内炎について書いてる。口内炎パッチ、もう少し安くならないかな…。
ツイートしてない中でもいっぱいあって、例えばまさに今日は腰が痛すぎて整体に行ったし、約一ヶ月前には夜中に吐いてしまい、妻を起こして夜間救急に連れて行ってもらったこともあった。
腰が痛いとか筋肉が減るとかはプログラマの職業病みたいなところがあるわけで、じゃあ体動かせばいいじゃんて話になるわけだけど、急に運動すると具合悪くなるのが常なのよね。
なんか悲しくなってきたので終わりにする。

ヘルシープログラマ ―プログラミングを楽しく続けるための健康Hack
- 作者: Joe Kutner,Sky株式会社玉川竜司
- 出版社/メーカー: オライリージャパン
- 発売日: 2015/07/23
- メディア: 単行本(ソフトカバー)
- この商品を含むブログ (6件) を見る
MPが足りない
今日はMPが足りなくて仕事ができないなーなどと思っていたらちょうど最近MPに関する記事がライフハッカーに載ってバズってたみたいでタイムリーだなーと思った話。
僕もはてブしました。
[L] 時間が足りないのではなく、MPが不足して何もできないとき | Lifehacking.jpまさに今MPが足りない。こういう時は消化すべきタスクリストとかがあると何も考えずに進められるんだけど、そうでもないときは本当に困る。
2015/08/25 12:28
MPが足りないとは
MPが足りないっていう表現はよく同僚とか妻にもしていた。僕はやる気が出ないとか、新しいことを始める意欲がないとか、気がすすまないとかそんなような意味あいで使っていた。
MPが足りないときには企画を考えるとかアイデアを出すとか、システムのアーキテクチャを考えるといったようなこと、言い換えると創造力が必要なことができない感じがする。逆にバグを直すとか、画面のレイアウトを少し修正するといった小さいタスクをこなすのは容易にできる。
頭を働かせることはできないが、ちょっと手を動かせば片付くような仕事はサクっと片付くという印象がある。ちょっとしたタスクをこなしている分には能率の低下は感じない。ザコ敵はMPが足りなくてもHPさえあればどんどん倒していけるわけ。
原因
どんなときにMPが足りなくなるのか。言い換えるとどんなときにやる気や意欲、想像力がなくなるのか。
- 体調を崩す(HPも足りない)
- 嫌なことを言われる
- Appleにリジェクトされる
- 睡眠不足
- 子どもがめちゃくちゃ機嫌悪い
など。もっと色々ある気がするけどあまり覚えていない。
AppleのリジェクトはものすごくMPを消費する、というか奪われる。まっとうなリジェクトでもテンションが下がるのに、半分ぐらいはレビュー担当者がちゃんと見ていないとか最初のリジェクトで一度に指摘してくれれば済んだのにとかって事態だとものすごいダメージになる。
同じアプリで何回もリジェクトされると「もういいわ〜」みたいな気持ちになる。いや良くないんだけど、そうなってしまう。
対策
今日の昼にMPを回復しようとして考えた。
MPを回復する方法をいくつか考えた。
運動。昼寝。甘い物。土いじり。Emacsの拡張、ブラウザ拡張、無料Macアプリあたりをあさる。
— おおの (@xoyip) 2015, 8月 25
大抵の場合は寝るのが良い気がする。睡眠不足のときってクリエイティブなことができないイメージがある。
運動も良さそう。あまり好きではないし膝が悪いからやらないんだけど、ランニング(ジョギング?)なんかは頭がすっきりしそうな気がしている。書籍「のうだま」でも読んだけど、運動をするとやる気を呼び起こす「淡蒼球」という部位が刺激されるらしいし、きっとそうなんだろう。それに運動すると気持ちがいいし。
Emacsとかブラウザの拡張とかを探し回るのはとても楽しいがあまり生産的な活動ではないので普段はやらないようにしている。かといって新しいものを何も導入したいのではつまらないので、MPが足りなくていまいち生産的ではないタイミングであえて新しい拡張機能を探したりするようにしている。今日はEmacsにスクロール関係の拡張を入れた。ツールが新しくなると使いたくなって仕事に戻れることもある。
あと、最初のライフハッカーの記事のブコメで瞑想がどうのって言ってる人がいたから少し調べてみた。
瞑想の状態ってのはよくわからないけど、ランニングしてると頭がクリアになることがあったからそれに近いのかなという気がしている。あの状態を運動せずに作れるなら楽かもね。
サボり?
MPが足りないとか言ってサボりじゃないかみたいな議論は起こりがちだと思うけど、やはり人間気が向いたときにやったほうが能率がいいしできるものも良くなると思う。少しぐらいダラダラしたっていずれMPが回復してフロー状態(ゾーン)のように仕事をできるといがきて挽回できるわけだし。
終わりです。

- 作者: 上大岡トメ,池谷裕二
- 出版社/メーカー: 幻冬舎
- 発売日: 2008/12
- メディア: 単行本
- 購入: 18人 クリック: 124回
- この商品を含むブログ (86件) を見る
Yosemiteで日本語入力が遅い問題が解決
昨年末にMacbook Pro 15inchに買い替えてからOS X Yosemiteで日本語入力が遅い問題にずっと困っていたのを、さっきおこなった対策で直せた気がするのでメモしておく。
まず、以前試していて少し改善したのがこれ。
Excel2011で日本語入力のスピードが極端に遅い | Apple サポートコミュニティ
フォントの重複が起こるのをFont Bookから解消するという話。
これでよくなった!と思っていたらそんなことはなくてしばらくすると再発するというのを繰り返していた。
Yosemiteでの日本語入力が遅すぎてつらい。特定のソフト上で遅くなる印象。ブラウザなど。 pic.twitter.com/BE6q7rb7oj
— おおの (@xoyip) 2015, 8月 21
特定のソフトというのは、ブラウザや一部のエディタ(Atomなど)、Evernoteなど。ATOK PadやEmacsのように遅くならないエディタもあった。
今日もいつものように「Yosemite 日本語 遅い」などとググっていくうちにこの方のブログに辿り着き、
アクセシビリティの設定で、次のようにアクセシビリティの設定で「コントラストを上げる」「透明度を下げる」の設定をONにすると解決しました。
このような対策をして解決したことがわかった。
ちなみにこの方、数記事に渡って色々な対策をしていくのを書いてくれているので、同じような問題に直面している身としては解決策を知るだけではなく途中経過も追えて良かったと思う。
「コントラストを上げる」「透明度を下げる」の対策後は問題のあったソフト上での日本語入力も問題なくできるようになった。ようやく解消してよかったという気持ちでいっぱいだが、もうすぐ新しいバージョンのOS Xが出るんだよなと思うと、また別の問題が起こりそうで面倒だ。いつもはすぐにインストールしていたが、今回はアップデート数回分待つぐらいのことはしてもいいかもしれない。
ところで、「コントラストを上げる」を選ぶと画面の雰囲気がそこそこ大きく変わる。
有効にする前(通常の見た目)はこれだが、
コントラストを上げるとこうなる。
でもすぐに慣れるので問題ないと思う。
SwiftでMicrosoft Azure StorageのAPIクライアントを書きました(書いてます)
最近はSwift版のMicrosoft Azure StorageのAPIクライアントを書いている。
Microsoft Azure Storageを管理するようなMacまたはiOSのアプリを書きたくてSwiftかObjective-Cで書かれたAPIクライアントライブラリを探したのだけれど、現時点ではそのようなものはないということがわかったのでSwiftを勉強しつつ自分で書くことにした(ここにそう書かれている→Microsoft Azure Storage Client Library for C++ v1.0.0 (General Availability) - Microsoft Azure Storage Team Blog - Site Home - MSDN Blogs)
このクライアントを使って書いたMacアプリは現在申請中でレビュー待ち。というか一回リジェクトされてしまった。
そもそもなぜMacアプリを書く必要があるのか、そしてそもそもなぜAWSではなくAzureなのか、ということに答える必要があるかもしれないけど、今回はその点はスルーすることにする。
MS Azure Storage
(ここ、間違っていたらごめんなさい)
MS Azure StorageにはBlob、Queue、Table、Fileという4つのサービスの総称で、AWSと対応させると大体こんな感じになっている。
Azure Storage | AWS | 用途 |
---|---|---|
Blob | S3 | ファイル |
Queue | SQS | メッセージング |
Table | DynamoDB | NoSQL |
File | (ない?) | ファイル共有 |
今回書いているAPIクライアントはこれら4つのサービスのうちBlobとQueueに対応しようと考えていて、実際主要なAPIはある程度実装できたと思っている。
ちなみにAzure StorageのAPIリファレンスはこちら。
ストレージ サービス REST API リファレンス | Windows Azure のテクニカル ドキュメント ライブラリ
設計
Swift力不足のためAPIクライアントをSwiftでいい感じに書くにはどうしたらいいのか全く検討がつかなかった。そこで「Swift API クライアント」などと適当にググって調べらとてもいい記事を発見し、記事やサンプルアプリケーションを見て良い感じだなと思ったのでほぼそのままの設計で実装することにした。この記事に感謝します。
設計方針はこの3つだそう。
目標としたのは以下の3つの条件を満たすことです。
この記事を読んでいただければ僕のライブラリでやっていることも全部わかると思うが、一応簡単に設計について触れておく。
クライアントの主要コード
クライアントの主要メソッドcall
の擬似コードを載せてみる。
public class Client { public func call<T: Request>(request: T, handler: (Response<T.Response>) -> Void) { // ① 成功時の処理 let success = { (task: NSURLSessionDataTask!, responseObject: AnyObject!) -> Void in let statusCode = (task.response as? NSHTTPURLResponse)?.statusCode switch (statusCode, request.convertResponseObject(responseObject)) { case (.Some(200..<300), .Some(let response)): handler(Response(response)) default: let userInfo = [NSLocalizedDescriptionKey: "unresolved error occurred."] let error = NSError(domain: "WebAPIErrorDomain", code: 0, userInfo: userInfo) handler(Response(error)) } } // ② 失敗時の処理 let failure = { (task: NSURLSessionDataTask!, error: NSError!) -> Void in handler(Response(error)) } // ③ リクエスト let manager = AFHTTPSessionManager() let url = scheme + "://" + host() + request.path() manager.responseSerializer = AFHTTPResponseSerializer() manager.responseSerializer.acceptableContentTypes = request.responseTypes() manager.GET(url, parameters: nil, success: success, failure: failure) } }
③の部分は単にAFNetworking
の呼び出しなのでここでは特に触れない。通信のライブラリとしてはAFNetworking
を選択した。同じ作者が書いたSwift版のライブラリ、Alamofire
のほうがSwiftらしく書けるのかもしれないけれど、一度も使ったことがなかったので今回はパスした。いずれ書き換えてみてもいいかもしれないと思っている。
次は短い②の部分だけど、これは単にエラーオブジェクトをcall
に渡ってきたハンドラに返している。
最後の①はレスポンスが正常に返ってきたときの処理で、ステータスコードとレスポンスから正しくモデルオブジェクトに変換できたかどうかで処理を分岐している。
全体を見ると、個々のリクエストに必要な情報(メソッド、パラメータ、HTTPレスポンスから得たいモデルオブジェクトなど)はリクエストオブジェクトから取り出して使うようになっている。そのためクライアントのコードは全てのリクエストに共通の処理だけ書いておけば良い。
レスポンス
クライアントのcall
メソッドに渡すハンドラにはResponse<T>
が渡ってくるようになっている。このResponseは値付きenum(というのかなんというのか…?)になっていて、成功時はリクエストオブジェクトが持つレスポンスの型に対応したモデルオブジェクトが、失敗時にはNSErrorを持っていることになる。
public class Wrapper<T> { public let value: T init(_ value: T) { self.value = value } } public enum Response<T> { case Success(Wrapper<T>) case Failure(Wrapper<NSError>) init(_ value: T) { self = .Success(Wrapper(value)) } init(_ error: NSError) { self = .Failure(Wrapper(error)) } }
クライアントの呼び出し側はこのようになる。response: Response<T>
でSwitchして成功時、失敗時の処理をしてあげる感じになる。
client.call(AzureQueue.ListQueuesRequest(), handler: { response in switch response { case .Success(let wrapper): println(wrapper.value) // AzureQueue.ListQueuesRequest.Response case .Failure(let wrapper): println(wrapper.value) // NSError } })
リクエストオブジェクト
さっき書いたようにリクエストオブジェクトには個々のHTTPリクエストで必要な情報を個別に定義して、クライアントから使えるようにしてある。
参考にした記事では
- パス
- メソッド(GET,POSTなど)
- モデルオブジェクトへの変換
- モデルオブジェクトへの型
などが書かれていたが、Azure Storageのクライアントではさらに、
- リクエストBody
- 追加のHTTPヘッダー(BodyのContent-Lengthなど)
- HTTPレスポンスのContent−Type
あたりを追加している。
public class ListQueuesRequest: Request { public let method = "GET" public typealias Response = Collection<Queue> public init() {} public func path() -> String { return "/?comp=list" } public func body() -> NSData? { return nil } public func additionalHeaders() -> [String : String] { return [:] } public func convertResponseObject(object: AnyObject?) -> Response? { return ResponseUtility.responseItems(object, keyPath: "Queues.Queue") } public func responseTypes() -> Set<String>? { return ["application/xml"] } }
Promise版の呼び出し
ここまで書いたことでAPIクライアントとしての機能は大体果たせるようになった。
ところでJavascriptなんかではよくあるように、非同期処理を待ってから次の非同期処理を書こうとするととても書きにくいという問題が、Objective-CやSwiftでAPIクライアントを書くときにも現れる。これはまあ放っておいてもいいのだけど使うときに便利なほうがいいと思ったので試しに対応してみることにした。
SwiftでもJavascriptのPromise的なアプローチを使えることができると知っていたので調べてみたところ次のようなライブラリが候補に挙がった。
決め手はなんだったかよく覚えていないが、上に挙げた3つのライブラリを全て試してみて最終的にBrightFuturesを採用してみた。
実装の際に参考にしたリンクはこちら。
BrightFutures版のクライアント
public class Client { public func future<T: Request>(request: T) -> Future<T.Response, NSError> { let promise = Promise<T.Response, NSError>() // ① 成功時の処理 let success = { (task: NSURLSessionDataTask!, responseObject: AnyObject!) -> Void in let statusCode = (task.response as? NSHTTPURLResponse)?.statusCode switch (statusCode, request.convertResponseObject(responseObject)) { case (.Some(200..<300), .Some(let response)): promise.success(response) default: let userInfo = [NSLocalizedDescriptionKey: "unresolved error occurred."] let error = NSError(domain: "WebAPIErrorDomain", code: 0, userInfo: userInfo) promise.failure(error) } } // ② 失敗時の処理 let failure = { (task: NSURLSessionDataTask!, error: NSError!) -> Void in promise.failure(error) } // ③ リクエスト let manager = AFHTTPSessionManager() let url = scheme + "://" + host() + request.path() manager.responseSerializer = AFHTTPResponseSerializer() manager.responseSerializer.acceptableContentTypes = request.responseTypes() manager.GET(url, parameters: nil, success: success, failure: failure) // ④ Futureオブジェクトを返す return promise.future } }
通常版と変わったのはcall
メソッドにハンドラを渡さなくなり、代わりにFuture
というオブジェクトを返すようになったことで、レスポンスが返ってきたときにはハンドラにモデルオブジェクトやエラーを渡す代わりにPromise
オブジェクトのsuccess
やfailure
メソッドを呼ぶようになっている。
BrightFutures版を使う側のコード
例えば、
- Queueの一覧を取得した後で、
- Queueを新しく生成し、
- 次にそのQueueを削除する
というAPI呼び出し(意味はないが)をしたいとき、通常版ではこのようになる(ひどすぎる…)。
func onError(error: NSError) { println(error) } func normal() { let req1 = AzureQueue.ListQueuesRequest() queueClient.call(req1, handler: { response in switch response { case .Success(let wrapper): let req2 = AzureQueue.CreateQueueRequest(queue: "brandnewqueue") self.queueClient.call(req2, handler: { response in switch response { case .Success(let wrapper): let req3 = AzureQueue.DeleteQueueRequest(queue: "brandnewqueue") self.queueClient.call(req3, handler: { response in switch response { case .Success(let wrapper): println("Success!!") case .Failure(let wrapper): self.onError(wrapper.value) } }) case .Failure(let wrapper): self.onError(wrapper.value) } }) case .Failure(let wrapper): self.onError(wrapper.value) } }) }
BrightFutures版では煩雑さは残るものの幾分かマシに書けるようになる。
func promise() { let req1 = AzureQueue.ListQueuesRequest() queueClient.future(req1).flatMap { response -> Future<AzureQueue.CreateQueueRequest.Response, NSError> in let req = AzureQueue.CreateQueueRequest(queue: "brandnewqueue") return self.queueClient.future(req) }.flatMap { response -> Future<AzureQueue.DeleteQueueRequest.Response, NSError> in let req = AzureQueue.DeleteQueueRequest(queue: "brandnewqueue") return self.queueClient.future(req) }.onSuccess { response in println(response) }.onFailure { error in println(error) } }
煩雑さの原因になっているflatMap { response -> Future<AzureQueue.CreateQueueRequest.Response, NSError> in
のようなクロージャの型の部分だが、これを省略してしまうと現状のXcode6.4ではambiguousとか言われてコンパイルできなかった。PromiseKitなどでも同じように見えるエラーに出会ったのでこのあたりはSwiftやXcodeの進化が必要なのかな。
とにかく、これでAPI呼び出しを順番にしたいという要求にも一応答えられるようになった。
あとPromise系のライブラリはそれぞれ進化が速いらしい。すぐに色々変わってしまうかもしれない。
テスト
プロジェクトをCocoaPodsのpod lib create
で生成したらデフォルトでQuick
というテストライブラリが入ってきたのでそのままこれを使った。Quickでのテストは書いたことがなかったが参考になるコード(後述)が見つかったのであまり苦労することはなかった。
テストはできるだけ書いておきたいと思ったものの、APIクライアントはAPIサーバーあっての話なのでテストはどうしようか迷って色々試した結果、今のように実際のAzure環境を使ったテストに落ち着いた。
Nocillaでスタブ?
最初はNocilla
というライブラリを使ってスタブしてテストを書こうと思ったが、マッチポンプ的あまり意味がない気がしたのでこれは却下することにした。
なお、Nocillaを使おうとして色々調べているときに見つけたサンプルコードがQuickでテストを書くときにも訳にたったので紹介しておく。
Azure Storage Emulator
次に試そうとしたのはWindowで動かすことができるAzure Storage Emulatorを使うことだ。ざっくり言うとAPIサーバーのエミュレータをローカルに立てられるというものらしい。ということはこれをMacに入れたVMWareとかで動かしておけばテストに使えるんじゃねーか(少なくともローカルでは)と考え色々準備してみた。
ところがクライアントの接続先にVMWareのIPを指定してもどうにもうまくいかない。3時間近く奮闘したものの何も得られなかったのでこの作戦も却下することに。
実環境でテストする
ここでようやく他の言語のクライアントではどうしてるんだろうということに気がついたので、Railsで使ったことがあるRuby版のクライアントを見てみることにした。
これのテストコードを見ると環境変数にストレージのアカウントやアクセスキーが設定されているときだけテストを動かせるようになっていた。つまり本物のAzure環境でテストを動かすよ、ということのようだった。
そういうわけでSwift版でも同じようにAzure環境でテストを動かすコードを書くことになった。テストコードを書くにあたってBrightFutures版が非常に役に立った。これをしてそれをして、最後にあれをしたらこうなっている、というコードを通常版で書こうとしていたらだいぶ辛いことになっていたと思う。
コード
もう1回貼っておきます。
宣伝
途中に出てきた表は自作のMacアプリで作りました。日本語入力で若干不具合があるけどMarkdownで表を書くときにはWebにある表生成ツール(Markdown Tables generator)よりも便利なのでぜひどうぞ。
Table2Text (Markdown, CSV)
カテゴリ: 開発ツール, ユーティリティ

- 作者: 荻原剛志
- 出版社/メーカー: SBクリエイティブ
- 発売日: 2014/12/10
- メディア: 大型本
- この商品を含むブログ (2件) を見る
CocoaアプリケーションでファイルやURLを開く
覚書でーす。
URL
NSWorkspace.sharedWorkspace().openURL(NSURL(string: "http://google.co.jp")!)
ファイル/フォルダ
NSWorkspace.sharedWorkspace().openFile("/Applications/")
SwiftでN文字ずつに分割した文字列を得る方法
例えば"hogefugapiyo"
という文字列があるとして、これを4文字ずつに分割するなら["hoge", "fuga", "piyo"]
、5文字ずつに分割するなら["hogef", "ugapi", "yo"]
を得たい。
Rubyであればscanメソッドを使って次のように実行できるということがわかった。
str = "hogefugapiyo" # => "hogefugapiyo" str.scan(/.{1,5}/) # => ["hogef", "ugapi", "yo"]
参考
これと同じことをSwiftでやりたくなったが、どうやら全く同じようなことをする関数はなさそうに見えた。なのでSwift力が足りないながらも自前で書いてみたのでそれを晒してみる。
Rubyの用にArrayを返す関数を追加するのでもよかったが、SequenceTypeを使うほうがよさそうな気がしたので↓のように実装した。String
にsubstr(Int)
という関数を生やして、それを呼ぶとforループやmapとかが使えるという感じになった。
extension String { var length: Int { return count(self) } internal class SubstringGenerator: GeneratorType { typealias Element = String let count: Int let string: String var i = 0 init(count: Int, string: String) { if count <= 0 { fatalError("'count' must be bigger than 0.") } self.count = count self.string = string } func next() -> Element? { if i < string.length { var endIndex : String.Index if i + count > string.length { endIndex = string.endIndex } else { endIndex = advance(string.startIndex, i + count) } var range = advance(string.startIndex, i)..<endIndex i += count return string.substringWithRange(range) } else { return nil } } } internal class SubstringSequence : SequenceType { let count: Int let string : String typealias Generator = SubstringGenerator init(count: Int, string: String) { self.count = count self.string = string } func generate() -> Generator { return Generator(count: count, string: string) } } func substr(count: Int) -> SubstringSequence { return SubstringSequence(count: count, string: self) } }
このsubstr
を実際に使ってみるとこうなる。
for substr in "hogefugapiyo".substr(5) { println(substr) } // hogef // ugapi // yo var array = map("hogefugapiyo".substr(5)) {$0} println(array) // [hogef, ugapi, yo]
どうですかね、これ。

- 作者: 荻原剛志
- 出版社/メーカー: SBクリエイティブ
- 発売日: 2014/12/10
- メディア: 大型本
- この商品を含むブログ (2件) を見る