Xcode で info.plist のプロパティを追加する

プロパティの追加方法がわかりづらかったからメモ。

f:id:komaji504:20160508033247p:plain

上記の手順をふむとプロパティが追加されるので、以下のようにプロパティ名や型を目的の値に変更して完了です。

f:id:komaji504:20160508040415p:plain

ちなみに、、、

③で一番下のプロパティと書きましたが、どのプロパティでも構いません。
当該プロパティの下の欄にプロパティが追加されます。

また、 プロパティ横の ▶︎ が ▼ の状態で + をクリックすると、 当該プロパティの子プロパティとして追加されます。

Rails の Time と DateTime

日時を扱うクラスには DateTime と Time の二つがあり、どちらを使えば良いのかを知ることもなく過ごしてきてしまっていたのですが、ざっくりと知ることができたのでメモ。

基本的には Time ( ActiveSupport::TimeWithZone ) を使う

Rails 環境においては、特に理由がないときは Time クラスを使うと良いそうです。
正確に言うと、ActiveSupport::TimeWithZone クラスです。

現在時刻を取得する場合で言うと、DateTime.now ではなく、 Time.now でもなく Time.current を用いるのが良いです。

Time.current を用いることで、Time クラスではなく ActiveSupport::TimeWithZone クラスの時刻を取得することができるからです。 (内部的には Time.zone.now が実行されています。)

なんで?

ActiveSupport::TimeWithZone クラスは application.rb のタイムゾーンを使い、また、DB のタイムスタンプは Time.current で更新されます。 そのため、設定したタイムゾーンが反映されていないぞ!ということがなくなり、DBとも統一されるので、安心感もあります。

これらのことから、 ActiveSupport::TimeWithZone クラスの時刻を取得することができる Time クラスを使うと良いとのことでした。

ローカル環境の Ruboty を slack で動かす

ローカル環境の Ruboty を slack で動かしてみたときのメモです。

Ruboty の使い方は、先日投稿したエントリにざっくり書いてあります。

komaji504.hateblo.jp

slack team を用意する

作っていない場合はこちらから。 Slack: Be less busy

slack 用アダプタのインストール

Gemfile に gem 'ruboty-slack_rtm' を追記して bundle install します。

bot アカウントの追加

Bots | Slack

こちらから、 Ruboty を動かしたい team に Bots をインストールします。

Username を聞かれるので、好きな名前を入力して Add bot integration をクリック。 これが bot アカウントの名前になります。後から変更することもできます。

クリックした後の画面で表示される Integration Settings の API Token をメモしておきます。

slack を確認すると bot アカウントが追加されていると思います。

環境変数の設定

ターミナルで環境変数 SLACK_TOKEN を設定します。 この値を先ほどメモした API Token にします。

export=<API Token>

以上で準備完了です。

slack で動かしてみる

bundle exec ruboty
 

で Ruboty を起動します。 アダプタが設定されているので、 シェル上では何も表示されません。

slack を確認すると、 先ほど追加した bot アカウントがオンラインになっています。 この状態で、 bot アカウントのいる CHANNEL でコマンドを入力すると正しく動作するはずです。

ruboty ping を入力してみると pong が返ってくると思います!

Ruboty を使ってみた

Ruboty 作者の r7kamura さんのエントリを読んで使ってみました。

r7kamura.hatenablog.com

動かしてみる

gem install ruboty
ruboty --generate
cd ruboty
bundle install

ここまでで Ruboty が動作する状態になります。

bundle exec ruboty を実行することで、シェル上で動作確認ができます。

bundle exec ruboty
Type `exit` or `quit` to end the session.
>

ruboty help を実行すると コマンド一覧が出てくるので、試しに ruboty ping を実行してみます。

> ruboty help
ruboty /help( me)?(?: (?<filter>.+))?\z/i - Show this help message
ruboty /ping\z/i - Return PONG to PING
ruboty /who am i\?/i - Answer who you are
> ruboty ping
pong
>

pong が返ってくることが確認できました。

拡張してみる

以下のように、ruboty hello を実行すると world!!! が返ってくるように拡張してみます。

Type `exit` or `quit` to end the session.
> ruboty hello
world!!!
>

クラスの追加

Ruboty::Handlers::Base を継承したクラスを作ることで拡張していくことができます。

# ruboty/test.rb

module Ruboty
  module Handlers
    class Test < Base
      on(
        /hello/, # トリガー
        name: 'say_world', # 実行するメソッド
        description: 'return "world" to "hello"' # ruboty help で表示される説明文
      )

      # world!!! を返すメソッド
      def say_world(message)
        message.reply('world!!!')
      end
    end
  end
end

動作確認

-l ファイル名 をつけることで指定したファイルを読み込ませることができます。 ruboty help を実行してみると、先ほどのコマンドが追加されていることが確認できます。

bundle exec ruboty -l test.rb
Type `exit` or `quit` to end the session.
> ruboty help
ruboty /hello/ - return "world" to "hello"
ruboty /help( me)?(?: (?<filter>.+))?\z/i - Show this help message
ruboty /ping\z/i - Return PONG to PING
ruboty /who am i\?/i - Answer who you are
>

ruboty hello を実行すると world!!! が返ってきます。

> ruboty hello
world!!!
>

RSpec の expect_any_instance_of でハマった

class Test
  def say_hoge
    hoge1 = Hoge.new
    hoge2 = Hoge.new
    hoge1.say
    hoge2.say
  end
end

class Hoge
  def say
    puts 'hoge'
  end
end

こんな感じのクラスがあったとして、 Test#say_hogeHoge インスタンスHoge#say を1回ずつ実行していることをテストしたいとなったときに、以下のようなテストを書きました。

describe 'Test' do
  describe '#say_hoge' do
    it 'Hoge インスタンス は Hoge#say を1回ずつ実行する' do
      expect_any_instance_of(Hoge).to receive(:say).once
      test = Test.new
      test.say_hoge
    end
  end
end

これを実行してみたところ、落ちてしまいました。


ああ、呼ばれている回数は全インスタンスの合計になるのか、なるほどね!とか思って、以下のように once を twice に変えてみました。

describe 'Test' do
  describe '#say_hoge' do
    it 'Hoge インスタンス は Hoge#say を1回ずつ実行する' do
      expect_any_instance_of(Hoge).to receive(:say).twice # 合計2回実行されるので twice に変えてみた
      test = Test.new
      test.say_hoge
    end
  end
end

これを実行してみたところ、またまた落ちてしまいました。


なぜだと思ってエラーを見てみると、「Hoge#say を hoge2 が実行したんだけど、 hoge1 でもう実行されてるよ」 的なことが書いてありました。

  1) Test #say_hoge Hoge instance call Hoge#say once
     Failure/Error: hoge2.say
       The message 'say' was received by #<Hoge:70248456891000 > but has already been received by #<Hoge:0x007fc7fca35518>

ためしに、以下のように hoge2.say を消して、 twice を once に戻してみました。

class Test
  def say_hoge
    hoge1 = Hoge.new
    hoge2 = Hoge.new
    hoge1.say
    # hoge2.say
  end
end
describe 'Test' do
  describe '#say_hoge' do
    it 'Hoge インスタンス は Hoge#say を1回ずつ実行する' do
      expect_any_instance_of(Hoge).to receive(:say).once
      test = Test.new
      test.say_hoge
    end
  end
end

これを実行すると、ちゃんと通りました。

わかったこと

おそらく、 expect_any_instance_of はどのインスタンスも対象にとるが、対象のインスタンスは1つに限るということなのだと思います。

どうするか

そのため、stub を使って Hoge.new でつくられるインスタンスを同じにして、そのインスタンスHoge#say が合計2回呼ばれるということをテストすることにしました。

class Test
  def say_hoge
    hoge1 = Hoge.new
    hoge2 = Hoge.new
    hoge1.say
    hoge2.say
  end
end
describe 'Test' do
  describe '#say_hoge' do
    it 'Hoge インスタンス は Hoge#say を1回ずつ実行する (合計2回) ' do
      hoge = Hoge.new
      allow(Hoge).to receive(:new).and_return(hoge)
      expect(hoge).to receive(:say).twice
      test = Test.new
      test.say_hoge
    end
  end
end

これを実行したところ無事通りました。

Finished in 0.01246 seconds (files took 0.42959 seconds to load)
1 example, 0 failures

入社してから早くも1年

先日は入社式があり、一緒に働く新しい仲間がたくさん増えました。

ということは、自分が入社してから早くも1年が経ったということです。
この1年は、とてもとてもあっという間でした。が、とても濃い1年でした。

ちょっと振り返る

自分が入社した時はどんな気持ちだったかなーと思い出してみると、やってやるぞ!!という気持ち半分、不安半分でした。

社会人としてやっていけるかなという、初めての環境に対する当然の不安もありましたが、そもそもエンジニアとしてやっていけるのかなという不安もありました。
自分は、技術的にとても未熟で未熟すぎて未熟で、自信がありませんでした。
どれくらい未熟だったかというと、社長に「技術的に不安だったよ〜」と直接言っていただけるくらいです。

いざ入社してみると、会社の先輩はもちろんなのですが、同期がとても優秀だったので焦りました。

エンジニア研修で一番最初に、すでに支給されていた PC の開発環境をいろいろ整えといてと言われたのですが、自分はどういったことをすれば良いのか全くわからない中、同期は空き時間に既に終わらせていたのは衝撃は忘れられません。
ちなみにこのときは、研修担当のエンジニアの方に自分だけみっちり教えていただきました。(同期が優秀な話をしようと思ったのに、自分がただただ未熟だったことしか伝わらないですね...)

その後、長い長い充実した研修を通して、技術的なこともたくさん学びましたし、エンジニアのチームでの働き方もたくさん学びました。
そのおかげで、当たり前なのですが、1年前に比べて見違える程になり、現在は先輩エンジニアの方にたくさん教えてもらいながらですが、日々楽しく開発を行えています。

自分で言うのもなんなのですが、めちゃくちゃ成長しました。
本当にこれだけは胸張って言えます。

2年目として

新しく入ったエンジニアの人たちは優秀なので、自分と同じような不安はあまりないとは思いますが、もしそういった不安を抱いているのであれば、

「大丈夫だよ、こんな自分でもちゃんとやっていけているんだから!(良い意味で)」

ということを伝えていけたらなあと思っています。

そんなことを伝えていきつつも、いるだけで成長のできる素晴らしい環境を存分に活かして、これからもどんどん成長していきたいです!

curl のオプション小まとめ

Web API の動作検証をするときに curl を使っているのですが、 そのときに使うオプションについて少しだけ書きます。
本当に少しだけです。

認証ユーザの指定

-u user_name:password

サーバの認証に使用するユーザ名とパスワードを指定できます。

デフォルトでは Basic 認証なのですが、--digest をつけることで Digest 認証にすることもできます。

リクエストメソッドの指定

-X method

リクエストメソッドを指定できます。

デフォルトは GET なので、 POSTDELETE 等を指定したい場合に使用できます。

リクエストパラメータの指定

-d data

リクエストパラメータを渡すことがきます。

このオプションを指定するとリクエストメソッドPOST として扱われるので、 それ以外を指定したい場合は -X で指定する必要があります。

data の指定方法

-d "name=don&age=20"

key=value のように指定します。 & で区切ることで複数のパラメータを渡すことができます。

-d "user[name]=don&user[age]=20"

のように指定することで、入れ子になったパラメータを渡すこともできます。