PerlerのRuby日記

Rubyとか

Rails のキャッシュストアとセッションストアに Redis を使う

Ruby 2.7.1 + Rails v6.0.3.2 + Redis


Gemfile

...
gem 'redis'
gem 'hiredis'
...


開発環境用の設定

config/environments/development.rb

  # Enable/disable caching. By default caching is disabled.
  # Run rails dev:cache to toggle caching.
  if Rails.root.join('tmp', 'caching-dev.txt').exist?
    config.action_controller.perform_caching = true
    config.action_controller.enable_fragment_cache_logging = true

    #--------------------------------------------------------------------
    # config.cache_store = :memory_store
    config.cache_store = :redis_cache_store, {
      url: 'redis://localhost:6379',
      expires_in: 30.minutes,
      namespace: 'foo_cache',
    }
    config.session_store :cache_store, key: "foo_session",
                                       expire_after: 1.day.to_i
    #--------------------------------------------------------------------

    config.public_file_server.headers = {
      'Cache-Control' => "public, max-age=#{2.days.to_i}"
    }
  else
    config.action_controller.perform_caching = false

    config.cache_store = :null_store
  end

キャッシュを有効にする。

$ ./bin/rails dev:cache
Development mode is now being cached.

参考:
railsguides.jp
railsguides.jp

AWS Lambda Ruby 2.7 の puts の返却値は nil ではなく文字数

メモ。

AWS Lambda でランタイムに Ruby 2.7 を選択する。そのとき puts を使うと返却値は nil ではなくて、出力した文字数が返る。

AWS Lambda

# lambda_handler.rb
require 'json'

def lambda_handler(event:, context:)
  ret_puts = puts "foo!!!!!"
  puts "ret_puts: #{ret_puts.inspect}" #=> 8 ("foo!!!!!".length)

  { statusCode: 200, body: JSON.generate('Hello from Lambda!') }
end

ローカルで irb したとき

2.7.1 :001 > ret_puts = puts "foo!!!!!"
foo!!!!!
2.7.1 :002 > puts "ret_puts: #{ret_puts.inspect}"
ret_puts: nil
 => nil


ちなみに、ランタイムに Ruby 2.5 を選択すると、puts は nil が返る。

参考:
docs.ruby-lang.org

配列の要素が、1ずつ増加しているかどうかをチェックする

配列内の要素が1ずつ増えているかどうかをチェックしたかったメモ。

[1, 2, 3, 4] #=> OK
[1, 2, 4]    #=> NG
[4, 5]       #=> OK
[6]          #=> OK
[7, 8, 0]    #=> NG

今回自分が出くわした場面では、要素内の値が0〜9ということが確定していたので、こんな解決方法を思いついた。

ary = [1, 2, 3, 4]

ok_str = (0..9).to_a.join #=> "0123456789"
if ok_str.index(ary.join)
  puts "OK!"
else
  puts "NG."
end

あらかじめ0から9までの数字を連結させた文字列を用意して、String#indexでひっかけるやり方である。

まあでもかなり特殊な条件だし、ぱっと見て何をしているか親切ではないので、何かないですかね〜とチームメイトに相談したら、Array#each_consというのを教えてもらった。

ary = [1, 2, 3, 4]

ary.each_cons(2) do |v1, v2|
  puts "v1: #{v1}, v2: #{v2}"
end

#=> v1: 1, v2: 2
#=> v1: 2, v2: 3
#=> v1: 3, v2: 4

https://ruby-doc.org/core-2.5.0/Enumerable.html#method-i-each_cons

順繰りにまとめたものをループしてくれる。すばらしい。

なので、0〜9とかに限らず、ちゃんと1ずつ増加しているかどうかを確認するやり方をeach_consを使ってみると、

ary = [1, 2, 3, 4]

result = ary.each_cons(2) do |v1, v2|
  if (v1 + 1) != v2
    break false
  end
end

if result.nil?
  puts "OK!"
elsif result == false
  puts "NG."
end

こんな感じかな。each_consは正常に回りきったらnilを返してくれるので、途中でだめだったときにそれ以外の値でbreakして切り分けるのがちょっとかっこ悪いけど、これなら0〜100とか300〜89654とか、桁数に限らずチェックはできそう。