Hyurakuのエンジニア日誌

SE出身Webエンジニアのブログ

リモートのマスターに合わせたくなったときに使うコマンドの解説 #21

先日、ローカルブランチでのconflict多すぎてリモートに合わせるのが難しいのでローカルブランチを強制的にリモートのに合わせたい。と思ったときに見付けたコマンドを紹介する。

以下コマンド記載。

git fetch origin
git reset --hard origin/master

それぞれのコマンドが実行していることを解説する。

  • git fetch origin
    リモートにある同ブランチの情報を取得している。

  • git reset --hard origin/master

    • git reset --hard 指定のHEADの位置までファイルやコミットの状態が戻る。

    • origin/master リモートにあるmasterブランチと結び付いているブランチ。

Rubyのdropメソッドとtakeメソッド #20

今日はRubyの配列に関するメソッドdrop,takeについて紹介する。

1. drop

リファレンスより参照。

# Array.drop(捨てる要素数)

a = [1, 2, 3, 4, 5, 0]
a.drop(3)
> [4, 5, 0]

2. take

リファレンスより参照。

# Array.take(要素数)

a = [1, 2, 3, 4, 5, 0]
a.take(3)
> [1, 2, 3]

今日はこれまで。

テーブルを呼び出す、または結合するRailsのメソッド #19

テーブルを呼び出す、または結合するメソッドがいくつかあるので、
今回はドキュメントに記載されている例を元に振り返る。

1. includes

関連しているテーブルを呼び出す。

Page.includes(:category)
# SELECT "pages".* FROM "pages"
# SELECT "categories".* FROM "categories" WHERE "categories"."id" IN (1)

関連しているテーブルの数だけ呼び出す。
テーブル結合はしていない。

2. joins

複数のテーブルを結合して検索している。

Category.joins(:posts)
# SELECT categories.* FROM categories INNER JOIN posts ON posts.category_id = categories.id

実際には内部結合している。

3. eager_load

指定したテーブルのすべてのデータを取得する。

User.eager_load(:posts)
=> SELECT "users"."id" AS t0_r0, "users"."name" AS t0_r1, ...
FROM "users" LEFT OUTER JOIN "posts" ON "posts"."user_id" =
"users"."id"

実際には外部結合している。

なお、外部結合と内部結合の違いは次のとおり。 - 内部結合 一致するもののみ抽出対象

  • 外部結合 一致するものがないレコードも抽出対象

4. preload

APIdockには次のように書かれていた。

# includesと同じ方法で、指定したテーブルを呼び出す。

User.preload(:posts)
=> SELECT "posts".* FROM "posts" WHERE "posts"."user_id" IN (1, 2, 3)

Rubyのメソッドblock_given?の紹介 #18

先日コードを読んでいたときに気になっていたメソッドblock_givin?について紹介したい。

1. block_given

公式サイトより参照。

メソッドにブロックが与えられていれば真を返します。

ブロックとは{}に囲まれた引数や処理のことである。

2. 実際に書いてみた

次のようなファイル(index.rb)を書いてみた。

def check
  if block_given?
    puts "Block is given."
  else
    puts "Block isn't given."
  end
end

p check{}
p check

実行結果は次のとおり。

ruby index.rb
> Block is given.
> Block isn't given.

ブロックの有無のチェックをメソッド内に定義する、
という使い方がよいと考える。

ジュニアエンジニアに伝えたい15のアドバイス #17

今日はIf I knew then what I know nowという記事に書かれていた15のアドバイスを備忘録としてまとめた。

  1. コードレビューのときは頭を下げなさい。謙虚でありなさい。
    あなた自身ではなくコード自体のレビューですから。

  2. コードを掘り下げる前には読書が必要です。
    トラブルが起きたときだけマニュアルを読まないように。

  3. デザインパターンはいいものです。しかしすべてのパターンを使う必要はありません。
    必要な時に必要なコードを書きましょう。

  4. Pythonは早めに学びましょう。Python REPLにアクセスし、import thisと入力しましょう。

  5. コーヒーやピザ、ポテトチップスはとてもよいものですが、20年後は控えたほうがよいでしょう。

  6. 今から2,3年後ソーシャルメディアは大きくなるでしょう。控えたほうがよい。

  7. 嫌いな数学の単元こそより生活を豊かにする。

  8. いつになったらジュニアから卒業できるのかと悩むのはやめなさい。
    どんな技術を選んでどんなものができるのかを認識していれば、もうジュニアではない。

  9. 質問もするときは丁寧に。
    マニュアルを読めよ、なんて返されたくなかっらEric Raymondさんのhow to ask smart questionsを読みましょう。

  10. 会議のときは、紙とペンをもってメモを取ろう。

  11. 何か見つけ出すために3時間以上かかったら人に聞こう。
    相手にはどんなことで時間を喰っているのかを伝えよう。
    (ただし質問するときは9. に記載したことを読もう)

  12. 金曜日にできますよ、と約束するなら早めにいいましょう。金曜日にいうものではない。

  13. 体を鍛えろ。あなたの脳は(そしてあなたの血圧も)あなたの運動を望んでいる。

  14. 達人プログラマー―システム開発の職人から名匠への道の話がでたら、読みましょう。

  15. LOLCODEを書いてみよう、ユーモアを失わないでしょう。

N+1問題解消のヒントを教えてくれるbulletの紹介 #16

N+1問題を解決するためにいつもbulletを使っているので、 使い方を忘れぬようメモをする。

1. bullet

N+1問題が発生している箇所を検出、指摘するgem。

2. 使い方

  • まずはbulletをインストールする。
gem install bullet

またはgemfileに書き込んだ後でbundle installを使用。

gem 'bullet'
  • 次にbulletの設定をする。
    config/environments/development.rbに次のコードを書き込む。
Rails.application.configure do
  --< omit >--

  config.after_initialize do
    Bullet.enable  = true   # bullet を有効にする。

    Bullet.alert   = true   
    Bullet.bullet_logger = true
    Bullet.rails_logger = true
    Bullet.add_footer   = true
  end
end
  • もしもrailsのアプリケーションを動かしていたなら再起動する。

  • 起動後、アプリケーション画面を確認する。

実際に出たアラートの一部を貼る。 f:id:hyuraku:20181018223806p:plain

知っておきたいRubyのarrayメソッド6つ #15

Rubyでarrayを扱うときに、Six Ruby array methods you need to know という記事を読んだ。紹介されたメソッドの中にはあまり使っていないのがあったので、 備忘録がてらまとめてみた。

1. Map/Each

mapとeach、やっていることは同じだが次の違いがある。 - map: 新たにオブジェクトを生成している。 - each: 既存のオブジェクトを参照している。

array = [1, 2, 3]
effects = array.each{|x| # create record from x }
> [1,2,3]
added = array.map{ |x| x + 2 }
> [3,4,5]

array.object_id
> 70287991433000
effects.object_id
> 70287991433000
added.object_id
> 70287996325680

2. Select

このメソッドは条件に当てはまる要素を抽出するメソッドである。

array = [1, 2, 3]
array.select{ |x| x%2==0 }
> [2]

次のようにMapと組み合わせ使うこともできる。

Level = ['Easy','Middle','Hard']
Test_list = [{
  subject: 'language',
  level: 'Middle'
  }, {
  subject: 'Math',
  level: 'Very Hard'
  }, {
  subject: 'Science',
  level: 'Easy'
  }]

Test_list.select{ |test| Level.include?(test[:level])}.map{ |test| test[:subject]}
> ["language", "Science"]

3. Reject

selectとは逆の作用をするメソッド。

Test_list.reject{ |test| Level.include?(test[:level])}.map{ |test| test[:subject]}
> ["Math"]

4. Reduce

arrayの各要素に同じ処理を行うメソッド。 また引数を指定して処理を行うことができる。

array = [1, 2, 3, 4]
array.reduce{|sum, x| sum + x}
# 1 + 2 + 3 + 4
> 10
array.reduce(20) {|num, n| num - n }
> 10

5. Join

配列の各要素を連結した文字列を返すメソッド。

Test_list.map{ |test| test[:subject]}.join(',')
> "language,Math,Science"

ちなみに元記事では紹介されたすべてのメソッドを使用したコードが書かれている。 実際に動かしてみるのもよいでしょう。

days = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
days.map{|day| day.odd? ? 
   {task: 'dishes', minutes: Random.rand(20)} : 
   {task: 'sweep', minutes: Random.rand(20)}}
   .select{|task| task[:minutes] < 15}
   .reject{|task| task[:minutes] < 5}
   .reduce(0){|sum, task| sum + task[:minutes]}