Open47

Tips Output vol.1

オクトオクト

each_with_object

https://docs.ruby-lang.org/ja/latest/method/Enumerable/i/each_with_object.html

最近知ったメソッド。
最初ややこしいし、なんのために使うか分からなかった。

ユースケースとしては、
validのものとinvalidのものを仕分けたいときに使えそう。

返り値は、オブジェクト

users = [{ name: 'Taro', age: 18 }, { name: 'jiro', age: 20 }, { name: 'Hanako', age: 24 }]

result = users.each_with_object(valid: [], invalid: []) do |user, result|
  if user[:age] > 20
    result[:valid] << user
  else
    result[:invalid] << user
  end
  result
end.compact

p result
#=> {:valid=>[{:name=>"Hanako", :age=>24}], :invalid=>[{:name=>"Taro", :age=>18}, {:name=>"jiro", :age=>20}]}
オクトオクト

Array#all?

https://docs.ruby-lang.org/ja/latest/method/Array/i/all=3f.html

配列の中身と引数やブロックの評価結果が真である場合にtrueを返し、偽である場合にfalseを返すメソッド。

例えば、

def calc(*numbers)
  numbers.map do |n|
    n * 2
  end
end

same_result = calc(2, 2, 2)
p same_result.all?(4)  #=> true

different_result = calc(2, 3, 4)
p different_result.all?(4)  #=> false

Hashでもいける。

person = { name: 'Sato' }
p person.all? { |_, val| val == 'Sato' }  #=> true
オクトオクト

is_a

https://docs.ruby-lang.org/ja/latest/method/Object/i/is_a=3f.html

レシーバが引数のクラス、もしくはそのクラスのサブクラスの場合にtrueを返す。
Module#includeObject#extendModule#prependによってサブクラスのインスタンスになる場合も評価される。

Sample code
class Sports
  def initialize(name)
    @name = name
  end
end

class Baseball < Sports
  def initialize(sum_teams)
    @sum_teams = sum_teams
  end
end

sports = Sports.new('baseball')
p sports.is_a?(Sports)  #=> true

baseball = Baseball.new(20)
p baseball.is_a?(Sports)  #=> true
オクトオクト

Hash#delete

https://docs.ruby-lang.org/ja/latest/method/Hash/i/delete.html

keyに対応する値を取り除く。
ブロックを渡すこともできて、このブロックはキーに対応する値がなかった場合に、評価される。
deleteメソッドが実行された後の、元のハッシュは取り除かれていない要素のみを持つ。

Sample code
user = { name: 'Taro', age: 20 }

p user.delete(:age)  #=> 20

p user.delete(:address)  #=> nil

p user.delete(:address) {|key| "#{key} is nothing."}  #=> "address is nothing."

p user  #=> {:name=>"Taro"}
オクトオクト

Rails.root.join

プロジェクトルートパスからパスを組み立てる。
Rails.root.join('hoge/fuga')とすることで、Rootディレクトリから簡潔にファイルパスを取得できる。

irb(main):003:0> Rails.root
=> #<Pathname:/app>
irb(main):004:0> Rails.root.join('hoge/fuga')
=> #<Pathname:/app/hoge/fuga>

おまけ

デフォルトのRails.envはdevelopment, test, productionの3つ。

興味深い記事
https://neko314.hatenablog.com/entry/2020/11/21/231326

参考

https://qiita.com/jnchito/items/418277508dce263cf4f0

オクトオクト

初めてこのコードに出会ったとき、戸惑った。
特にRubyでは#がコメントの扱いをすることがほとんどなので、余計に。

# -*- mode: ruby -*-
# vi: set ft=ruby :

この2つは、ファイルに対して特定の編集モードを選択するようエディタに伝えるためのコードみたいだ。
ハイライトやインデント幅が適用されるようだ。
ftfile typeの省略みたいだ。

https://superuser.com/questions/703803/bash-vi-mode-what-does-mode-ruby-vi-set-ft-ruby-mean

オクトオクト

Array#filter, Array#select

各要素に対して、ブロックの評価をした結果、trueになる要素のみを取り出して配列で返す。
trueになる要素がない場合は、空の配列を返す。

Sample code
empty_arry = []

result = empty_arry.filter do |i|
  i % 3 == 0
end

p result  #=> []
arry = [1, 2, 3, 5, 6, 9, 10]

result = arry.filter do |i|
  i % 3 == 0
end

p result  #=> [3, 6, 9]
オクトオクト

https://railsdoc.com/archive/6_0_2_1/page/find_each

find_eachは分割してレコードを1件ずつ取ってきて、それに対して処理を行うメソッド。
デフォルトでは1000件ずつ処理を行う。

Sample Code
[1] pry(main)> User.find_each do |user|
[1] pry(main)*   p user.id
[1] pry(main)* end  
  TRANSACTION (0.4ms)  BEGIN
  User Load (9.7ms)  SELECT `users`.* FROM `users` WHERE `users`.`deleted_at` IS NULL ORDER BY `users`.`id` ASC LIMIT 1000
2
3
5
6
7
8
10
11
12
13
14
15
16
17
18
19
オクトオクト

serializable_hash

https://railsdoc.com/page/serializable_hash

これは、あるオブジェクトをシリアル化されたハッシュに変換するメソッド。

Sample Code
> user
#=> #<User id: 1, email: "test_user@example.com", created_at: "2022-07-30 13:03:02.019168000 +0900", updated_at: "2022-07-30 13:06:11.849681000 +0900">

> user.serializable_hash
#=> {"id"=>1, "email"=>"test_user@example.com", "created_at"=>Sat, 30 Jul 2022 13:03:02.019168000 JST +09:00, "updated_at"=>Sat, 30 Jul 2022 13:06:11.849681000 JST +09:00>}