u16suzuの blog

日々学んだことのメモブログです。

2016/08/03の日記

このブログ記事に書いてあるスクリプトを読んで、わからないところを調べた。

83億レコードを移行し、日々2,500万レコードのアクセスログをBigQueryに記録している話(インフラ編) | Money Forward Engineers' Blog

set -o pipefail

bashset -o pipefail と書くと、エラーが発生した場合にそれ以降の処理をしないで止まってくれるようになる。

#!/bin/bash -e

set -o pipefail

export LC_ALL=C

ロケール環境変数を指定している。

sortの時に早くなるらしい。

mailコマンドでメールを送る

上のブログの記事とは関係ないけど、mailコマンドに関しても調べた。

mailコマンドを使うと、メールを送ることができる。

本文は以下のように echo文で指定しなければならない。

echo "本文" | mail -s "タイトル"  sample@example.com

2016/8/2(tue)の日記

shell起動時に自動的に指定のディレクトリに移動するようにした。

毎朝仕事を開始する時に、いつも仕事用のディレクトリにcdで移動するのが大変なので書いた。

以下のように .open_directoryディレクトリを指定すると、shell 起動時に移動してくれる。

$ cat ~/.open_directory
/Users/u16suzu/workGithub/rails_project
### 起動時に .open_directory ファイルで指定された directory に自動で移動する
function auto_move(){
  cd "`cat ~/.open_directory`"
}
auto_move

2016/8/1(mon)の日記

プロジェクトで使っている bundler で入れたgemの調査をするためのコマンドをbashで書いた。

Ruby 書くときは atom がメインエディタになりつつある。

RubyMineは重いので、コードリーディングの時だけ使っている。

### bundler でインストールした gem を編集したり、元に戻したりするコマンド
# gem の内部動作を調査する際に使う
# どちらのコマンドも操作対象のgemを引数で指定する必要がある
function gem_edit(){
  atom `bundle show $1`
}
alias gem_edit="gem_edit"
alias gem_restore="bundle exec gem pristine"

ただ、一つだけ問題があって、gemを書き換えた後に rails consoleを再起動しないと読み込んでくれない。

pry

binding.pry を書くと、gemのコードの中で処理を止めてpryで変数の中身を見たりできる。

Arelの定義位置を調べたい時、pryコンソールで show-source Arel とすると、arel のコードがどこで定義されているのかを調査することもできる。

2016/7/31(Sun)の日記

今日はマクドRuby script 用のDSLを書いて遊んだ。

仕事でよく使うテスト用のスクリプトなんだけど、実行するタスクを引数で指定できるようになっている。

それをDSLで指定できるようにした。

@argv = [ {env: "pro"}, 'login', 'start' ]
@env = "dev"

p ARGV

def debug(a)
  puts "---\n#{a}\n---"
end

def before_all(&block)
  @before_all = block
end

def after_all(&block)
  @after_all = block
end

def env(name, &block)
  @env = @argv.select{ |o| o.is_a?(Hash) }.first[:env]
  yield(block) if @env == name
end

before_all do
  debug 'before_all'
end

after_all do
  debug 'after_all'
end

def task(name, &block)
  @before_all.call if @before_all != nil && @argv.include?("all")
  yield block if block_given? && (@argv.include?( name ) || @argv.include?('all') )
  @after_all.call if @after_all != nil && @argv.include?("all")
end

env 'test' do
  debug 'test'
end

env 'stg' do
  debug 'stg'
end

env 'pro' do
  debug 'pro'
end

task 'login' do
  debug 'login'
end

task 'start' do
  debug 'start'
end

task 'finish' do
  debug 'finish'
end

2016/7/28(木)の日記

jbuilderについて

extract! # activerecord objectのアトリビュートを指定して書き出し
ignore_nil! # このメソッドを書いた後は, nil のkey-valueをjsonに書き出さない. ignore_nil! false でオフにできる.

Splat演算子

a, b = *[1,2] # => a = 1, b = 2
*c = 1,2,3 # => c = [1,2,3]

Rubyで、配列を展開するときに使う *array みたいな演算子 * を Splat演算子と呼ぶ.

上の動作は知っていたけど、下の動作は気づいていなかった.

展開後の値を代入で指定しているわけですね.

メソッドの引数にハッシュを指定するときのつまづきポイント

[42] pry(main)> fuga a: 123
=> {:a=>123}
[43] pry(main)> fuga {a: 123}
SyntaxError: unexpected ':', expecting '}'
fuga {a: 123}
[43] pry(main)> fuga( {a: 123})
=> {:a=>123}

メソッドの引数にハッシュを指定したいときに, fuga {a: 123} と書くとエラーになる。

これは、Rubyが引数の { をブロック引数の { として解釈してしまうため発生する。

fuga({a: 123})()明示的に引数指定をすればエラーにならない

はじめ、Splat演算子と関係あるのかなと思ったけど、関係なかった。

今回、仕事で久しぶりに遭遇して、同僚のA氏に昔教えていただいたことを思い出した。

テスト周りで久しぶりにハマった

BaseController の rescue_from で例外の出力処理を書いていなかったため

テストは落ちるけど、スタックトレースが出力されず、原因の特定に困った。

いわゆる例外の握りつぶしに意図せずになってしまっていた。

これから rescue_fromStandardError を補足する場合は注意したい。

2016/7/27の日記

Rubyのメソッドに関する雑多なメモ

<< # 右ビットシフト `*2` と同じ意味
>> # 左ビットシフト `/2` と同じ意味
| # 論理和演算子. 0011|0101 => 0111
8.to_s(2) #=> "1000" : 2進数表現の文字列を取得
"0x4d2".hex #=> 1234 : 16進数を10進数に変換. 0xはなくてもあっても良い.

super

Rubyのsuperはオーバーライドしているメソッドを呼び出す. 注意点として、引数を省略してsuperとコールすると、全ての引数を受け渡してコールしてしまう. super() と明示的に()をつけてコールすると、引数を渡さない. このことは Effective Ruby でも書かれていた.

Effective Ruby

Effective Ruby

クラスマクロを自分で定義してみる.

クラスマクロを使うことで、 attr_accessor みたいなメソッドを定義できる. 完全にクラスメソッドだけど、こういう attr_accessorっぽい宣言的な構文で記述が出来る奴をクラスマクロと言うらしい. Railshas_many, belongs_to もクラスマクロだ.

class User
  attr_accessor :name

  def self.attr_special_accessor( *key )
    p key
  end

  def self.before_hoge_hoge(key)
    p key
  end

  def self.after_hoge_hoge(k)
    p k
  end
end

class Boy < User
  attr_special_accessor :name, :age
  before_hoge_hoge :foo
  after_hoge_hoge :bar
end

このQiitaの記事がとても参考になった.