読者です 読者をやめる 読者になる 読者になる

u16suzuの blog

u16suzu のブログです。

ActiveSupportの Array のメソッドを一通り眺めてみる

rails

ActiveSupport の Array の拡張メソッドを一通り眺めてみた

  • extract_options!

引数のオプション部分だけをかえしてくれる. メソッドを定義するときに便利

def options(*args)
  args.extract_options!
end

options(1, 2)        # => {}
options(1, 2, a: :b) # => {:a=>:b}
  • to_param

配列からurlを生成できる。join( '/' ) と同じ。

This is used by url_for in Action Pack. Action Packの url_for で使われている。

[36] pry(main)> [1,2,3,4,5].to_param
=> "1/2/3/4/5"
# File activesupport/lib/active_support/core_ext/object/to_query.rb, line 40
def to_param
  collect { |e| e.to_param }.join '/'
end

再起的にto_paramが呼ばれるようになっている。 nil#to_paramは active_supportの Nil classに定義されていた

irb(main):022:0* [[1,2,3],1,2,3].to_param
=> "1/2/3/1/2/3"
  • to_query
[21] pry(main)> [1,2,3].to_query( :hoge )
=> "hoge%5B%5D=1&hoge%5B%5D=2&hoge%5B%5D=3"
[22] pry(main)> URI.unescape( _ )
=> "hoge[]=1&hoge[]=2&hoge[]=3"
  • code
# File activesupport/lib/active_support/core_ext/object/to_query.rb, line 48
def to_query(key)
  prefix = "#{key}[]"

  if empty?
    nil.to_query(prefix)
  else
    collect { |value| value.to_query(prefix) }.join '&'
  end
end

nil#to_paramはわかったけど、 nil#to_query がどこで定義されているのかわからない。

  • to_sentence

こんなメソッドあるんだ...

[29] pry(main)> %i( dog cat rat ).to_sentence
=> "dog, cat, and rat"
  • split

指定した index でarrayを分割する. 指定されたindexは含まれない.

p [1,2,3].split(1) # =>[[], [2, 3]]
p [1,2,3].split(2) # =>[[1], [3]]
p [1,2,3].split(3) # =>[[1, 2], []]
p [1,2,3].split(4) # =>[[1, 2, 3]]
  • in_groups

指定した数のグループ数に分ける。rubyのeach_sliceとは異なる。

  • in_groups_of

指定した数の要素を含むグループに分ける。rubyのeach_sliceとほぼほぼ同じ

よくわからなかったメソッドたち

  • to_default_s
  • to_formatted_s, to_s

学習のためRailsのコードリーディングをした時のmemo

railsrspec

  • scopeのマージは、以下のようにかくと、paramsの条件分岐が綺麗に書ける.
scope = User.where( id: user.id )
scope = scope.where( 'created_at >= ?', params[:date_from].to_date ) if params[:date_from].present?
scope = scope.where( 'created_at < ?', params[:date_to].to_date + 1.day ) if params[:date_to].present?
scope = scope.order( 'id DESC' )
  • created_at に index を貼っても良い. 日付scopeで絞る時はindexを日付に貼るべき.
  • RSpecの let{} に 前処理の do_request を書いちゃうの良い. let{:do_request}{ get /hoge, params } みたいな感じ

DBの分割方法2種類

  • 水平分割 : レコード単位で分割する. 横に切るイメージ. パーティションで代替可能で、できればパーティションを使うべき.
  • 垂直分割 : カラム単位で分割する. 縦に切るイメージ. 集約で代替可能. 集約と垂直分割の違いは、マートは元のテーブルを残すが、垂直分割は残さないこと.
    • 集約 : サマリーとマートの2種類. マートは元テーブルを残して、特定のカラムだけからなる別テーブルを作るもの。当然同期が必要.

参考サイト

opensslコマンドについて調べた

RSA秘密鍵を生成

  • pemという拡張子にしているが、これはテキストエンコーディングで保存しているということのみを表し、暗号方式とは関係ない
  • openssl ではデフォルトでpem形式で保存される
$ openssl genrsa 1024 > private.pem
Generating RSA private key, 1024 bit long modulus
...++++++
...++++++
e is 65537 (0x10001)
$ cat private.pem
-----BEGIN RSA PRIVATE KEY-----
MIICWwIBAAKBgQC6IP/uleEN/ylwgWA5ImazybAuLToALL2iuZD3sooQEu9vDR6J
GD8Hcf/F7edjWkhjtzV5FIouDUnPMcue3fPkGan6HNG/lYf+HUi82ojHTswWTcbJ
Oluy/d5IJ5SO1jbBLdhFGUaOrvnysBZXWjw5D4jtT51Rn7lY1VAN0D2H+wIDAQAB
AoGAeUJWelEatcuua6Vd0tsenbKgHPVJ/CMpyIGseDLQz3gGlQqvAhHRvj/+qiw7
uvZugsgxBhjjjO0LUPjX90ASS0QEsvMwPLFhHr7bvmImEZrqslKAI4YbrLidVqNT
+DGDsSnoZmSWHVqSGbkzcDlLRM3RJHyf0e7Mp0bXALZzI4ECQQDgb+MLT2DZRYNQ
nh2y94t0xuynjgCAY2LySLP7jww7RmFyqZ19ACjZ11V840v81D2yh1HcEUlryW+a
PjHYdD/TAkEA1E30Y4/NMZmikHP0sUECq0ZFP0UTU1+RlyfuQAIVWffjgs/GLvql
bsbgGB1zYIDK0G1gFOHai+rKRWSa5FYmOQJAKddyIpen3JnDA3KW4tiXnSvAzvQA
T+83cSfwtgNTKnHSlQfeHoG7G/GzNFdDwVzoK7Jipn5qi7fAIKdbr5jslQJANfWu
RNPa0l17HP3r1lVwqTmOBhu3Yrxqk6GZg3lEFf7UO341n+EixPoVIOvzVDbH1ZvH
DOeulVtSl7qPR7PBuQJALAsrQOiy0Y6nu/4lc8hmYc1LijVeYNUaFO/C2pzFyozL
PHQ6Obf9ciXrsgyT/nkWpbdz9IMackXIQe6i5x9u4g==
-----END RSA PRIVATE KEY-----

秘密鍵の中身を見てみる

  • prime1, prime2 という部分が暗号に使われている素数
  • RSAは巨大な素数の約数導出の困難性を利用した暗号化方式
$ openssl rsa -in private.pem -text -noout
Private-Key: (1024 bit)
modulus:
    00:ba:20:ff:ee:95:e1:0d:ff:29:70:81:60:39:22:
    66:b3:c9:b0:2e:2d:3a:00:2c:bd:a2:b9:90:f7:b2:
    8a:10:12:ef:6f:0d:1e:89:18:3f:07:71:ff:c5:ed:
    e7:63:5a:48:63:b7:35:79:14:8a:2e:0d:49:cf:31:
    cb:9e:dd:f3:e4:19:a9:fa:1c:d1:bf:95:87:fe:1d:
    48:bc:da:88:c7:4e:cc:16:4d:c6:c9:3a:5b:b2:fd:
    de:48:27:94:8e:d6:36:c1:2d:d8:45:19:46:8e:ae:
    f9:f2:b0:16:57:5a:3c:39:0f:88:ed:4f:9d:51:9f:
    b9:58:d5:50:0d:d0:3d:87:fb
publicExponent: 65537 (0x10001)
privateExponent:
    79:42:56:7a:51:1a:b5:cb:ae:6b:a5:5d:d2:db:1e:
    9d:b2:a0:1c:f5:49:fc:23:29:c8:81:ac:78:32:d0:
    cf:78:06:95:0a:af:02:11:d1:be:3f:fe:aa:2c:3b:
    ba:f6:6e:82:c8:31:06:18:e3:8c:ed:0b:50:f8:d7:
    f7:40:12:4b:44:04:b2:f3:30:3c:b1:61:1e:be:db:
    be:62:26:11:9a:ea:b2:52:80:23:86:1b:ac:b8:9d:
    56:a3:53:f8:31:83:b1:29:e8:66:64:96:1d:5a:92:
    19:b9:33:70:39:4b:44:cd:d1:24:7c:9f:d1:ee:cc:
    a7:46:d7:00:b6:73:23:81
prime1:
    00:e0:6f:e3:0b:4f:60:d9:45:83:50:9e:1d:b2:f7:
    8b:74:c6:ec:a7:8e:00:80:63:62:f2:48:b3:fb:8f:
    0c:3b:46:61:72:a9:9d:7d:00:28:d9:d7:55:7c:e3:
    4b:fc:d4:3d:b2:87:51:dc:11:49:6b:c9:6f:9a:3e:
    31:d8:74:3f:d3
prime2:
    00:d4:4d:f4:63:8f:cd:31:99:a2:90:73:f4:b1:41:
    02:ab:46:45:3f:45:13:53:5f:91:97:27:ee:40:02:
    15:59:f7:e3:82:cf:c6:2e:fa:a5:6e:c6:e0:18:1d:
    73:60:80:ca:d0:6d:60:14:e1:da:8b:ea:ca:45:64:
    9a:e4:56:26:39
exponent1:
    29:d7:72:22:97:a7:dc:99:c3:03:72:96:e2:d8:97:
    9d:2b:c0:ce:f4:00:4f:ef:37:71:27:f0:b6:03:53:
    2a:71:d2:95:07:de:1e:81:bb:1b:f1:b3:34:57:43:
    c1:5c:e8:2b:b2:62:a6:7e:6a:8b:b7:c0:20:a7:5b:
    af:98:ec:95
exponent2:
    35:f5:ae:44:d3:da:d2:5d:7b:1c:fd:eb:d6:55:70:
    a9:39:8e:06:1b:b7:62:bc:6a:93:a1:99:83:79:44:
    15:fe:d4:3b:7e:35:9f:e1:22:c4:fa:15:20:eb:f3:
    54:36:c7:d5:9b:c7:0c:e7:ae:95:5b:52:97:ba:8f:
    47:b3:c1:b9
coefficient:
    2c:0b:2b:40:e8:b2:d1:8e:a7:bb:fe:25:73:c8:66:
    61:cd:4b:8a:35:5e:60:d5:1a:14:ef:c2:da:9c:c5:
    ca:8c:cb:3c:74:3a:39:b7:fd:72:25:eb:b2:0c:93:
    fe:79:16:a5:b7:73:f4:83:1a:72:45:c8:41:ee:a2:
    e7:1f:6e:e2

RSAの公開鍵を生成

$ openssl rsa -in private.pem -pubout -out public.pem
  • こちらも同様にpem形式で保存される
  • pemだとファイルの行頭が -----BEGIN で始まっている
$ cat public.pem
-----BEGIN PUBLIC KEY-----
MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC6IP/uleEN/ylwgWA5ImazybAu
LToALL2iuZD3sooQEu9vDR6JGD8Hcf/F7edjWkhjtzV5FIouDUnPMcue3fPkGan6
HNG/lYf+HUi82ojHTswWTcbJOluy/d5IJ5SO1jbBLdhFGUaOrvnysBZXWjw5D4jt
T51Rn7lY1VAN0D2H+wIDAQAB
-----END PUBLIC KEY-----
  • 続いて、公開鍵の中身を表示してみる
  • -pubin-inの順番は間違えると怒られる. opensslは引数の指定が複雑だ。
$ openssl rsa -pubin -in public.pem -text -noout
Modulus (1024 bit):
    00:ba:20:ff:ee:95:e1:0d:ff:29:70:81:60:39:22:
    66:b3:c9:b0:2e:2d:3a:00:2c:bd:a2:b9:90:f7:b2:
    8a:10:12:ef:6f:0d:1e:89:18:3f:07:71:ff:c5:ed:
    e7:63:5a:48:63:b7:35:79:14:8a:2e:0d:49:cf:31:
    cb:9e:dd:f3:e4:19:a9:fa:1c:d1:bf:95:87:fe:1d:
    48:bc:da:88:c7:4e:cc:16:4d:c6:c9:3a:5b:b2:fd:
    de:48:27:94:8e:d6:36:c1:2d:d8:45:19:46:8e:ae:
    f9:f2:b0:16:57:5a:3c:39:0f:88:ed:4f:9d:51:9f:
    b9:58:d5:50:0d:d0:3d:87:fb
Exponent: 65537 (0x10001)

ディレクトリの作成と移動を同時に行うコマンド

zsh
function mkcd {
  mkdir $1 && cd $_
}

参考:

blog.tstylestudio.com

全くzshに関係ないけど、fish便利だから、そろそろ仕事でも使いたい。pecoとの連携ができてなかったので、そこが設定できたら使えそう。

DBやKVSの楽観ロックと悲観ロックについて調べた

楽観ロック

  • 参照時にロックをしない
  • 仕組み : バージョンを保持しておき、バージョンが更新されていたら、その後の変更は破棄される
  • 同じリソースへの更新が、頻繁に発生しないことを想定したロック
  • 変更が破棄されるためリトライを考慮した設計にしなければならない
  • 主にアプリケーションレベルでかけることが多い
  • Redisではこちらの機能が使える

悲観ロック

  • 参照時にロックをする
  • 仕組み : 参照時にロックをかけ、他のプロセスはそのロックが解放されるまで待ちが発生する
  • 同じリソースへの更新が、頻繁に発生することを想定したロック
  • 主にDBレベルでかけることが多い

参考にしたページ

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