1年ふりかえり

気づけば、Toyama.rbをはじめてまる1年経ちました。

あっという間でしたが、思えばこの1年ほどで色々と経験し、得るものも多かったです。

全然ブログ書いてなかったのもあるので、 このあたりで一度振り返ってみます。


プログラミングキャンプ参加

mugi1.hateblo.jp

自分の中ではすべてがここから始まってます。

PlayFrameworkがきっかけで触り始めたRubyRailsでしたが、 独学に限界を感じて勢いだけで突っ込んだ人生初の勉強会でした。

結果としては

  • もっと早く勉強会とか参加すればよかった
  • みなさんいい人だった
  • 世界は広い

といった感じ。

そして、富山にもコミュニティないのかな〜・・と思った結果

Toyama.rb開催

富山にはRubyのコミュニティはなかった。

上記の体験をブログに書いたところ、西脇.rb 伊藤さんの紹介で地元富山のエンジニアの方がブログにコメントしてくれたことがきっかけで、Toyama.rbを作っちゃった。

勢いで作った感じはありましたが、ちゃんと人数が集まって安心。

倉貫さんと語らう会

社内の先輩が以前から知り合いだったこともあり、新しい書籍が出版されるタイミングで、ビアバッシュ形式の語らう会を開催。

Toyama.rbで一番人数が集まった会でした。ゲスト効果すごい。 内容的にも得るものが本当に多かった。

自分自身を見つめ直す機会にもなりました。倉貫さんホントにすごかったです。

数学パズルを解こう会

www.shoeisha.co.jp

変わったことがやりたいな〜、と思い、みんなで同じテーマでコードを書いてみよう!という会を思いつきで企画してやってみたところ、結構盛り上がりました。

同じテーマだとコードをみたときにイメージしやすく、ちゃんと勉強になってる感があったのも良かったです。

フルリモートもくもく会

実験的にフルリモートで開催してみました。

・・・が、正直これには課題も多かったかな〜と反省しています。

  • 常に通信するので個人のマシンスペックによっては重い
  • 終始無言だと一人とさして変わらない
  • 普段リモートワークの人からすると、直接会うイベントだからこそ価値がある

なにごともチャレンジですよ!と付き合ってくれたコミュニティの皆様には感謝です。

東京・富山会場での開催

開催のうち半数ほどは永和システムマネジメントさんを東京会場として、2拠点開催することができました。

これは完全に @kunitoo さんのご協力あってのことだと思います。 本当にありがとうございます。


個人的にもくもく会でやったこと

  • RSpecを書いてみる
  • React.jsのサーバサイドレンダリングを試す
  • ターミナル環境を整える(zsh/peco/ghq/enhancdなど)
  • Gemのソースを読む(Faker)
  • ゼロからアプリを作ってどこまでいけるかやってみる
  • DeviseでOmniauth
  • Unicorn/Puma にデプロイしてみる

良かった点

  • Toyama.rbを毎月継続開催できた
  • もくもく会だけでもいいかな?と思っていたが、特殊企画もできた
  • 私しか居ない、という会は無かった
  • 参加者の方と仲良くなれた(と私は思っている)

改善すべき点

  • もくもくしすぎ感があったかも。参加者同士の交流が飲み会頼みだった。
  • 開催することに意識を持ってかれていた。
  • 自分のRubyスキルって上がったのか?
    (まあでもそれなりに色々やったような気もする)

まとめるとこんな感じかと思います。

来年以降の開催としては、もう少し参加者同士で関われるような内容になるよう、中身を工夫していければな〜と思っています。

個人的なところでいえば、なんだかんだいって書いたコード量が少なかったのが最大の反省点です。

原因としては、断片的に学ぼうととしていたことが良く無かったのではないかと。 少し書いて満足してしまって、トータルで見たときに、学んだこと同士があまり繋がらないのですよね。

何か1つWEBサービスなり何なりを決めて、それを軸にコードを書くようにしたほうが長期的に続けることもでき、実際に役に立つスキルを得ることもできそうです。

まずは案を考えるところからですが、来年はそんな方向でやってみようかと。


Toyama.rbに関しては参加していただいた皆様のおかげで続けることが出来ました。ありがとうございました。

これで終わりみたいな雰囲気ですが、今後ももちろん続けていくので、これからもよろしくお願いします!

「プログラマ脳を鍛える数学パズルを解こう会」を開催しました

(盛り上がってほとんど写真撮るの忘れてました)

Toyama.rb #05イベントとして、「プログラマ脳を鍛える数学パズルを解こう会」を開催しました。

プログラマ脳を鍛える数学パズル ?

↓こちらの書籍です

www.shoeisha.co.jp

翔泳社主催のITエンジニア本大賞 2016技術書部門大賞にも選ばれました。 プログラミングのスキル評価サイト CodeIQに掲載された問題から 良問とされる問題が抜粋されており、解き方のサンプルなども掲載されています。

私個人としては、Amazon翔泳社の技術書籍が半額セールだった時にkindle版を購入しました。

勉強会のテーマに

基本的にToyama.rbは毎回もくもく会を主体に開催していたので、各自が好きなテーマでもくもくとコードを書いていましたが、 今回は主催者(というか私)の都合で開催週がズレてしまい、「参加者が少ないかもな〜」→「じゃあ実験的にいつもと違うことやってみよう!」という発想で、この本をテーマに開催することにしました。

チョイスした問題

問題自体は私の独断と偏見で良さそうなもの(できれば現実世界の具体的なモノをイメージしやすそうなもの)をチョイス。比較的本の中でも前半〜中盤に掲載されている易しめの問題にしましたが、実際やってみたら全然易しくなかったという現実。

というより、解こうと思えば解けるけど、パフォーマンスや可読性などを考えると良い感じのコードにならなくて悩むという。易しめのにしたのは正解だったかも。

実際の問題は↓です


Q1. バスの両替機

前提条件
  • 両替で出てくるのは 500/100/50/10円の硬貨のみ
  • 両替で払い出せるのは最大で15枚まで
問題
  • 1000円投入した場合の両替パターンは全部でいくつあるか?

実際解こうと思うと、意外と手が止まっちゃいました。

悩んだ挙句私が叩き出したコード

module Q1
  def self.count
    # プライドを捨ててすべての組み合わせで1000円になるやつを探す
    count = 0
    (0..15).to_a.each { |a|
      (0..15).to_a.each { |b|
        (0..15).to_a.each { |c|
          (0..15).to_a.each { |d|
            if ((a + b + c + d) <= 15 && 500 * a + 100 * b + 50 * c + 10 * d) == 1000
              count += 1
            end
          }
        }
      }
    }
    count
  end
end

puts "answer : #{Q1.count}"

コメントがすべてを物語る。

後輩が書いてきたら「お前本当にこれで良いと思ったのか」って言われるレベル。

(0..15).to_a.each { |a| }の部分をコピペしている時に「絶対これ違うわ!!」と頭をよぎってました。

イメージ的には再帰を使ってスマートに解きたかったんですけど、時間制限を設けたのもあって間に合わず、途中で思考放棄してこんなコードに。

そして後で書籍を見ると、解答サンプルにこれを同じコードが乗っていて

「単純に解くならこんなコードで大丈夫だよ!」
「わぁ、これなら僕でも理解できるや!!」

という扱いを受けていました。屈辱である

他の参加者のコード

他の参加者の方のコードの中で、個人的に「お〜」と思ったのがコチラ

module Q1
  def self.count
    coins = [10, 50, 100, 500]

    result = []
    (2..15).each do |n|
      coins.repeated_combination(n).each do |cs|
        result << cs if cs.inject(:+) == 1000
      end
    end
    result.count
  end
end

puts "answer : #{Q1.count}" #=> answer : 20

私のコードのように無駄な重複がありません。
そして、repeated_combination がポイントですね。

リファレンス

呼び出すだけで、重複を許可したすべての組み合わせを列挙してくれます。
こういった機能の充実具合がさすがRubyだな〜といった感じです。

普通に知らなかった・・
(でもこういうとき以外で使うタイミングあるのかな?)

解き方のアプローチの違い

おもしろいな〜と思ったのが、もちろん最終的なコードは違いますが、解くまでのそもそものアプローチが人によって違っていたことでした。

上記の例の場合、根本的な考え方は

  • 使える硬貨を組み合わせて1000円になる組み合わせを探す

となりますが、人によっては

  • 1000円から使える硬貨を引いていき、0になるものを見つけていく

という攻め方をしていました。イメージ的には実際の両替に近いですね。


そして第2問目↓


Q2. ストラックアウト

前提条件
  • ストラックアウトをイメージ
| 1 | 2 | 3 |  
| 4 | 5 | 6 |
| 7 | 8 | 9 |
  • ボールを投げると的が抜ける
  • ボールは必ずいずれかの的にヒットする
  • 5以外の的は2枚抜きができる (1&2, 4&7 などはok / 5&6, 2&5などは不可)
問題
  • 的がすべて抜ける投球パターンはいくつ存在するか?

ポイントは2枚抜き。
というか2枚抜きがなければ階乗を出すだけで一瞬で終わりますね。

1問目以上に(私含め)苦戦していたようです。

  • なんか明らかに少ない数字になるぞ・・
  • 処理が返ってこないぞ・・

といった声が多数。大変楽しんでいただけたようです。

私がひねり出したコード

module Q2
  PATTERN = [
    [1], [2], [3], [4], [5], [6], [7], [8], [9],
    [1, 2],
    [2, 3],
    [3, 6],
    [6, 9],
    [9, 8],
    [8, 7],
    [7, 4],
    [4, 1]
  ]

  def self.hit(board, target)
    # いずれかが存在しなければ不正な投球
    target.each { |n| return 0 unless board.include?(n) }

    hit_board = board - target

    # 空になったら終わり
    return 1 if hit_board.empty?

    # 残りのパターンを網羅
    return PATTERN.map { |target| self.hit(hit_board, target) }.inject(:+)
  end

  def self.strike
    PATTERN.map { |target| self.hit((1..9).to_a, target) }.inject(:+)
  end
end

puts "answer : #{Q2.strike}"

今回は何を思ったか「今回は再帰で解きます!」と宣言してスタートしたので、明らかに自分の首を締めてしまったのですが、なんとか宣言通りのコードになりました。

「投げられるパターンが決まってるなら、全部投げていけばいいじゃない!」というスタンス。

コードの綺麗さというか、すっきりしてる感じでは悪くないのでは?と思います。

が・・・今回の問題では、答えを出す以外にも、さらに隠れ課題が。

処理速度

上記のコードでも答えは出るのですが、実行すると私のマシンでは約20秒程度かかります。

別に1回限りだしいいじゃん、という考えもありだとは思います。

でもほら、なんというか、速くできるなら速くしたいじゃないですか!!そこに深い意味はないんですよ!

他の参加者のコード

まずは私と同じく再帰を使っていた方の解答です

module Q2
  NUMS = (1..9).to_a
  PAIRS = [[1, 2], [1, 4], [2, 3], [3, 6], [4, 7], [6, 9], [7, 8], [8, 9]]

  module_function

  def hit seq, left = NUMS.dup
    if left.empty?
      [seq]
    else
      [
        *left.map do |i|
          hit [*seq, i], (a = left.dup; a.delete(i); a)
        end.inject(:+),
        *PAIRS.select { |pair| pair.all? { |i| left.include? i } }.map do |pair|
          hit [*seq, pair], left - pair
        end.inject(:+)
      ]
    end
  end

  def strike
    (@sequences = hit([])).count
  end

  def sequences
    @sequences
  end
end

以下がポイントなのかな〜と思いました。

  • 実際の投球パターンを網羅したリストが作成される
  • 不必要な投球を削ることで処理速度が向上されている

無駄が省かれているため、私のコードより2倍ほど高速に。

同じ再帰なのにこうも違うコードになるのか・・と感心してしまいました。

最速だったコード

そして全員のコードで最速だったコードが以下でした。

module Q2
  def self.strike
    board = *(1..9)
    count = factorial(board.count)

    two_numbers = (board.zip(board.rotate) + board.zip(board.rotate(3))). #=> [[1, 2], [2, 3], [3, 4], [4, 5], [5, 6], [6, 7], [7, 8], [8, 9], [9, 1], [1, 4], [2, 5], [3, 6], [4, 7], [5, 8], [6, 9], [7, 1], [8, 2], [9, 3]]
                   select {|ns| ns[0] < ns[1] }.
                   reject {|ns| ns.include?(5) }.
                   reject {|n| [[3, 4], [6, 7]].include?(n) }

    (1..4).each do |n|
      two_numbers.combination(n).each do |nums|
        next if nums.flatten.size != nums.flatten.uniq.size

        numbers = nums + board.select {|b| !nums.flatten.include?(b) }
        count += factorial(numbers.count)
      end
    end

    count
  end

  def self.factorial(number)
    (1..number).inject(1,:*)
  end
end

おそらくこのコード、書籍に載っていたサンプルより速いのではないでしょうか。
マシンスペックにもよりますが、おおよそ1ms〜2msで終了するようです。(爆速)

ポイントは、「そもそも網羅的に捜査はしていない」ということかもしれません。

処理的には

  1. まず、投球のユニークな組み合わせを列挙する
  2. 組み合わせごとに階乗値 = 投球パターンを算出する
  3. 2の合計を算出する

という流れのようで、結果的に処理の大半が単純な数値の演算となるため、非常に高速に動作するようです。

実際に自分でコードを書いたときには、「いかに網羅して調べるか」ということばかり考えていたため、 そもそも階乗すればいいじゃない、という発想がありませんでした。

根本の部分で自分の発想を疑ってみるのも大事ですね〜・・

ちなみに

今回は「よくやったで賞」という小学校のお楽しみ会でありそうな賞を用意しました。

具体的に何をしたか、というより

  • この人今日よくやったな

という人を投票で決めよう!というもの。

副賞として1,500円分のAmazonギフトカードを贈呈。(もちろん私の自腹で!)

結果的には上記の最速コードの作者に贈呈されました。おめでとうございます!

終わってみて

思いつきで開催した企画だったのですが、個人的にはかなり面白い内容だったと思います。 同じテーマでコードを書いたこともあり、会話も活発でした。

そして、人のコードを見るのは本当に参考になりますね〜

そもそも自分じゃ思いつかない発想に触れられるのはそれだけで貴重。

普段の業務で求められるコードなど、バックグラウンドとなる部分が人によって異なるからこういう結果になるのでしょうね。こういうのはコミュニティならではかもしれません。

また機会があれば全員で同じテーマでコードを書くイベントをやってみたいな〜

React/Redux 使ってみての勘所

前回のエントリでは、React/Redux/ES6のざっくりとした感想をまとめました。

mugi1.hateblo.jp

今回はその続きということで、React/Redux利用時において、

  • こうすればよかった!!
  • こうすべきじゃなかった・・

といったところをまとめてみたいと思います。

Immutable.js は使ったほうが幸せになれた

https://facebook.github.io/immutable-js/

javascriptで不変データ構造を提供してくれるライブラリ。(by facebook) これによって解消される問題が多数。

構造がネストした場合の更新が簡単に

「そもそもネストしないような構造にしろよ」という話なのですが、 大人の事情でネストせざるを得ないときもあります。

ネストしたstoreの場合、action経由で深い階層の値を更新したい場合に結構な手間になります。

たとえば user[0].products[2].item.name みたいになってしまったケース。

Object.assignやlodash#mergeなどを利用するのも手だと思いますが、 動作をきちんと理解せずに利用すると、

  • 同オブジェクト内の存在しないキーが落ちる
  • undefinedの値が落ちる(落ちない)

といった状態になり、ハマってしまうことがありました。 気をつければいいのですが、「気をつけているコード」で溢れかえるとかえって読みにくくなったり。

これがImmutable.jsを利用していると

state.setIn(["user", 0, "products", 2, "item", "name"], "yeah");

でstate自体に影響を与えることなく、新しいstateを得ることができます。

記述が統一できる

reducerで新しいstateを生成する際には、引数として受け取ったstateを書き換えず、新しいstateを生成する必要があります。

そのため、state生成時には操作時に注意することが出てきます。

  • 配列の要素を変更する場合
    • Array#concat などで新しい配列を作って差し替える
  • オブジェクトの生成方法が1つではない
    • Object#assign
    • lodashのメソッド(assign/merge/extend/default...)
    • 普通に自力で作成

これらで対応することそのものが問題ではありませんが、「ネストした場合の更新」の欄でも触れた通り、方法によってundefined状態のフィールドの取り扱いが違ったりするため、複数人での開発時には記法を統一するほうがベターだと思います。

「reducerでのstate操作はImmutable.jsで」としておけばそれだけである程度は操作が統一できるため、心理的負担も少し下がります。

比較が簡単に

Reactでコードを書いていくと、どこかでパフォーマンスチューニングのために、shouldComponentUpdate によるレンダリング抑制を書く機会が登場します。

このとき、とりあえず this.propsnextProps を比較して差異がなければレンダリングしない(return false)とするケースが多いのですが、Immutable.jsを利用していれば、=== を利用して容易に比較することが可能となります。

利用しない場合には自力で比較するか、lodash#isEqualなどを利用することになりますが、細かいところでカスタマイズが必要になるケースが多いです。

Reactの公式docにもImmutable.jsに関する記載はありますね。

facebook.github.io

構造をコード上に定義しておける

redux(flux)を利用した場合、アプリケーションの状態を表すstoreは一箇所で管理されますが、初期状態とすべきstore状態をどこに定義するか?という問題が発生します。

reducerファイル内に直接定義してしまっても大丈夫ですが、規模が大きくなってくるとカオスになりがちです。というかカオスになりました。

そこで、Immutable.jsを利用してデフォルトのstore定義のみを定義しておくことで、store全体がどのような構造かすぐ解るようになり、見通しが良くなりました。

また、reducerを分割管理している場合などは、ベースとなるstoreを定義しておき、そこからImmutable.jsのmergeを利用して拡張することで、継承っぽくstore定義していくこともできます。(お作法的にどうなのかは謎)

export const User = Immutable.fromJS({
  id: null,
  name: "",
  email: ""
});

export const AdminUser = User.merge({
  tel: "",
  address: "",
  permission: false
});
function user(state = User, action) {
  switch (action.type) {
    case 'USER_UPDATE':
      return /* update */;
  }
  return state;
}

function admin(state = Admin, action) {
  switch (action.type) {
    case 'ADMIN_UPDATE':
      return /* update */;
  }
  return state;
}

ただ、Immutable.jsはファイルサイズが大きいのがネックとなるケースもあるようです。

ご利用は計画的に。

connectはひかえめに

connect記述により、任意のstoreをsubscribeすることができます。

これを利用すると、Reactで陥りがちなpropsのバケツリレーをぶった切ることが可能となります。

・・が、実際にはあまりこれはオススメできません。 最初はガンガンconnectを利用してコーディングしてしまっていたのですが、後になって色々と問題が表面化してきました。

再利用しにくくなる

connectしてstoreをsubscribeするということは、そのstoreに依存していると言っても間違いではないと思います。 一概に全てというわけではありませんが、大半のケースでは、connectを利用したcontainerは1つの用途に限定されてしまい、「あー、connectsしてるから使えないじゃーん!」というケースが発生して悲しい思いをしました。

パフォーマンスに影響が出てくる

通常のReactコンポーネントであれば、親要素で shouldComponentUpdate によるレンダリング抑制を行った場合、子の要素も自動的にレンダリングが抑制されます。

とても素直な考えだと思いますが、ここで子がconnectしてしまっていると、親からのprops伝搬とは別に、storeの変更時にもレンダリングが発生することになります。

つまり、子自身の中で shouldComponentUpdate による抑制を行う必要が発生します。別にそれでもいいじゃん、という発想もありますが、数が増えてくると shouldComponentUpdate そのものが大量になってしまったり、パフォーマンス低下時に原因を追求するのが難しくなっていきます。

「親で shouldComponentUpdate ちゃんと動いてんのになんでこんなに描画重くなるんだ・・・」というときにこれが原因でした。

というわけで

などなどの理由から、基本的には、connectするのは最上位階層のみとし、子以下には素直にpropsでバケツリレーとするほうが、最終的には可読性・保守性ともに望ましい形のコードになりました。 SPAの場合は、ルーティング単位でrecducer分割してconnectするとちょうど良い感じですが、そのあたりは作成するアプリケーションに応じて差異があるかと思います。

いずれにしても、乱用しないほうが望ましいかも。

Storeはできるだけフラットな構造に

Immutable.jsの欄で「ネスト時の更新が簡単に!」とか書いてますが、そもそもの話としてはStoreはできるだけネストさせないほうが望ましいです。

理由は

  • ネストしていると、undefined/null を意識する手間が増える
  • そもそも更新がめんどうになる
  • PureRenderMixinが使えるようになる

などです。

normalizeするのも1つの方法ですね。

github.com



思い返すと他にもたくさんポイントとなる箇所はありましたが、また同構成を利用する機会があれば、とりあえずは上記は最初から抑えた状態で着手したいな〜という感じです。

ただ、やはりもう少し軽いもの(実装量的に)があれば嬉しいな〜

めまぐるしく変化し続けている世界ですし、2016年にもまた何か大きい変化があったりするのかな。

React/Redux/ES6をしばらく使ってみての所感

ここ数ヶ月、お仕事で以下構成での開発をしています

  • React
  • Redux
  • ES6

徐々に解ってきたと思う(たぶん)ので、感覚がホットなうちに備忘も兼ねて整理。

※個人的な感想も含みます。

良かったところ

React : コンポーネント再利用時の安心感

いままで → なんか心配

従来は、フロントエンドはjQueryをメインに開発をしていました。

jQueryプラグインするなど、後々再利用可能な形で部品化することは従来も行っていましたが、いざ使う時に「これ本当に大丈夫か?」という気持ちになることも多々。

  • 他のプラグインとの相性は?
  • 名前空間の汚染がないか?
  • 依存するHTML上のid/class/attributeで悪影響がないか?

ルールを徹底したり、ドキュメントとして注意点をちゃんと残しておいたりすればある程度は回避できますが、最後は「ある程度覚悟して信頼する」という工程を通っていたと思います。

React : あんしん

Reactでお約束に則ってコンポーネントを作成していくと、propsベースとなり内部には状態保持せず、かつコンポーネント外のDOMには影響を与えない作りとなります。

直接DOM操作もやろうと思えばできるため、100%安心!というわけではありませんが、ポイントなのは「基本的に作ってれば大丈夫」というところだと思っています。

  1. 気をつけていれば安全なコンポーネントにできる
  2. 特殊なコードを書いたときだけ安全ではないコンポーネントになる

では大きな差があると思っていて、後者のほうが圧倒的に信頼できます。

React : パフォーマンスの改善がしやすい

無心でひたすらコードを書いていくと、徐々にパフォーマンスの劣化が気になってきます。 その時に、パフォーマンス改善のためのツールが用意されているのは大きかったです。

今のところほとんどのケースにおいては

  1. Perfomance Toolsボトルネックになってるコンポーネントを探す
  2. shouldComponentUpdateでがんばる

でだいたい問題とならないレベルまで改善が可能でした。 パフォーマンス劣化時に、問題となる範囲が想定しやすいのも良いですね。

jQueryをdisっているわけではありませんが、 効率の悪いセレクタを探したりDOMの操作回数をできるだけ減らす努力をしたりして地道に頑張っていたのはなんだったのかと。

(とはいえ、対応できないレベルのパフォーマンス問題にぶつかったら考えは変わるかもしれません・・

ES6 : たくさんの幸せ

ES6が便利すぎて半端じゃないです。ES6なしではjs書けない体になりました。

アロー関数
  • コールバック系が書きやすいし読みやすい
  • self = this がいらない幸せ
spread operator
  • argumentsって書く頻度が激減
スコープまわりのあれこれ
  • ブロックスコープとか
  • const/let とか
  • 即時関数もあまり使わなくなった気がする

これだけじゃないですが、本当に痒いところに手が届くようになった感じ。もう戻れない。

つらかったところ

記述が超増える!!

React/Reduxともにですが、どうしてもコード量が大幅に増えます。

Reactの場合、Reduxのところでも少し触れましたが、propsが怒涛のリレーになることが多いです。 階層が深くなればなるほど propsが増えていき、コードの記述量が増えて行くのはなかなか大変。

Reduxについては、ビジネスロジックとデータ(store)の管理を綺麗に分離することができますが、確実に大幅にコードが増えます。

レイヤーが増えるから仕方ないとは思うのですが、簡単な画面の作成時でも

  • view
  • container
  • component
  • action
  • reducer

などと、多岐に渡る修正が必要となり、新規ファイル作成量も多いです。 「1つボタンを増やして、押したらAPIを読んで結果を別のとこにレンダリング」というだけでも、結構なコードを書く必要があります。

おまじない的にコードを書かないといけない感じもあり、java/strutsを使ってweb開発していたころを思い出しました。

役割を分離できることで粒度の細かいテストを書けるなど、 恩恵が大きいのも理解はできるのですが、恩恵以上にすごい勢いでコードが増えていくな〜と。

実際には作業スケジュールも加味しないといけないので、 全コードに対してテストを書いている余裕がないのが現実だったりもします。 その時に、コードが多ければ多いほどネガティブな影響を受けやすいのではないかと。

とはいえ、Fluxのデータフローを1方向にするという思想自体はとても良いものだなと思います。 コードが増えるは増えるのですが、実際に読む際には流れを追いやすい。

このあたりは実装側の問題もあるかもしれませんが、 同じような問題に悩んでいる人は多いのかな〜・・?

ES6 : 使う準備が大変

ES6が、というわけではありませんが、ビルド環境の整理が大変です。 このあたりは私の先輩がゴリゴリに組み込んでいましたが、それでも大変そうでした。

あとは使っているとあれもこれも入れたくなってくるので、 どんどんカオスになっていくpackages.json

ある程度自重するのも大事なのかもしれません。


まだまだ解ったような解っていないような感じですが、トータルでまとめると

  • React : 良い
  • Redux : つらい
  • ES6 : 良い

といった感じです。

React/Reduxについては、ベストプラクティスと言うのはおこがましいですが、 円滑に開発を進めるための勘所みたいなところも多々あると思います。

そのあたりについてはまた別の記事でまとめてみます。

Toyama.rb #03 「倉貫義人さんと語らう会」を開催しました!

f:id:mugi1:20160206131126j:plain

2/5(土)に、Toyama.rb #03 かつスペシャル企画として、「倉貫義人さんと語らう会」を開催しました!

toyamarb.doorkeeper.jp

語らう会?

今回お招きしたゲストは、株式会社ソニックガーデンの代表取締役 倉貫義人さんです。 「納品のない受託開発」という新しいビジネスモデルや、リモートワークを積極的に実施されるなど、様々な新しい取り組みを行っている方です。

私個人としては、以前から書籍を購入して拝読していたのもあり、お名前は知っていたのですが、「あの有名な凄い人」のような、雲の向こうの人だと思っていました。

身近なつながり

きっかけとなったのは、Toyama.rbにも参加してくれている私の会社の先輩が、倉貫さんと知り合いだったことです。その先輩からの紹介で、今回のイベントに繋がりました。いずれにしても、Toyama.rbをやっていなければ実現しなかったと思うので、思い切って始めて良かったです。

内容

どんな内容にしたらいいか?と相談・検討していた結果、「ビアバッシュにしたらいいんじゃない?」という話に。

いいですね、ビアバッシュ!やりましょう!ビアバッシュってなんですか!!?


(...googleで検索 )


どうやら普通のセミナーとは違い、お酒や軽食を片手にわいわいとゆるい感じで歓談するイベントのことを指すようです。たのしそう!ということでビアバッシュに決定。

メインテーマは、今回倉貫さんが2冊目の書籍「リモートチームでうまくいく」を出版されたこともあり、リモートワーク・リモートチームを軸に進めることとなりました。

準備

こちらのブログを鬼のように参考にさせていただきました。 本当にありがとうございます。

d.hatena.ne.jp

イベント当日

イベント当日は以下のようなタイムスケジュールでした

  • 1時間ほど : 倉貫さんによるセッション
  • 15分ほど : 準備
  • 2時間ほど : ビアバッシュ

初めて参加してくれた方も多く、普段のもくもく会の倍ほどの人数が集まりました。 (Ruby!というテーマではないので、あまりToyama.rbの名前を出さなかったのもあるのかもしれません)

f:id:mugi1:20160206140412j:plain

最初の1時間は倉貫さんのセッションです。

富山県という地域の特性か、SIerのエンジニアの方が多い印象で、リモートワークという刺激的なテーマに対して、かなりのめりこんで聞いていた方が多かったように思います。

私自身は内心、「ちゃんとビアバッシュのピザ届くのか・・!?」とドキドキしていたのは秘密。


(ちゃんととどいた)

f:id:mugi1:20160206150103j:plain


ピザが届いたタイミングでビアバッシュ開始!
ピザーラのピザはとてもおいしかった。)

f:id:mugi1:20160206151530j:plainf:id:mugi1:20160206151524j:plain


倉貫さんのお話しされる内容は、いい意味で心に「グサリ」と来ることも多かったです。参加される方も色々思うところがあるのか、時折全員が空を見つめてしんみりしているのが印象的でした。笑

でも、そうやって改めて考える、というのも貴重な機会になったのではないかと思います。

リモートワークに限らず様々な質問も飛び交い、気づけばあっという間に時間となりました。


最後は全員で記念撮影をして終了!

f:id:mugi1:20160206174216j:plain


主催としては多々至らぬところもありましたが、無事にイベントを終えることができたと思います。

個人的な感想

個人的に倉貫さんのセッションやビアバッシュでの話で印象に残っているのは、「そもそもなぜ採用するのか?」というところに多くのテーマが集約していくところでした。

たとえば、リモートワークでセキュリティの部分が気になっていましたが、まず、オンプレ環境よりそもそもAWSなどのクラウド環境のほうがむしろ安全なのでは?というのは前から思っていた部分でした。

それでもセキュリティ面を課題とされるのは、個人による情報の不正利用などをリスクとして懸念している部分が少なからずあると思います。

であれば、「なんで信用できない人を採用するの?」ということに。

逆に言えば、チーム内・お客さんも含めて適切な信頼関係を築くことができていれば、柔軟に仕事に対応することができるようになり、コスト面などにおいても恩恵が大きいと。

採用してからのリスク対策などのためにコストをかけるより、最初の採用時点でじっくり労力とコストをかけることで、全体が円滑にまわる仕組みができているのはとても興味深かったです。

どうしてもこの業界にいると「そんなのは理想論だ」という意見も聞きがちですが、実現されているチームが存在している限り、これは理想ではなく真理なのでは、と思いました。

イベントを終えて

なんとも緊張しましたが、とても充実した1日となりました。
参加者の方にも楽しんでもらえた(と私は思っている)ようです。

そして、はるばる富山まで来てくださった倉貫さん、本当にありがとうございました!



次回

次回は平常運転でもくもく会を行います。

興味のある方はどうぞ!(今回も富山&東京の2会場開催です!)

toyamarb.doorkeeper.jp toyamarb.doorkeeper.jp

Toyama.rb #02 もくもく会とリモート

仕事が激務で更新できていませんでしたが、Toyama.rb #02 / #03(ex回) を開催しました!

とても充実した内容となりました!

今回は #02 の主催レポートです。(ex回となった #03 については近日中更新)

Toyama.rb #02 - もくもく会

f:id:mugi1:20160109132608j:plain

第1回と同様、もくもく会を開催しました。

が、1回目と決定的に違う点が1つ。

リモート開催

第1回目の参加者のうち、数名は 「心は富山、体は東京」という方でした。

(東京からわざわざ来ていただいたことに本当に感謝)

参加したいけど、さすがに毎回富山にくるのは難しい。。。ということで、@kunitoo さんにリモート側の主催者を担当していただき、東京側との2拠点同時開催とすることに!

課題

いいですね!やりましょうやりましょう!!!と勢いで言ったものの、課題がもりだくさん。

  • どうやって繋ぐの?
  • 安定した回線確保できるの?
  • 機器類とかはどうするの?

いろいろと相談・検討した結果。。。

解決案

  • 接続
    → appear.in, だめなら GoogleHangout
  • 回線
    → Toyama Free Wi-Fi に託す。だめならLTEテザリング)で頑張る。
  • 機器
    → 私がなんとかして用意

といった具合に。

特に心配だったのが回線。安定とかそういう以前に、そもそもポートとかの関係でまったく繋がんなかったらどうしよう?とも思いましたが、事前にiPhone + LTE + appear.in での接続確認をしたところ、意外と問題なく接続できることが判明。

つまり、私のパケット上限さえ無視すればいける!!

(とはいえ、第1回開催時のもくもく中は意外と静かだったので、開始と終了時だけ繋がれば最悪なんとかなるかな〜という算段でした。)

当日

富山会場6名、東京会場5名(残念ながらおひとりは風邪で欠席)が集まってくれました!

あわせれば11名なので、1回目よりも多い人数に。いやほんと皆様ありがとうございます。

イベント企画

ソニックガーデン伊藤さんのブログでもかなり前にご紹介いただいていますが、今回は東京とのリモート開催に加え、西脇.rb&神戸.rb さんともリモートで接続し、ちょっとしたイベントを盛り込みました。

同じ日に勉強会開催で、かつ同じ日にリモート開催という、なんとも色々と偶然が重なった結果実現に至りましたが、まず発案していただいた伊藤さんに感謝です。

イベント内容

短い時間でパッとできるもの!ということで、会場別対抗 Rubyクイズ大会を開催。

私は事前に問題を知っていたので、背後でニヤニヤしながら見ていました。


総力で挑む富山会場の図 f:id:mugi1:20160109145855j:plain

クイズ自体も盛り上がりましたが、何よりも、普段Rubyにはそこまで関心の無い参加者の方(※)からも「Rubyにちょっと興味が出た」と言ってもらえたことが嬉しかったです。

※Toyama.rbでは、Rubyがベースだけど何やっても別にいいよ!というスタンスでございます。

最後に記念撮影をして、無事にイベントは終了!

f:id:mugi1:20160211164455p:plain

第2回をやってみて

リモート開催でも意外となんとかなりました。不安いっぱいでしたが、致命的なトラブルはなかったように思います。

Toyama Free Wi-Fi が想像以上に安定していたのもあります。ありがとう富山県

ただ、やはりすべてがうまくいったわけではなく、改善すべき点もいくつか。

発表がしづらい

クイズ大会終了後は、再度Toyama.rb側はもくもくに戻り、最後には例のごとく成果発表会を行ったのですが、これがいまひとつだったかな〜というのが反省点です。

まず、発表者がappear.inに入っていただき、両会場でそれをスクリーンに映すような形をとったのですが、空気感がうまく共有できず、あまり質問もなく淡々と進む感じになってしまいました。

マイクをちゃんと用意できなかったのが根本原因なので、次回はなんとか改善したいな〜と思います。

ともあれ

全体で見ればうまくいったのではないかな?と思います。何事もやってみるもんですね!!

西脇.rb&神戸.rbのみなさん、勉強会に参加していただいたみなさん、本当にありがとうございました!

3月開催予定のもくもく会も同様に2拠点開催予定なので、興味のある方は気軽にご参加をどうぞ!


ちなみに....

今回のもくもく会で、私は react-rails を触っていました。
基本はこちらのQiita投稿を参考に写経。

仕事でRubyは使わないものの、react/redux/es6 あたりはガッツリ使うので、せっかくなのでそれ絡みで何かやってみよう!という感じ。

サーバサイドレンダリングの動きを確認できたようなできなかったような。。

react-railsに限った話ではないですが、Railsとエッジなフロントエンド技術を併せた場合の無難な着地点ってどこになるんでしょうね?次回はそのあたりをやってみようかな〜


懇親会のもつ鍋。うまかった。 f:id:mugi1:20160109180921j:plain

Toyama.rb もくもく会 1st を開催しました!

f:id:mugi1:20151205124515j:plain

2015/12/5 富山県民会館にて Toyama.rb もくもく会 1st を開催しました!

そもそもの成り立ち〜開催終了までのレポートです。

もくじ

  • Toyama.rb ができるまで
  • 事前準備
  • 当日の流れ
  • 主催してみて
  • 今後

Toyama.rbができるまで

よくよく考えると、私が10月に西脇.rb&神戸.rb主催のRubyプログラミングキャンプに参加してきたことが始まりなのかもしれません。

mugi1.hateblo.jp

人生初の勉強会でしたが、 そのまま勢いで金沢で行われているkanazawa.rbにも参加してみたりしました。

結果、「富山にもRubyコミュニティがあればいいのに・・」と思うように。

そんなことをFacebookなんかで呟いていると、

「それなら作っちゃえばいいじゃん!」

という意見もいただきました。

いっちょやってみるか!と思う気持ちはありましたが、主催するとなると、ただ勉強会に参加するのとはわけが違うよなぁ〜と思ってました。

何よりも、負荷もかなり違うという話を聞いたのもあり、自分だけではなくもう一人主催者が欲しかったです。

社内勉強会で「誰かやろうぜ」みたいなことを言ってもみましたが、予想通りというか誰も反応せず。結局動けずに悶々としておりました。



が、ある日このブログに1件コメントが。




f:id:mugi1:20151206225804p:plain

衝撃でした。 何よりも世の中の狭さに驚き。


まさか西脇.rb&神戸.rbの伊藤さん経由で富山のRubyistを紹介されるとは....


この機会を逃すわけにはいかん!

というわけで、ここからToyama.rbがスタートしました。

事前準備

内容は「もくもく会をしたい!」とスパッと決まりましたが、会場選びで悩む。何より、どこもかしこも富山の会場は値段が高め!

お、ここいいんじゃないのか?と思っても、

  • 富山駅から超遠い
  • ネットは別料金
  • 空調は別料金(死ねる)
  • とんでもなく早く閉館する

などなど。

10〜20人程度の参加を確定で見込めるなら良いのですが、ここは富山県。そもそも地元でRubyの仕事なんて聞いたことがないし、Rubyist存在するのか?

最悪2〜3人で開催っすね!みたいなことも話していたので、下手に大きい会場をとってしまって赤字になってしまっては私の個人的な財布が悲しいことになります。

いろいろ考慮した結果、最終的な会場は「富山県民会館」になりました。

f:id:mugi1:20151205120356j:plain

決め手は以下。

  • 財布に優しい
  • wifiが使える
  • 富山駅から近い(徒歩圏内)


さて、会場は決まりましたが、もう一つ決めなければいけないことが!



コミュニティ名はどうする!?

今でこそToyama.rbと書いていますが、最初は以下の候補がありました。

もう後半は正気とは思えないネーミングですが、富山県らしくていいんじゃないか!?と一瞬思ったので候補にあげてました。

結果、他の地域Rubyの名前を参考に素直にToyama.rbにしました。(理性が勝った。)


募集

募集はDoorkeeperで。初めて使ったのでドキドキしましたが、ここはスムーズでした。

あとは人が集まることを祈る・・

当日の流れ

13時開始だったのですが、「早く着かなきゃ!!」と思った私は、なぜか11時半には現地にいたことは大きな声では言えない。

早すぎたので近くの喫茶店でオムライス食べてました。


最終的に集まった人数ですが、なんと8人でした。
「最悪二人っすね」とか言っていたので、これはかなり驚き。


当日は以下のような流れで進めました。

  1. Toyama.rbについて簡単なお話 (by 私)
  2. 各自自己紹介 & やること発表
  3. もくもく
  4. 成果発表会


参加者は多種多様で

  • 独学でやってる。いつか会社で使いたい。普段はJava/javascript (私)
  • 普段からバリバリ使ってるぜ!
  • リモート勤務です!
  • 神奈川から来ました!

などなど。
そしてやるテーマも個性的!

募集時にはRubyで縛るかどうかも悩んだのですが、
交流自体も立派な目的だな〜と思ったので、
あくまでも主軸がRubyで、関係なくてもOK!ということにしました。


(もくもくの図) f:id:mugi1:20151205152509j:plain


slackの利用

西脇.rb & 神戸.rb や kanazawa.rb の内容をパク・・
参考にさせていただいている部分がとても多かったのですが、
この点だけはオリジナル要素なのかな?と思ってます。

以前参加させていただいたプログラミングキャンプ時の個人的な反省として、「もくもくに集中しすぎてコミュニケーションとるの忘れてた」というのがありました。

でもよーく考えると、

  • みんな集中してるのに喋るのはためらいがある?
  • えー、でも聞きたいことは聞きたいよ?

と、意外と難しい課題であることに気づく。


そこで、普段業務で利用しているslackを使ってみました。

slack.com

要はチャットなのですが、メンバー全員をslackのmeetup用チャンネルに招待し、そこで自由に独り言でもなんでも発言していいですよ!という扱いにしてみました。

そして意外とこれが(思いつきで導入したわりに) 好評でした。
目の前にいるのにチャットってどうなの!?という気持ちもわかりますが、もくもくに集中しだすとまったく見なかったりもするので、ちょうどいい具合で関わりを作ってくれたんじゃないかと思います。


ちなみに招待は⬇︎をherokuにデプロイして利用しました。

rauchg/slackin · GitHub


発表会

もくもく後は発表会を行いました。

f:id:mugi1:20151205163704j:plain

良い意味で予想外だったのですが、これが思いのほか盛り上がり、ちょっと時間が足りない状態になってしまいました。

懇親会会場の予約が17:30で、発表中に17:35になっていて一人こっそり焦っていたのですが、さすがに参加者にはバレているかもしれません。

次回以降は、もう少し余裕をもって発表会の時間の確保しよう。


...といった具合で、あとはお片づけをして懇親会に繰り出し、
良い具合に酔っ払ったところで解散となりました。

主催してみて

勉強会に初参加したときも同じ事を言ってますが、「意外となんとかなるもんだな!」というのが感想です。

参加者がみなさん良い人だったのも大きいです。

勢いで全部やってしまった

私自身が一度必要な準備作業をすべて体験してみたかったのもあるのですが、ついついほぼ全部一人でやってしまった感が・・

やること自体は私は何ら苦ではないというか、色々経験できてむしろ少し楽しいぐらいだったのですが、コミュニティ自体の継続開催を考えたときに、一人で全部やってしまっていると、私が参加できない場合に開催できなくなってしまうので、これは反省点だな・・と思いました。

というわけで、次回以降少しずつタスクを分けていければみんな安心ですね! (@zappar200 さんよろしくお願いします!)


今後

確定というわけではないですが、極力月1回程度のペースで継続開催を考えており、次回2016年1月にも #02 を開催する方向で現在進めております。


そして・・


次回は東京にリモート会場も設けて開催予定です。

今回の #01もくもく会 で関東在住の方が数名参加されていたのがきっかけです。

ちゃんと回線繋がるのか!?といった不安要素も多いですが、もくもく会中はslackがつながればいいんだからなんとかなるでしょう!といった、とりあえずやってみようぜ精神で開催します。

詳細はまたDoorkeeperで告知すると思いますので、興味のある方はぜひ一緒にもくもくしましょう!



最後に、参加していただいた皆様、
そしてきっかけを作っていただいた 西脇.rb 伊藤さん、
本当にありがとうございました!


以上、主催レポートでした。

おわり