[name=makicamel]
- Redis 入門 を読んでいる
redis-objects
を使う
# config/initializers/redis.rb
require 'connection_pool'
Redis::Objects.redis = ConnectionPool.new(size: 5, timeout: 5) { Redis.new(host: '127.0.0.1', port: 6379) }
class User < ApplicationRecord
include Redis::Objects
list :items
end
user = User.last
user.items.get
# => []
user.items << 'りんご'
user.items << 'ばなな'
user.items << 'マンゴー'
user.items.get
# => ["りんご", "ばなな", "マンゴー"]
def update_token
now = Time.zone.now.to_f
redis = Redis.current
redis.hset('login:', current_user.token, current_user.id)
redis.zadd('recent:', now, current_user.token)
redis.zadd('viewed:' + current_user.token, now, @item.id)
redis.zremrangebyrank('viewed:' + current_user.token, 0, -6)
end
alias 新メソッド名 旧メソッド名
- クラス/メソッドの定義
以前は元のメソッドに何か付け加えたい時に以下のように利用してメソッドの書き換えを行っていたが、今は Module#prepend
と super の組み合わせで実現することが多い。
元のメソッドを退避し別名で呼びたい場合は現在でも有効。
module Logging
def log(message)
puts message
end
def log_with_timestamp(message)
log_without_timestamp("[#{Time.now}]#{message}")
end
# log を log_without_timestamp というメソッド名で呼べるように退避する
alias log_without_timestamp log
# log というメソッド名で log_with_timestamp を呼ぶようにする
alias log log_with_timestamp
end
class AwesomeLogger
include Logging
end
logger = AwesomeLogger.new
logger.log 'hoi'
# => [2021-12-24 05:02:06 +0900]hoi
logger.log_without_timestamp 'hoi'
# => hoi
以前は Rails に alias_method_chain
が存在したが 5 系で deprecated になり今は削除された。
上述の通り Ruby2.0 で Module#prepend
が実装されたため。
Method
Object#method
によりオブジェクト化されたメソッドオブジェクトのクラスunbind
でUnboundMethod
オブジェクトにできる
method = '1 2'.method(:split)
# => #<Method: String#split(*)>
method.call
# => ["1", "2"]
method.unbind
# => #<UnboundMethod: String#split(*)>
# Method#source_location が present な場合、その値が表示される
hoi = Struct.new('Hoi') { def hoihoi; p 'hoi!'; end }.new
method = hoi.method(:hoihoi)
# => #<Method: Struct::Hoi#hoihoi() (irb):1>
method.call
# => "hoi!"
UnboundMethod
レシーバを持たないメソッドを表すクラス 呼び出すためにはレシーバにバインドする必要があり、bind
で Method オブジェクトにできる
unbound_method = String.instance_method(:split)
# => #<UnboundMethod: String#split(*)>
unbound_method.call
# NoMethodError: undefined method `call' for #<UnboundMethod: String#split(*)>
# from (pry):1:in `__pry__'
method = unbound_method.bind('1 2')
# => #<Method: String#split(*)>
method.call
# => ["1", "2"]
Adapterパターンは,求めているものと,提供されているものの違いを吸収して,求めているものに適合させるものである. (中略) 実現する方法には2種類ある.クラスの関係を用いて「継承」を使ったものと,インスタンスを用いた「委譲」を使ったものがある.
form objectを使ってみよう - メドピア開発者ブログ であげられているフォームオブジェクトを例として考えてみる。
class Signup
include ActiveModel::Model
attr_accessor :email, :password, :password_confirmation
validates :email, presence: true, format: { with: /\A.+@.+\z/ }
validates :password, presence: true, length: { minimum: 6 }, confirmation: { allow_blank: true }
def save
return false if invalid?
user = User.new(email: email, password: password, password_confirmation: password_confirmation)
user.save!
UserMailer.welcome(user).deliver_later
true
end
end
この例では User 自身のバリデーションを実施するのは user.save!
になるため Signup#valid?
と Signup#save
の結果が異なり得る。
User
クラスの性質を持った SignupUser
クラスを作成し処理を実行する。
- class Signup
- include ActiveModel::Model
+ class SignupUser < User
User
クラスのインスタンスを介して処理を実行する。
Signup
が save
メソッドを必要とせず valid?
のみを必要としている場合、 ActiveRecord の性質を持つ User
を継承するのは好ましくない。
class Signup
include ActiveModel::Model
# Signup#email, Signup#password にアクセスしたい場合は delegate する
delegate :email, :password, to: :@user
attr_accessor :invitation_code
validates :invitation_code, presence: true, format: { with: /\A[\w\d]{6}\z/ }
validate :user_validate
def initialize(invitation_code:, attribute)
@invitation_code = invitation_code
@user = User.new(attribute)
end
# def valid?(*args)
# super & @user.valid?(*args)
# end
def error_messages
# Signup#errors と User#errors をそれぞれ保持したい
errors.full_messages + @user.errors.full_messages
end
private
def user_validate
@user.valid?
end
end
Ruby で並列処理を実現するには以下の方法がある
- プロセス メモリを独立して持つためスレッドに比較し独立性が高くコストも高い 特にプロセスの fork 時にメモリをまるごとコピーする場合メモリを逼迫する。コピーオンライト(利用時にコピーする)方式を採用する場合緩和される
- スレッド メモリを共有するためプロセスに比較し独立性が低くコストも低い
- Fiber ノンプリエンプティブ( CPU の管理を OS が行わず、各アプリケーションが自ら切換えする方式)な軽量スレッド
- Ractor アクターモデル風の並行・並列制御機構であり、スレッド安全に関する懸念なく、Ruby で並列処理を行うための機能
Ruby ではグリーンスレッド(OS ではなく VM でスケジューリングするスレッド)を採用している。これは Matz が定めた方針 ref) It isn't Easy to Remove the GIL - Matzにっき(2007-09-13)
- unicorn
マルチプロセス
スロークライアントに弱い、 Nginx 側でリバースプロキシを立てることを前提としている 最近の Rack サーバ事情について - おもしろwebサービス開発日記
- puma
マルチプロセス + マルチスレッド
スレッドアンセーフなアプリケーションで使えない
以前は Rails がマルチスレッドを考慮した作りになっていなかったが、Rails, puma 両者の対応が進み、結実したのが Rails5 railsアプリケーションにおいて、なぜNginx+unicornの組み合わせが多いのでしょうか?Nginx+pumaと比較して何が違うのでしょうか? - Quora
- falcon マルチプロセス + マルチファイバー
[name=ken3ypa]
- Cmd + i で自分のアイコン出す、ぐらいしか使ったことなかったけど、J, K が便利
キーボードショートカット | 効果 | 使える場所 |
---|---|---|
文字を選択 + P |
選択部分がセットされた状態で、新しい投稿ページが開く | 記事ページ |
⌘ + K |
リンク記法を挿入 | 記事 or コメントの編集中 |
J , K |
前のリビジョン/次のリビジョン | リビジョン詳細ページ |
J , K |
(同じカテゴリ内の)前の記事/次の記事 | 記事詳細ページ |
[ , ] |
(チーム内の)前の記事/次の記事 | 記事詳細ページ |
? | ショートカットのヘルプを表示 | どこでも |
/ | 検索formにfocus | どこでも |
- Create Link
- Markdown形式でコピーが出来て便利
- GitHubに外部ページのURL貼るときなど便利
Copy Title and Url as Markdown Style - Chrome ウェブストア
- 2人で1ヶ月ぐらいのタスク
- 先に一人が入っていて、あとで自分が入った
- はじめて一緒にお仕事した人でもスムーズに進めることが出来た
- お見合い状態から早めに抜けて、相談しやすい環境を作れた
- キックオフ
- 自分はどういう人間か・どう仕事を進めるか
- 「ふつう」の認識合わせ
- パフォーマンス出る時間・出にくい時間
- PR を出していくサイクル
- その分野の経験
- タスクの不安な点の共有
- 「ドメイン知識は任せろ、Ruby の書き方には不安がある」
- 「Ruby の書き方は任せろ、ドメイン知識は不安がある」
- MTGの頻度決め
- 週次 MTG
- タスクの窓口を決める
- 自分はどういう人間か・どう仕事を進めるか
- 定例MTG
- 予実管理
- 不安な点の共有
- スポット
- ペアプロの実施
- 最後
- KPTの実施