ushumpei’s blog

生活で気になったことを随時調べて書いていきます。

PhRUG(Philippine Ruby Users Group) September 2017 Meetupに行ってきた

 最近フィリピンに滞在しています。2017/09/21にフィリピンのRubyユーザーグループのイベントが行われるということで、海外勉強会ってどんな感じだろう?日本と違いがあったりするのかな?とか思い参加してきました。たくさん写真撮ってくるの忘れました。

 とりあえず結論、強く思ったのは、フィリピンでも日本でも、技術系の勉強会は大体同じ雰囲気、ということです。

概要

 イベントはmeetupから発見しました。PhRUG September 2017 Meetup  会場のホストはShield Foundryというベンチャー企業で、HPも綺麗な感じです、ただHPを見ても何を作っているかはよくわかりませんでした。場所はShield Foundryのオフィス、マニラのBGC(Bonifacio Global City)にあります。BGCにはいったことなかったですが、未来っぽい町でした。外資系企業がたくさんあるみたいで、金持ちが多いみたいな話です。

 余裕を持って会場へ向かったのですが、交通渋滞、ビルを間違える、などのアクシデントで、会場に着いたのは開始30分後くらいになってしまいました…

 会場のShield FoundryはいかにもITベンチャーといった感じでした。広さは3~40畳くらいで、オフィススペースとキッチンスペースに分かれています。オフィススペースには長机に沢山の椅子(アーロンチェア?)、各椅子の前の机にiMacとモニターがずらりと並んでいます。それぞれ漫画とか本とかも乗っていました。その他、バランスボールあり、サッカーボールあり、あとサッカーのアレ(二人でバーを回してボールを蹴り合うゲーム)もありました。テック系は世界共通なんだな、と少し安心しました。

 受付を済ませてプレゼンしているキッチンスペースに入ると、ビール手渡され、真ん中のダイニングテーブルにはピザが置いてあり、ご自由にどーぞといった感じでした。  

イベント

f:id:ushumpei:20170923211805j:plain

 最初の発表は、会場に到着したときは既に始まっていて、ちょっと詳細がわからなかったです…。発表者はエンジニアの一日、のようなスライドを表示していました。とりあえず自分はタガログ語が一切できないので、英語でプレゼンしていてホッとしました。ただ英語がそこまでできるわけでもないし、トピック不明だったのでなんとなく頷いたりして過ごしました。

 2番目の発表はrailsのパフォーマンス改善やテストなどの発表でした。bootsnap, PhantomJS, rack-mini-profiler, New Relic, その他諸々、をそれぞれいい感じに使って、計測、改善したよ!という感じです。そうですよね。納得な感じです。

 3番目の発表はjupyter/notebookを使って見た系の発表。マークダウン + コードでドキュメントかけるやつです。これ自体は先輩に教えてもらっていて知っていたのですが、バグレポートとかに使って、楽に可視化していこうよ!といった、やっぱりそう考えるよね的な共感を持ちました。

 4番目の発表は、開発Tipsの紹介でした。gitprecommit-hookでコミット前にrubocopしてます、とか。railsのサーバープロセスの優先順位あげたらなおった、とか。やっぱりコミット前にちゃんとしておきたいと思うよね!という再度、強い共感を持ったりしました。

感想

 会が終わった後にエンジニアの方にフィリピンのプログラミング言語事情について尋ねて見たところ、大企業とか、求人の多さで言えばjava, phpベンチャーruby, pythonといった感じです。scalaはとてもいい言語だと思うけど学習コストが高いのと、まだ事例をそこまで聞かない、とのことでした。日本では既に事例があるので、このあたりの情報共有とか何かできるかも(逆もあるだろうし。そういえばtwitterは?scalaの事例としてはどう捉えていたのだろう?国内事例がない、という感じなのだろうか?)。

 フロントエンドのjavascriptフレームワークに関しては、angular2, reactjavascriptフレームワークはリッチすぎて、本当に欲しいものがその中の1つだったりする、という日本でも割と聞く話を伺うことができました。ionicでネイティブを、とかいう話題もちらほら聞くようです。

 ここまで書いて、強いて挙げるならフィリピンと日本のIT界隈の相違点はなんなのだろうか?という方向に思考が向かいました。フィリピンの方が学歴に関して厳しいのかな?という予想を最近持っていますが、まだちゃんと議論したことがないので結論としては不十分と思います。さらに交流を重ねなければと思います。

 参加する前はブログを書くつもりがなかったため、少々微妙なレポートになってしまいました。来月もグループがあるそうなので、もし行くとなればもっといい感じにレポートしたいと思います。meetup便利です。

iOS11アップデートについていくためのSwift入門(主観)

 2017/09/20に、iOS11がリリースされました。今回のアップデートでは機械学習やSiriアプリ、ARなど様々な新機能が使えるようになりました。リンクを見ていて、「ちょっとSwift読めるようになっておかないと、おそらく半年くらいつまらなくなってしまう…上がってくるニュースを見ているだけになってしまう…」と思ったのがこの記事を書こうと思ったきっかけです。

 リファレンスとしてはAppleのサイト、The Swift Programming Language (Swift 4): A Swift Tourを使います。学習の目的はSwiftのコード(主に今後発表されるであろう「iOS11で追加された〇〇を使って見た系の記事のコード」)を読めるようになることです。

 Hello, world!を目標、と思ったのですが、ベタ書きで終わってしまいました。

print("Hello, world!")

概要

 リファレンスの内容は、Swiftを書き始めるのに十分な知識を得るためのツアーです。記事がSwiftのプロジェクトとしてまとめられていて、ダウンロードできるのでそれを使って学習していきます。

 セクションは次のようになっています;

  • Simple Values
  • Control Flow
  • Functions and Closures
  • Objects and Classes
  • Enumerations and Structures
  • Protocols and Extensions
  • Error Handling
  • Generics

 本記事ではリファレンス内に記載されている情報で、主に書き方に関することをメモしていきます。すでに序文の時点で以下の二点が記載されています;

  • グローバルスコープの処理は勝手に実行されるので、エントリーポイントとしてのmain関数が必要ない
  • 文末にセミコロンは必要ない

Simple Values

  • 変数宣言について、定数はlet、通常の変数はvarで宣言する: var hoge = 1とか。
  • 明示的な型の宣言はlet piyo: Double = 70 (後置型宣言)
  • \()で文字列に変数を埋め込める。"template \()"
  • 3ダブルクォート"""で複数行の文字列を囲むことができる
  • 配列リテラル["hoge", "piyo",]が使用可能
  • [“hoge”: 1, “piyo”: 2]辞書も可能
  • 空の辞書は[:]

Control Flow

  • if, switch, for-in, whileとかありますがこの辺は不思議なさそう
  • 型?でOptionalな変数を宣言できる(例var hoge: String? = "hoge")
  • if let hoge = { ... }でOptional変数から値を取り出すことができる、取り出すことができたらブロック内の処理を実行するという記法
  • if var piyo = { ... }ともかけるが、多分そんなに使わない
  • 取り出した変数のスコープはブロック内
  • その他にOptional変数を扱う方法としては、??を使って、defaultValue ?? optionalValueと言うように記述すると、値が取り出せる時のみ使用される
  • switchcasedefaultで構成していきます。breakは不要、defaultは必須です。
  • 0..<4で、0,1,2,3の範囲のレンジを作成できる

Functions and Closures

  • 関数定義はfunc、引数の定義はhoge: String(後置型宣言)、アロー->で戻り値の型を記述: func hoge(hoge: String) -> String { ... }
  • 引数を名前付きで渡すことができるhoge('fuga', piyo: 'giyo')これは定義時にfunc hoge(_ hoge: String, piyo fuga: String)と言うようにする。引数のラベルと言うもので、_はラベルなしを意味する。
  • 高階関数も作れる: (Int) -> Intとかで型を宣言
  • クロージャ使える:
{ (hoge: Int) -> Int in // クロージャの型と変数名
  return hoge * 2
}
  • 場合によっては型も省略できるらしいので、{ hg in ... }とかブラケットとinが出てきたらクロージャとして読む。引数も$0, $1と順番で記載されることがあるので、{ $0 < $1 }とか書かれていても混乱しないように。

Objects and Classes

  • クラスのインスタンス化はClassName()
  • フィールドはベタ書きでいいが、外部からアクセスするにはgetterメソッドが必要
  • イニシャライザー(コンストラクター)はinit、クラス内のメソッドでインスタンス自身を参照するにはself、デイニシャライザーはdeinit
  • 継承はclass SubClass: SuperClass { ... }
  • setter定義時のnewValueパラメーターは予約語
  • method?.hogemethodの戻り値があればhogeを呼び出すと言うことができる

Enumerations and Structures

  • enumはcaseで値を振っていく。ラベルから数値を取り出すのはrawValue、数値からラベルを作成するにはイニシャライザを使う(この時の値はOptional)。
  • structで構造体を定義。だいたいの機能はクラスと同じだが、構造体は常に値渡しされる。
  • class, struct, enumは似ている

Protocols and Extensions

  • protocolでインタフェースのようなものが定義できる
  • メソッドにmutating宣言することで、インスタンスプロパティを変更するメソッドを定義できる(クラスの時は不要、struct,enumの時だけ)
  • extensionで既存の型に機能拡張を行える、Protocolの機能を追加するのにも使える

Error Handling

  • do...catch構文でかく、怪しいところにtryをかく
  • try?でOptional値を取り出す

Generics

  • ジェネリクス<Item>で、Itemを変数のようにしようできる(数学でいう変数的な、x的な): var hoge = [Item]()Item型の配列を宣言とか。
  • where句もジェネリクス関連、親、子などの型の検証を記述できる

感想

 以上、自分がSwiftを読む際に詰まりそうなところをまとめ終えました。逆に言えば詰まらなそうなところは、私の主観の範囲で無視しています。

 Optional型の存在がちょっと気になりました。だいぶ面白そうです。またクラス、構造体、列挙型に関する扱いも違った見方を得られて興味深いです。自分としては列挙型はそこまで重要視していなかったのですが、Swiftをかくことでもっと本質をつかむことができるかもと、少し前のめりになりました。

 iOS`界隈の盛り上がりに少しでもついていきたいと思った次第です。

 そう言えばSwiftってコンパイルしたら

文法の勉強のため簡単なObjective-CのコードをXcodeで実行してみた

 前回、React Nativeのソースコードを読もうとして挫折したので、基礎文法を勉強するためにObjective-Cで何か書いて見ます。

 その前にObjective-Cwikiを少し読んで感じをつかみます。とりあえず読むために必要そうなこと3つです。

  1. C言語としてもいける、コンパイラディレクティブを駆使する
  2. メッセージ式 [Object method:arg1:arg2]でメソッド呼び出し
  3. クラス定義は定義部(.h)と実装部(.m)に分かれている

書いて見る

環境: Xcode: Version 8.3.3 (8E3004b)

 ではとりあえずhello worldします。別にアプリケーションが書きたいわけではないので、コマンドラインツールプロジェクトとして書きます(もっと言えばコマンドラインツールが書きたいわけではないですが、実行の構成方法が不明だったため一旦これでいかせていただきます)

 まずXcodeを起動してFile > New > Projectを選択します。モーダルが表示されるので、macOSタブのCommand Line Toolを選択しNextを押します。名前などは自由に設定します、ただし使用言語はObjective-Cにして、初期設定を終えます。

f:id:ushumpei:20170919225414p:plain

 次にコードを書いていきます。すでにmain.m(エントリーポイントとなるファイル)が生成済みだったので、そこに処理を記述していきます。クラスの定義の練習をするためにHelloクラスを作成しましたのでそれを呼び出します。(@コンパイラディレクティブの他にもリテラルを使用するときの接頭辞として使う、いやおそらくコンパイラディレクティブでリテラルを変換している?)

  • main.m
#import <Foundation/Foundation.h>
#import "Hello.h"

int main(int argc, const char* argv[]) {
    @autoreleasepool {
        Hello* object = [[Hello alloc] init];
        NSString* message = @"Hello world!";
        [object setMessage:message];

        [object say];
        NSLog(@"[object message]: %@", [object message]);
    }
    return 0;
}

 次にHelloクラスをNew > FileからmacOSタブのCocoa Classを選択します。こうするとHello.hHello.mファイルが生成されます。内容を記述していきます。以下を定義しています、

  • 挨拶文を保持するmessage変数
  • 挨拶文を取得するmessage関数
  • 挨拶文を格納するsetMessage関数
  • 挨拶文をコンソールに出力するsay関数

です。

  • Hello.h
#import <Foundation/Foundation.h>

@interface Hello : NSObject {
    NSString* message;
}

-(NSString*) message;
-(void) setMessage: (NSString*) s;
-(void) say;

@end
  • Hello.m
#import "Hello.h"

@implementation Hello

-(NSString*) message {
    return message;
}

-(void) setMessage: (NSString*) s {
    message = s;
}

-(void) say {
    NSLog(@"say: %@", message);
}

@end

動かして見る

 Xcodeのウィンドウ上部メニュー左辺りにある▶︎(Runアイコン)を押してコードを実行します。

f:id:ushumpei:20170919230326p:plain

感想

 コンパイラディレクティブをちゃんと覚えていけばある程度読めるようになると思いました。@autoreleasepoolGCということでいいのかな?いやちゃんと覚えないといけないですね。とりあえず公式ドキュメントをこの辺から探して見ます。

 書けるようになる必要があるか?という問いに関しては一瞬、「まあでもSwiftあるし、、、」とか思いましたが、まだまだ使われているため、やっておいて損はなさそうな気がします。

React Nativeの画像遅延読み込み(ライブラリのソースを読んで見る)

 この記事を要約すると、「画像遅延読み込みの方法が知りたくて、ライブラリのソースコードを読んで、Objective-Cのコードにたどり着いて、次に進めなくなってしまい一旦諦めたけれど、これを糧にもっと勉強しようという気になった」という自己満話です。

概要

 少し前までWebサービスのユーザーのインターネット回線速度をそこまで強く意識したことがありませんでした。

 もちろんパフォーマンス計測はしていましたが、サーバー側の処理を改善することで対処していて、あくまで一般的なユーザーは回線がある程度の速度であることを仮定していましたし、回線が弱すぎるのはユーザー側の問題としている部分がありました。

 この回線の強弱に関する考え方が私が感じた、モバイルアプリとWebの大きな違いでした。

 モバイルでは回線が弱くなることが容易に起こりうるし、そのせいでアプリが操作不能になってしまうことは、ユーザーにとってストレスだと思います(操作不能にする方がいいケースもあると思います)。いや、といよりモバイルから閲覧するWebサービスとアプリとの違いでいうと、アプリだとオフライン状態でも使えるように作れる部分があるので、極力そうしていった方が親切だし、ユーザーも安心だよね、という話です。

 多分モバイルアプリ開発者の方々からすると当然すぎることだと思うのですが、私がこのことに気がつくためには、いつまでたっても画像が読み込まれないまま動かない、という経験が必要でした。(頭が悪いです)

読んでみる

 そんなこともあり遅延読み込みのライブライreact-native-image-progressとかに触れたのですが、そもそもどうやって遅延読み込みを実現しているか、ソースを読んでみようというのが今回の内容です。

 とりあえず一番はじめのリリース0.1.0を読む;

  • 基本的にはreact-nativeImageコンポーネント
  • Imageの読み込み開始、進捗、終了イベントハンドラにコールバックを登録している
  • Imageのprogressイベントについて苦労したんだろうなと感じられる
  • 遅延読み込み方法はImageのコードを読まなければわからない

 ということなのでreact-nativeImageコンポーネントのソースを読む;

  • RCTImageViewを読むべきとわかる

 ここからObjective-Cです、RCTImageView.mを読む;

  • RCTDirectEventBlockで詰まる…

すみません、詰まりました。

感想

 知らないことがたくさん見つかりましたし、いかに色々なことを知らないままで使っていたかわかりました。予想として遅延読み込みに関してはjavascriptfetchメソッドとかで実装されてて、簡単に読めないかな、とか思って軽く記事を書き始めたのですが、普通にネイティブでした。

 結局わからずじまいになってしまい、かなりダメダメなので、しばらくいろんなソースを読んでみることにすると思います。Objective-Cの基本的な構文も抑えて今回の詰まったところを解消したいです。あとReact Nativeの仕組みもちゃんと知りたくなりました。

 余談ですがFacebookのライセンスの話、どう捉えるか考えなければ。。。

ハノイの塔

なんだか久しぶりにjavascriptハノイの塔を解いて見ました。以下の関数は、number枚のハノイの塔をtime回操作した時の状態を計算するものです。特に目新しいものではないと思います。

const hanoiSnapshot = (number, time) => {
  // 円盤の移動が完了した以降の操作はエラーを表示(良いやり方かどうかは悩む)
  if (time > Math.pow(2, number) - 1) throw new Error(`${Math.pow(2, number) - 1}回目の操作時点ですでに塔は完成しています`);

  // 三本柱の配列データを定義
  hanoi = [[], [], []];

  // 1~number番目の円盤それぞれの場所を計算して柱に格納して行く
  for (let i = 1; i <= number; i++) {

    // 移動する方向
    const direction = Math.pow(-1, number + i + 1);

    // 移動した回数
    const moveCount = Math.floor((Math.pow(2, i - 1) + time) / Math.pow(2, i));

    // 1番目の柱を位置0とした時の円盤の絶対位置
    const absolutePosition = moveCount % 3;

    // 方向を加味して場所を0~2に正規化して決定
    const position = (direction * absolutePosition < 0) ? (3 + direction * absolutePosition) % 3 : absolutePosition;

    // 柱に円盤を追加する
    hanoi[position].unshift(i);
  }

  return hanoi;
}

感想

イメージとしては円盤は方向と速度を持っていて、3つの柱を移動しつつ、くるくる回って行る感じです。数学で三乗根の乗算を考えるときに書くような図をイメージするとわかりやすい気がします。